RefundRelayerForMessagesFromParachain improvements (#1895)

* RefundRelayerForMessagesFromParachain changes

- some renamings and cosmetics
- removing the GI generic param since we can get it from the parachains
  config
- merging (Parachains Instance, Parachain Id) and (Messages Instance,
  Messages lane Id) generic params
- removing unnecessay derives
- renaming for the `TransactionFeeCalculation` and defining
  `ActualFeeRefund` concrete implementation
- adding support for multiple RefundRelayerForMessagesFromParachain
  (by adding a `StaticStrProvider` generic param)

* Revert to using RuntimeDebug
This commit is contained in:
Serban Iorga
2023-02-20 16:36:13 +02:00
committed by Bastian Köcher
parent 1d6e8a9a26
commit 623bd85a5e
6 changed files with 247 additions and 169 deletions
+16 -12
View File
@@ -80,7 +80,13 @@ pub use pallet_sudo::Call as SudoCall;
pub use pallet_timestamp::Call as TimestampCall; pub use pallet_timestamp::Call as TimestampCall;
pub use pallet_xcm::Call as XcmCall; pub use pallet_xcm::Call as XcmCall;
use bridge_runtime_common::generate_bridge_reject_obsolete_headers_and_messages; use bridge_runtime_common::{
generate_bridge_reject_obsolete_headers_and_messages,
refund_relayer_extension::{
ActualFeeRefund, RefundBridgedParachainMessages, RefundableMessagesLane,
RefundableParachain,
},
};
#[cfg(any(feature = "std", test))] #[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage; pub use sp_runtime::BuildStorage;
pub use sp_runtime::{Perbill, Permill}; pub use sp_runtime::{Perbill, Permill};
@@ -582,17 +588,15 @@ generate_bridge_reject_obsolete_headers_and_messages! {
BridgeRialtoMessages, BridgeRialtoParachainMessages BridgeRialtoMessages, BridgeRialtoParachainMessages
} }
bp_runtime::generate_static_str_provider!(BridgeRefundRialtoPara2000Lane0Msgs);
/// Signed extension that refunds relayers that are delivering messages from the Rialto parachain. /// Signed extension that refunds relayers that are delivering messages from the Rialto parachain.
pub type BridgeRefundRialtoParachainRelayers = pub type BridgeRefundRialtoParachainMessages = RefundBridgedParachainMessages<
bridge_runtime_common::refund_relayer_extension::RefundRelayerForMessagesFromParachain< Runtime,
Runtime, RefundableParachain<WithRialtoParachainsInstance, RialtoParachainId>,
RialtoGrandpaInstance, RefundableMessagesLane<WithRialtoParachainMessagesInstance, RialtoParachainMessagesLane>,
WithRialtoParachainsInstance, ActualFeeRefund<Runtime>,
WithRialtoParachainMessagesInstance, StrBridgeRefundRialtoPara2000Lane0Msgs,
RialtoParachainId, >;
RialtoParachainMessagesLane,
Runtime,
>;
/// The address format for describing accounts. /// The address format for describing accounts.
pub type Address = AccountId; pub type Address = AccountId;
@@ -615,7 +619,7 @@ pub type SignedExtra = (
frame_system::CheckWeight<Runtime>, frame_system::CheckWeight<Runtime>,
pallet_transaction_payment::ChargeTransactionPayment<Runtime>, pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
BridgeRejectObsoleteHeadersAndMessages, BridgeRejectObsoleteHeadersAndMessages,
BridgeRefundRialtoParachainRelayers, BridgeRefundRialtoParachainMessages,
); );
/// The payload being signed in transactions. /// The payload being signed in transactions.
pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>; pub type SignedPayload = generic::SignedPayload<RuntimeCall, SignedExtra>;
@@ -18,12 +18,12 @@ use crate::messages::{
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
}; };
use bp_messages::{LaneId, MessageNonce}; use bp_messages::{LaneId, MessageNonce};
use frame_support::{dispatch::CallableCallFor, traits::IsSubType}; use frame_support::{dispatch::CallableCallFor, traits::IsSubType, RuntimeDebug};
use pallet_bridge_messages::{Config, Pallet}; use pallet_bridge_messages::{Config, Pallet};
use sp_runtime::{transaction_validity::TransactionValidity, RuntimeDebug}; use sp_runtime::transaction_validity::TransactionValidity;
/// Info about a `ReceiveMessagesProof` call which tries to update a single lane. /// Info about a `ReceiveMessagesProof` call which tries to update a single lane.
#[derive(Copy, Clone, PartialEq, RuntimeDebug)] #[derive(PartialEq, RuntimeDebug)]
pub struct ReceiveMessagesProofInfo { pub struct ReceiveMessagesProofInfo {
pub lane_id: LaneId, pub lane_id: LaneId,
pub best_proof_nonce: MessageNonce, pub best_proof_nonce: MessageNonce,
@@ -23,6 +23,7 @@ use crate::messages_call_ext::{
MessagesCallSubType, ReceiveMessagesProofHelper, ReceiveMessagesProofInfo, MessagesCallSubType, ReceiveMessagesProofHelper, ReceiveMessagesProofInfo,
}; };
use bp_messages::LaneId; use bp_messages::LaneId;
use bp_runtime::StaticStrProvider;
use codec::{Decode, Encode}; use codec::{Decode, Encode};
use frame_support::{ use frame_support::{
dispatch::{CallableCallFor, DispatchInfo, Dispatchable, PostDispatchInfo}, dispatch::{CallableCallFor, DispatchInfo, Dispatchable, PostDispatchInfo},
@@ -46,28 +47,77 @@ use sp_runtime::{
}; };
use sp_std::{marker::PhantomData, vec, vec::Vec}; use sp_std::{marker::PhantomData, vec, vec::Vec};
// TODO (https://github.com/paritytech/parity-bridges-common/issues/1667): // without this typedef rustfmt fails with internal err
// support multiple bridges in this extension type BalanceOf<R> =
<<R as TransactionPaymentConfig>::OnChargeTransaction as OnChargeTransaction<R>>::Balance;
type CallOf<R> = <R as frame_system::Config>::RuntimeCall;
/// Transaction fee calculation. /// Trait identifying a bridged parachain. A relayer might be refunded for delivering messages
pub trait TransactionFeeCalculation<Balance> { /// coming from this parachain.
/// Compute fee that is paid for given transaction. The fee is later refunded to relayer. trait RefundableParachainId {
fn compute_fee( /// The instance of the bridge parachains pallet.
type Instance;
/// The parachain Id.
type Id: Get<u32>;
}
/// Default implementation of `RefundableParachainId`.
pub struct RefundableParachain<Instance, Id>(PhantomData<(Instance, Id)>);
impl<Instance, Id> RefundableParachainId for RefundableParachain<Instance, Id>
where
Id: Get<u32>,
{
type Instance = Instance;
type Id = Id;
}
/// Trait identifying a bridged messages lane. A relayer might be refunded for delivering messages
/// coming from this lane.
trait RefundableMessagesLaneId {
/// The instance of the bridge messages pallet.
type Instance;
/// The messages lane id.
type Id: Get<LaneId>;
}
/// Default implementation of `RefundableMessagesLaneId`.
pub struct RefundableMessagesLane<Instance, Id>(PhantomData<(Instance, Id)>);
impl<Instance, Id> RefundableMessagesLaneId for RefundableMessagesLane<Instance, Id>
where
Id: Get<LaneId>,
{
type Instance = Instance;
type Id = Id;
}
/// Refund calculator.
pub trait RefundCalculator {
// The underlying integer type in which the refund is calculated.
type Balance;
/// Compute refund for given transaction.
fn compute_refund(
info: &DispatchInfo, info: &DispatchInfo,
post_info: &PostDispatchInfo, post_info: &PostDispatchInfo,
len: usize, len: usize,
tip: Balance, tip: Self::Balance,
) -> Balance; ) -> Self::Balance;
} }
impl<R> TransactionFeeCalculation<BalanceOf<R>> for R /// `RefundCalculator` implementation which refunds the actual transaction fee.
pub struct ActualFeeRefund<R>(PhantomData<R>);
impl<R> RefundCalculator for ActualFeeRefund<R>
where where
R: TransactionPaymentConfig, R: TransactionPaymentConfig,
<R as frame_system::Config>::RuntimeCall: CallOf<R>: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
BalanceOf<R>: FixedPointOperand, BalanceOf<R>: FixedPointOperand,
{ {
fn compute_fee( type Balance = BalanceOf<R>;
fn compute_refund(
info: &DispatchInfo, info: &DispatchInfo,
post_info: &PostDispatchInfo, post_info: &PostDispatchInfo,
len: usize, len: usize,
@@ -77,7 +127,55 @@ where
} }
} }
/// Signed extension that refunds relayer for new messages coming from the parachain. /// Data that is crafted in `pre_dispatch` method and used at `post_dispatch`.
#[cfg_attr(test, derive(Debug, PartialEq))]
pub struct PreDispatchData<AccountId> {
/// Transaction submitter (relayer) account.
relayer: AccountId,
/// Type of the call.
call_info: CallInfo,
}
/// Type of the call that the extension recognizes.
#[derive(RuntimeDebugNoBound, PartialEq)]
pub enum CallInfo {
/// Relay chain finality + parachain finality + message delivery calls.
AllFinalityAndDelivery(RelayBlockNumber, SubmitParachainHeadsInfo, ReceiveMessagesProofInfo),
/// Parachain finality + message delivery calls.
ParachainFinalityAndDelivery(SubmitParachainHeadsInfo, ReceiveMessagesProofInfo),
/// Standalone message delivery call.
Delivery(ReceiveMessagesProofInfo),
}
impl CallInfo {
/// Returns the pre-dispatch `finality_target` sent to the `SubmitFinalityProof` call.
fn submit_finality_proof_info(&self) -> Option<RelayBlockNumber> {
match *self {
Self::AllFinalityAndDelivery(info, _, _) => Some(info),
_ => None,
}
}
/// Returns the pre-dispatch `SubmitParachainHeadsInfo`.
fn submit_parachain_heads_info(&self) -> Option<&SubmitParachainHeadsInfo> {
match self {
Self::AllFinalityAndDelivery(_, info, _) => Some(info),
Self::ParachainFinalityAndDelivery(info, _) => Some(info),
_ => None,
}
}
/// Returns the pre-dispatch `ReceiveMessagesProofInfo`.
fn receive_messages_proof_info(&self) -> &ReceiveMessagesProofInfo {
match self {
Self::AllFinalityAndDelivery(_, _, info) => info,
Self::ParachainFinalityAndDelivery(_, info) => info,
Self::Delivery(info) => info,
}
}
}
/// Signed extension that refunds a relayer for new messages coming from a parachain.
/// ///
/// Also refunds relayer for successful finality delivery if it comes in batch (`utility.batchAll`) /// Also refunds relayer for successful finality delivery if it comes in batch (`utility.batchAll`)
/// with message delivery transaction. Batch may deliver either both relay chain header and /// with message delivery transaction. Batch may deliver either both relay chain header and
@@ -86,29 +184,29 @@ where
/// ///
/// Extension does not refund transaction tip due to security reasons. /// Extension does not refund transaction tip due to security reasons.
#[derive( #[derive(
DefaultNoBound,
CloneNoBound, CloneNoBound,
Decode, Decode,
DefaultNoBound,
Encode, Encode,
EqNoBound, EqNoBound,
PartialEqNoBound, PartialEqNoBound,
RuntimeDebugNoBound, RuntimeDebugNoBound,
TypeInfo, TypeInfo,
)] )]
#[scale_info(skip_type_params(RT, GI, PI, MI, PID, LID, FEE))] #[scale_info(skip_type_params(Runtime, Para, Msgs, Refund, Id))]
pub struct RefundRelayerForMessagesFromParachain<RT, GI, PI, MI, PID, LID, FEE>( pub struct RefundBridgedParachainMessages<Runtime, Para, Msgs, Refund, Id>(
PhantomData<(RT, GI, PI, MI, PID, LID, FEE)>, PhantomData<(Runtime, Para, Msgs, Refund, Id)>,
); );
impl<R, GI, PI, MI, PID, LID, FEE> impl<Runtime, Para, Msgs, Refund, Id>
RefundRelayerForMessagesFromParachain<R, GI, PI, MI, PID, LID, FEE> RefundBridgedParachainMessages<Runtime, Para, Msgs, Refund, Id>
where where
R: UtilityConfig<RuntimeCall = CallOf<R>>, Runtime: UtilityConfig<RuntimeCall = CallOf<Runtime>>,
CallOf<R>: IsSubType<CallableCallFor<UtilityPallet<R>, R>>, CallOf<Runtime>: IsSubType<CallableCallFor<UtilityPallet<Runtime>, Runtime>>,
{ {
fn expand_call<'a>(&self, call: &'a CallOf<R>) -> Option<Vec<&'a CallOf<R>>> { fn expand_call<'a>(&self, call: &'a CallOf<Runtime>) -> Option<Vec<&'a CallOf<Runtime>>> {
let calls = match call.is_sub_type() { let calls = match call.is_sub_type() {
Some(UtilityCall::<R>::batch_all { ref calls }) => { Some(UtilityCall::<Runtime>::batch_all { ref calls }) => {
if calls.len() > 3 { if calls.len() > 3 {
return None return None
} }
@@ -123,71 +221,30 @@ where
} }
} }
/// Data that is crafted in `pre_dispatch` method and used at `post_dispatch`. impl<Runtime, Para, Msgs, Refund, Id> SignedExtension
#[derive(PartialEq)] for RefundBridgedParachainMessages<Runtime, Para, Msgs, Refund, Id>
#[cfg_attr(test, derive(Debug))]
pub struct PreDispatchData<AccountId> {
/// Transaction submitter (relayer) account.
relayer: AccountId,
/// Type of the call.
pub call_type: CallType,
}
/// Type of the call that the extension recognizes.
#[derive(Clone, Copy, PartialEq, RuntimeDebugNoBound)]
pub enum CallType {
/// Relay chain finality + parachain finality + message delivery calls.
AllFinalityAndDelivery(RelayBlockNumber, SubmitParachainHeadsInfo, ReceiveMessagesProofInfo),
/// Parachain finality + message delivery calls.
ParachainFinalityAndDelivery(SubmitParachainHeadsInfo, ReceiveMessagesProofInfo),
/// Standalone message delivery call.
Delivery(ReceiveMessagesProofInfo),
}
impl CallType {
/// Returns the pre-dispatch messages pallet state.
fn receive_messages_proof_info(&self) -> ReceiveMessagesProofInfo {
match *self {
Self::AllFinalityAndDelivery(_, _, info) => info,
Self::ParachainFinalityAndDelivery(_, info) => info,
Self::Delivery(info) => info,
}
}
}
// without this typedef rustfmt fails with internal err
type BalanceOf<R> =
<<R as TransactionPaymentConfig>::OnChargeTransaction as OnChargeTransaction<R>>::Balance;
type CallOf<R> = <R as frame_system::Config>::RuntimeCall;
impl<R, GI, PI, MI, PID, LID, FEE> SignedExtension
for RefundRelayerForMessagesFromParachain<R, GI, PI, MI, PID, LID, FEE>
where where
R: 'static Self: 'static + Send + Sync,
+ Send Runtime: UtilityConfig<RuntimeCall = CallOf<Runtime>>
+ Sync + BoundedBridgeGrandpaConfig<Runtime::BridgesGrandpaPalletInstance>
+ UtilityConfig<RuntimeCall = CallOf<R>> + ParachainsConfig<Para::Instance>
+ BoundedBridgeGrandpaConfig<GI> + MessagesConfig<Msgs::Instance>
+ ParachainsConfig<PI, BridgesGrandpaPalletInstance = GI>
+ MessagesConfig<MI>
+ RelayersConfig, + RelayersConfig,
GI: 'static + Send + Sync, Para: RefundableParachainId,
PI: 'static + Send + Sync, Msgs: RefundableMessagesLaneId,
MI: 'static + Send + Sync, Refund: RefundCalculator<Balance = Runtime::Reward>,
PID: 'static + Send + Sync + Get<u32>, Id: StaticStrProvider,
LID: 'static + Send + Sync + Get<LaneId>, CallOf<Runtime>: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>
FEE: 'static + Send + Sync + TransactionFeeCalculation<<R as RelayersConfig>::Reward>, + IsSubType<CallableCallFor<UtilityPallet<Runtime>, Runtime>>
CallOf<R>: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo> + GrandpaCallSubType<Runtime, Runtime::BridgesGrandpaPalletInstance>
+ IsSubType<CallableCallFor<UtilityPallet<R>, R>> + ParachainsCallSubType<Runtime, Para::Instance>
+ GrandpaCallSubType<R, GI> + MessagesCallSubType<Runtime, Msgs::Instance>,
+ ParachainsCallSubType<R, PI>
+ MessagesCallSubType<R, MI>,
{ {
const IDENTIFIER: &'static str = "RefundRelayerForMessagesFromParachain"; const IDENTIFIER: &'static str = Id::STR;
type AccountId = R::AccountId; type AccountId = Runtime::AccountId;
type Call = CallOf<R>; type Call = CallOf<Runtime>;
type AdditionalSigned = (); type AdditionalSigned = ();
type Pre = Option<PreDispatchData<R::AccountId>>; type Pre = Option<PreDispatchData<Runtime::AccountId>>;
fn additional_signed(&self) -> Result<(), TransactionValidityError> { fn additional_signed(&self) -> Result<(), TransactionValidityError> {
Ok(()) Ok(())
@@ -200,15 +257,12 @@ where
_info: &DispatchInfoOf<Self::Call>, _info: &DispatchInfoOf<Self::Call>,
_len: usize, _len: usize,
) -> TransactionValidity { ) -> TransactionValidity {
let calls = match self.expand_call(call) { if let Some(calls) = self.expand_call(call) {
Some(calls) => calls, for nested_call in calls {
None => return Ok(ValidTransaction::default()), nested_call.check_obsolete_submit_finality_proof()?;
}; nested_call.check_obsolete_submit_parachain_heads()?;
nested_call.check_obsolete_receive_messages_proof()?;
for call in calls { }
call.check_obsolete_submit_finality_proof()?;
call.check_obsolete_submit_parachain_heads()?;
call.check_obsolete_receive_messages_proof()?;
} }
Ok(ValidTransaction::default()) Ok(ValidTransaction::default())
@@ -225,35 +279,35 @@ where
self.validate(who, call, info, len).map(drop)?; self.validate(who, call, info, len).map(drop)?;
// Try to check if the tx matches one of types we support. // Try to check if the tx matches one of types we support.
let parse_call_type = || { let parse_call = || {
let mut calls = self.expand_call(call)?.into_iter(); let mut calls = self.expand_call(call)?.into_iter();
match calls.len() { match calls.len() {
3 => Some(CallType::AllFinalityAndDelivery( 3 => Some(CallInfo::AllFinalityAndDelivery(
calls.next()?.submit_finality_proof_info()?, calls.next()?.submit_finality_proof_info()?,
calls.next()?.submit_parachain_heads_info_for(PID::get())?, calls.next()?.submit_parachain_heads_info_for(Para::Id::get())?,
calls.next()?.receive_messages_proof_info_for(LID::get())?, calls.next()?.receive_messages_proof_info_for(Msgs::Id::get())?,
)), )),
2 => Some(CallType::ParachainFinalityAndDelivery( 2 => Some(CallInfo::ParachainFinalityAndDelivery(
calls.next()?.submit_parachain_heads_info_for(PID::get())?, calls.next()?.submit_parachain_heads_info_for(Para::Id::get())?,
calls.next()?.receive_messages_proof_info_for(LID::get())?, calls.next()?.receive_messages_proof_info_for(Msgs::Id::get())?,
)), )),
1 => Some(CallType::Delivery( 1 => Some(CallInfo::Delivery(
calls.next()?.receive_messages_proof_info_for(LID::get())?, calls.next()?.receive_messages_proof_info_for(Msgs::Id::get())?,
)), )),
_ => None, _ => None,
} }
}; };
Ok(parse_call_type().map(|call_type| { Ok(parse_call().map(|call_info| {
log::trace!( log::trace!(
target: "runtime::bridge", target: "runtime::bridge",
"RefundRelayerForMessagesFromParachain from parachain {} via {:?} \ "{} from parachain {} via {:?} parsed bridge transaction in pre-dispatch: {:?}",
parsed bridge transaction in pre-dispatch: {:?}", Self::IDENTIFIER,
PID::get(), Para::Id::get(),
LID::get(), Msgs::Id::get(),
call_type, call_info,
); );
PreDispatchData { relayer: who.clone(), call_type } PreDispatchData { relayer: who.clone(), call_info }
})) }))
} }
@@ -270,14 +324,14 @@ where
} }
// We don't refund anything for transactions that we don't support. // We don't refund anything for transactions that we don't support.
let (relayer, call_type) = match pre { let (relayer, call_info) = match pre {
Some(Some(pre)) => (pre.relayer, pre.call_type), Some(Some(pre)) => (pre.relayer, pre.call_info),
_ => return Ok(()), _ => return Ok(()),
}; };
// check if relay chain state has been updated // check if relay chain state has been updated
if let CallType::AllFinalityAndDelivery(relay_block_number, _, _) = call_type { if let Some(relay_block_number) = call_info.submit_finality_proof_info() {
if !SubmitFinalityProofHelper::<R, GI>::was_successful(relay_block_number) { if !SubmitFinalityProofHelper::<Runtime, Runtime::BridgesGrandpaPalletInstance>::was_successful(relay_block_number) {
// we only refund relayer if all calls have updated chain state // we only refund relayer if all calls have updated chain state
return Ok(()) return Ok(())
} }
@@ -291,44 +345,44 @@ where
} }
// check if parachain state has been updated // check if parachain state has been updated
match call_type { if let Some(para_proof_info) = call_info.submit_parachain_heads_info() {
CallType::AllFinalityAndDelivery(_, parachain_heads_info, _) | if !SubmitParachainHeadsHelper::<Runtime, Para::Instance>::was_successful(
CallType::ParachainFinalityAndDelivery(parachain_heads_info, _) => { para_proof_info,
if !SubmitParachainHeadsHelper::<R, PI>::was_successful(&parachain_heads_info) { ) {
// we only refund relayer if all calls have updated chain state // we only refund relayer if all calls have updated chain state
return Ok(()) return Ok(())
} }
},
_ => (),
} }
// Check if the `ReceiveMessagesProof` call delivered at least some of the messages that // Check if the `ReceiveMessagesProof` call delivered at least some of the messages that
// it contained. If this happens, we consider the transaction "helpful" and refund it. // it contained. If this happens, we consider the transaction "helpful" and refund it.
let messages_proof_info = call_type.receive_messages_proof_info(); let msgs_proof_info = call_info.receive_messages_proof_info();
if !ReceiveMessagesProofHelper::<R, MI>::was_partially_successful(&messages_proof_info) { if !ReceiveMessagesProofHelper::<Runtime, Msgs::Instance>::was_partially_successful(
msgs_proof_info,
) {
return Ok(()) return Ok(())
} }
// regarding the tip - refund that happens here (at this side of the bridge) isn't the whole // regarding the tip - refund that happens here (at this side of the bridge) isn't the whole
// relayer compensation. He'll receive some amount at the other side of the bridge. It shall // relayer compensation. He'll receive some amount at the other side of the bridge. It shall
// (in theory) cover the tip here. Otherwise, if we'll be compensating tip here, some // (in theory) cover the tip there. Otherwise, if we'll be compensating tip here, some
// malicious relayer may use huge tips, effectively depleting account that pay rewards. The // malicious relayer may use huge tips, effectively depleting account that pay rewards. The
// cost of this attack is nothing. Hence we use zero as tip here. // cost of this attack is nothing. Hence we use zero as tip here.
let tip = Zero::zero(); let tip = Zero::zero();
// compute the relayer reward // compute the relayer refund
let reward = FEE::compute_fee(info, post_info, len, tip); let refund = Refund::compute_refund(info, post_info, len, tip);
// finally - register refund in relayers pallet
// finally - register reward in relayers pallet RelayersPallet::<Runtime>::register_relayer_reward(Msgs::Id::get(), &relayer, refund);
RelayersPallet::<R>::register_relayer_reward(LID::get(), &relayer, reward);
log::trace!( log::trace!(
target: "runtime::bridge", target: "runtime::bridge",
"RefundRelayerForMessagesFromParachain from parachain {} via {:?} has registered {:?} reward: {:?}", "{} from parachain {} via {:?} has registered reward: {:?} for {:?}",
PID::get(), Self::IDENTIFIER,
LID::get(), Para::Id::get(),
Msgs::Id::get(),
refund,
relayer, relayer,
reward,
); );
Ok(()) Ok(())
@@ -353,18 +407,17 @@ mod tests {
}; };
parameter_types! { parameter_types! {
pub TestParachain: u32 = 1000; TestParachain: u32 = 1000;
pub TestLaneId: LaneId = TEST_LANE_ID; pub TestLaneId: LaneId = TEST_LANE_ID;
} }
type TestExtension = RefundRelayerForMessagesFromParachain< bp_runtime::generate_static_str_provider!(TestExtension);
TestRuntime, type TestExtension = RefundBridgedParachainMessages<
(),
(),
(),
TestParachain,
TestLaneId,
TestRuntime, TestRuntime,
RefundableParachain<(), TestParachain>,
RefundableMessagesLane<(), TestLaneId>,
ActualFeeRefund<TestRuntime>,
StrTestExtension,
>; >;
fn relayer_account_at_this_chain() -> ThisChainAccountId { fn relayer_account_at_this_chain() -> ThisChainAccountId {
@@ -470,7 +523,7 @@ mod tests {
fn all_finality_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> { fn all_finality_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> {
PreDispatchData { PreDispatchData {
relayer: relayer_account_at_this_chain(), relayer: relayer_account_at_this_chain(),
call_type: CallType::AllFinalityAndDelivery( call_info: CallInfo::AllFinalityAndDelivery(
200, 200,
SubmitParachainHeadsInfo { SubmitParachainHeadsInfo {
at_relay_block_number: 200, at_relay_block_number: 200,
@@ -489,7 +542,7 @@ mod tests {
fn parachain_finality_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> { fn parachain_finality_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> {
PreDispatchData { PreDispatchData {
relayer: relayer_account_at_this_chain(), relayer: relayer_account_at_this_chain(),
call_type: CallType::ParachainFinalityAndDelivery( call_info: CallInfo::ParachainFinalityAndDelivery(
SubmitParachainHeadsInfo { SubmitParachainHeadsInfo {
at_relay_block_number: 200, at_relay_block_number: 200,
para_id: ParaId(TestParachain::get()), para_id: ParaId(TestParachain::get()),
@@ -507,7 +560,7 @@ mod tests {
fn delivery_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> { fn delivery_pre_dispatch_data() -> PreDispatchData<ThisChainAccountId> {
PreDispatchData { PreDispatchData {
relayer: relayer_account_at_this_chain(), relayer: relayer_account_at_this_chain(),
call_type: CallType::Delivery(ReceiveMessagesProofInfo { call_info: CallInfo::Delivery(ReceiveMessagesProofInfo {
lane_id: TEST_LANE_ID, lane_id: TEST_LANE_ID,
best_proof_nonce: 200, best_proof_nonce: 200,
best_stored_nonce: 100, best_stored_nonce: 100,
@@ -520,14 +573,14 @@ mod tests {
} }
fn run_validate(call: RuntimeCall) -> TransactionValidity { fn run_validate(call: RuntimeCall) -> TransactionValidity {
let extension: TestExtension = RefundRelayerForMessagesFromParachain(PhantomData); let extension: TestExtension = RefundBridgedParachainMessages(PhantomData);
extension.validate(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) extension.validate(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0)
} }
fn run_pre_dispatch( fn run_pre_dispatch(
call: RuntimeCall, call: RuntimeCall,
) -> Result<Option<PreDispatchData<ThisChainAccountId>>, TransactionValidityError> { ) -> Result<Option<PreDispatchData<ThisChainAccountId>>, TransactionValidityError> {
let extension: TestExtension = RefundRelayerForMessagesFromParachain(PhantomData); let extension: TestExtension = RefundBridgedParachainMessages(PhantomData);
extension.pre_dispatch(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) extension.pre_dispatch(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0)
} }
+3 -6
View File
@@ -17,14 +17,11 @@
use crate::{Config, Pallet, RelayBlockNumber}; use crate::{Config, Pallet, RelayBlockNumber};
use bp_parachains::BestParaHeadHash; use bp_parachains::BestParaHeadHash;
use bp_polkadot_core::parachains::{ParaHash, ParaId}; use bp_polkadot_core::parachains::{ParaHash, ParaId};
use frame_support::{dispatch::CallableCallFor, traits::IsSubType}; use frame_support::{dispatch::CallableCallFor, traits::IsSubType, RuntimeDebug};
use sp_runtime::{ use sp_runtime::transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction};
transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction},
RuntimeDebug,
};
/// Info about a `SubmitParachainHeads` call which tries to update a single parachain. /// Info about a `SubmitParachainHeads` call which tries to update a single parachain.
#[derive(Copy, Clone, PartialEq, RuntimeDebug)] #[derive(PartialEq, RuntimeDebug)]
pub struct SubmitParachainHeadsInfo { pub struct SubmitParachainHeadsInfo {
pub at_relay_block_number: RelayBlockNumber, pub at_relay_block_number: RelayBlockNumber,
pub para_id: ParaId, pub para_id: ParaId,
+24
View File
@@ -507,6 +507,24 @@ impl WeightExtraOps for Weight {
} }
} }
/// Trait that provides a static `str`.
pub trait StaticStrProvider {
const STR: &'static str;
}
#[macro_export]
macro_rules! generate_static_str_provider {
($str:expr) => {
$crate::paste::item! {
pub struct [<Str $str>];
impl $crate::StaticStrProvider for [<Str $str>] {
const STR: &'static str = stringify!($str);
}
}
};
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@@ -531,4 +549,10 @@ mod tests {
), ),
); );
} }
#[test]
fn generate_static_str_provider_works() {
generate_static_str_provider!(Test);
assert_eq!(StrTest::STR, "Test");
}
} }
+1 -1
View File
@@ -95,7 +95,7 @@ impl ChainWithTransactions for Millau {
frame_system::CheckWeight::<millau_runtime::Runtime>::new(), frame_system::CheckWeight::<millau_runtime::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<millau_runtime::Runtime>::from(unsigned.tip), pallet_transaction_payment::ChargeTransactionPayment::<millau_runtime::Runtime>::from(unsigned.tip),
millau_runtime::BridgeRejectObsoleteHeadersAndMessages, millau_runtime::BridgeRejectObsoleteHeadersAndMessages,
millau_runtime::BridgeRefundRialtoParachainRelayers::default(), millau_runtime::BridgeRefundRialtoParachainMessages::default(),
), ),
( (
(), (),