From 5ba8fa0e806b45eb71cdb49127cd238eb4430368 Mon Sep 17 00:00:00 2001 From: Serban Iorga Date: Mon, 20 Feb 2023 16:36:13 +0200 Subject: [PATCH] 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 --- bridges/bin/millau/runtime/src/lib.rs | 28 +- .../runtime-common/src/messages_call_ext.rs | 6 +- .../src/refund_relayer_extension.rs | 347 ++++++++++-------- bridges/modules/parachains/src/call_ext.rs | 9 +- bridges/primitives/runtime/src/lib.rs | 24 ++ bridges/relays/client-millau/src/lib.rs | 2 +- 6 files changed, 247 insertions(+), 169 deletions(-) diff --git a/bridges/bin/millau/runtime/src/lib.rs b/bridges/bin/millau/runtime/src/lib.rs index 5a18f8b12c03..369bea2b1faf 100644 --- a/bridges/bin/millau/runtime/src/lib.rs +++ b/bridges/bin/millau/runtime/src/lib.rs @@ -80,7 +80,13 @@ pub use pallet_sudo::Call as SudoCall; pub use pallet_timestamp::Call as TimestampCall; 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))] pub use sp_runtime::BuildStorage; pub use sp_runtime::{Perbill, Permill}; @@ -582,17 +588,15 @@ generate_bridge_reject_obsolete_headers_and_messages! { BridgeRialtoMessages, BridgeRialtoParachainMessages } +bp_runtime::generate_static_str_provider!(BridgeRefundRialtoPara2000Lane0Msgs); /// Signed extension that refunds relayers that are delivering messages from the Rialto parachain. -pub type BridgeRefundRialtoParachainRelayers = - bridge_runtime_common::refund_relayer_extension::RefundRelayerForMessagesFromParachain< - Runtime, - RialtoGrandpaInstance, - WithRialtoParachainsInstance, - WithRialtoParachainMessagesInstance, - RialtoParachainId, - RialtoParachainMessagesLane, - Runtime, - >; +pub type BridgeRefundRialtoParachainMessages = RefundBridgedParachainMessages< + Runtime, + RefundableParachain, + RefundableMessagesLane, + ActualFeeRefund, + StrBridgeRefundRialtoPara2000Lane0Msgs, +>; /// The address format for describing accounts. pub type Address = AccountId; @@ -615,7 +619,7 @@ pub type SignedExtra = ( frame_system::CheckWeight, pallet_transaction_payment::ChargeTransactionPayment, BridgeRejectObsoleteHeadersAndMessages, - BridgeRefundRialtoParachainRelayers, + BridgeRefundRialtoParachainMessages, ); /// The payload being signed in transactions. pub type SignedPayload = generic::SignedPayload; diff --git a/bridges/bin/runtime-common/src/messages_call_ext.rs b/bridges/bin/runtime-common/src/messages_call_ext.rs index 20e604142d94..740d17129c89 100644 --- a/bridges/bin/runtime-common/src/messages_call_ext.rs +++ b/bridges/bin/runtime-common/src/messages_call_ext.rs @@ -18,12 +18,12 @@ use crate::messages::{ source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, }; 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 sp_runtime::{transaction_validity::TransactionValidity, RuntimeDebug}; +use sp_runtime::transaction_validity::TransactionValidity; /// Info about a `ReceiveMessagesProof` call which tries to update a single lane. -#[derive(Copy, Clone, PartialEq, RuntimeDebug)] +#[derive(PartialEq, RuntimeDebug)] pub struct ReceiveMessagesProofInfo { pub lane_id: LaneId, pub best_proof_nonce: MessageNonce, diff --git a/bridges/bin/runtime-common/src/refund_relayer_extension.rs b/bridges/bin/runtime-common/src/refund_relayer_extension.rs index ac65617483d5..9efeedf24dd5 100644 --- a/bridges/bin/runtime-common/src/refund_relayer_extension.rs +++ b/bridges/bin/runtime-common/src/refund_relayer_extension.rs @@ -23,6 +23,7 @@ use crate::messages_call_ext::{ MessagesCallSubType, ReceiveMessagesProofHelper, ReceiveMessagesProofInfo, }; use bp_messages::LaneId; +use bp_runtime::StaticStrProvider; use codec::{Decode, Encode}; use frame_support::{ dispatch::{CallableCallFor, DispatchInfo, Dispatchable, PostDispatchInfo}, @@ -46,28 +47,77 @@ use sp_runtime::{ }; use sp_std::{marker::PhantomData, vec, vec::Vec}; -// TODO (https://github.com/paritytech/parity-bridges-common/issues/1667): -// support multiple bridges in this extension +// without this typedef rustfmt fails with internal err +type BalanceOf = + <::OnChargeTransaction as OnChargeTransaction>::Balance; +type CallOf = ::RuntimeCall; + +/// Trait identifying a bridged parachain. A relayer might be refunded for delivering messages +/// coming from this parachain. +trait RefundableParachainId { + /// The instance of the bridge parachains pallet. + type Instance; + /// The parachain Id. + type Id: Get; +} -/// Transaction fee calculation. -pub trait TransactionFeeCalculation { - /// Compute fee that is paid for given transaction. The fee is later refunded to relayer. - fn compute_fee( +/// Default implementation of `RefundableParachainId`. +pub struct RefundableParachain(PhantomData<(Instance, Id)>); + +impl RefundableParachainId for RefundableParachain +where + Id: Get, +{ + 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; +} + +/// Default implementation of `RefundableMessagesLaneId`. +pub struct RefundableMessagesLane(PhantomData<(Instance, Id)>); + +impl RefundableMessagesLaneId for RefundableMessagesLane +where + Id: Get, +{ + 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, post_info: &PostDispatchInfo, len: usize, - tip: Balance, - ) -> Balance; + tip: Self::Balance, + ) -> Self::Balance; } -impl TransactionFeeCalculation> for R +/// `RefundCalculator` implementation which refunds the actual transaction fee. +pub struct ActualFeeRefund(PhantomData); + +impl RefundCalculator for ActualFeeRefund where R: TransactionPaymentConfig, - ::RuntimeCall: - Dispatchable, + CallOf: Dispatchable, BalanceOf: FixedPointOperand, { - fn compute_fee( + type Balance = BalanceOf; + + fn compute_refund( info: &DispatchInfo, post_info: &PostDispatchInfo, 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 { + /// 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 { + 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`) /// 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. #[derive( + DefaultNoBound, CloneNoBound, Decode, - DefaultNoBound, Encode, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, )] -#[scale_info(skip_type_params(RT, GI, PI, MI, PID, LID, FEE))] -pub struct RefundRelayerForMessagesFromParachain( - PhantomData<(RT, GI, PI, MI, PID, LID, FEE)>, +#[scale_info(skip_type_params(Runtime, Para, Msgs, Refund, Id))] +pub struct RefundBridgedParachainMessages( + PhantomData<(Runtime, Para, Msgs, Refund, Id)>, ); -impl - RefundRelayerForMessagesFromParachain +impl + RefundBridgedParachainMessages where - R: UtilityConfig>, - CallOf: IsSubType, R>>, + Runtime: UtilityConfig>, + CallOf: IsSubType, Runtime>>, { - fn expand_call<'a>(&self, call: &'a CallOf) -> Option>> { + fn expand_call<'a>(&self, call: &'a CallOf) -> Option>> { let calls = match call.is_sub_type() { - Some(UtilityCall::::batch_all { ref calls }) => { + Some(UtilityCall::::batch_all { ref calls }) => { if calls.len() > 3 { return None } @@ -123,71 +221,30 @@ where } } -/// Data that is crafted in `pre_dispatch` method and used at `post_dispatch`. -#[derive(PartialEq)] -#[cfg_attr(test, derive(Debug))] -pub struct PreDispatchData { - /// 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 = - <::OnChargeTransaction as OnChargeTransaction>::Balance; -type CallOf = ::RuntimeCall; - -impl SignedExtension - for RefundRelayerForMessagesFromParachain +impl SignedExtension + for RefundBridgedParachainMessages where - R: 'static - + Send - + Sync - + UtilityConfig> - + BoundedBridgeGrandpaConfig - + ParachainsConfig - + MessagesConfig + Self: 'static + Send + Sync, + Runtime: UtilityConfig> + + BoundedBridgeGrandpaConfig + + ParachainsConfig + + MessagesConfig + RelayersConfig, - GI: 'static + Send + Sync, - PI: 'static + Send + Sync, - MI: 'static + Send + Sync, - PID: 'static + Send + Sync + Get, - LID: 'static + Send + Sync + Get, - FEE: 'static + Send + Sync + TransactionFeeCalculation<::Reward>, - CallOf: Dispatchable - + IsSubType, R>> - + GrandpaCallSubType - + ParachainsCallSubType - + MessagesCallSubType, + Para: RefundableParachainId, + Msgs: RefundableMessagesLaneId, + Refund: RefundCalculator, + Id: StaticStrProvider, + CallOf: Dispatchable + + IsSubType, Runtime>> + + GrandpaCallSubType + + ParachainsCallSubType + + MessagesCallSubType, { - const IDENTIFIER: &'static str = "RefundRelayerForMessagesFromParachain"; - type AccountId = R::AccountId; - type Call = CallOf; + const IDENTIFIER: &'static str = Id::STR; + type AccountId = Runtime::AccountId; + type Call = CallOf; type AdditionalSigned = (); - type Pre = Option>; + type Pre = Option>; fn additional_signed(&self) -> Result<(), TransactionValidityError> { Ok(()) @@ -200,15 +257,12 @@ where _info: &DispatchInfoOf, _len: usize, ) -> TransactionValidity { - let calls = match self.expand_call(call) { - Some(calls) => calls, - None => return Ok(ValidTransaction::default()), - }; - - for call in calls { - call.check_obsolete_submit_finality_proof()?; - call.check_obsolete_submit_parachain_heads()?; - call.check_obsolete_receive_messages_proof()?; + if let Some(calls) = self.expand_call(call) { + for nested_call in calls { + nested_call.check_obsolete_submit_finality_proof()?; + nested_call.check_obsolete_submit_parachain_heads()?; + nested_call.check_obsolete_receive_messages_proof()?; + } } Ok(ValidTransaction::default()) @@ -225,35 +279,35 @@ where self.validate(who, call, info, len).map(drop)?; // 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(); match calls.len() { - 3 => Some(CallType::AllFinalityAndDelivery( + 3 => Some(CallInfo::AllFinalityAndDelivery( calls.next()?.submit_finality_proof_info()?, - calls.next()?.submit_parachain_heads_info_for(PID::get())?, - calls.next()?.receive_messages_proof_info_for(LID::get())?, + calls.next()?.submit_parachain_heads_info_for(Para::Id::get())?, + calls.next()?.receive_messages_proof_info_for(Msgs::Id::get())?, )), - 2 => Some(CallType::ParachainFinalityAndDelivery( - calls.next()?.submit_parachain_heads_info_for(PID::get())?, - calls.next()?.receive_messages_proof_info_for(LID::get())?, + 2 => Some(CallInfo::ParachainFinalityAndDelivery( + calls.next()?.submit_parachain_heads_info_for(Para::Id::get())?, + calls.next()?.receive_messages_proof_info_for(Msgs::Id::get())?, )), - 1 => Some(CallType::Delivery( - calls.next()?.receive_messages_proof_info_for(LID::get())?, + 1 => Some(CallInfo::Delivery( + calls.next()?.receive_messages_proof_info_for(Msgs::Id::get())?, )), _ => None, } }; - Ok(parse_call_type().map(|call_type| { + Ok(parse_call().map(|call_info| { log::trace!( target: "runtime::bridge", - "RefundRelayerForMessagesFromParachain from parachain {} via {:?} \ - parsed bridge transaction in pre-dispatch: {:?}", - PID::get(), - LID::get(), - call_type, + "{} from parachain {} via {:?} parsed bridge transaction in pre-dispatch: {:?}", + Self::IDENTIFIER, + Para::Id::get(), + Msgs::Id::get(), + 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. - let (relayer, call_type) = match pre { - Some(Some(pre)) => (pre.relayer, pre.call_type), + let (relayer, call_info) = match pre { + Some(Some(pre)) => (pre.relayer, pre.call_info), _ => return Ok(()), }; // check if relay chain state has been updated - if let CallType::AllFinalityAndDelivery(relay_block_number, _, _) = call_type { - if !SubmitFinalityProofHelper::::was_successful(relay_block_number) { + if let Some(relay_block_number) = call_info.submit_finality_proof_info() { + if !SubmitFinalityProofHelper::::was_successful(relay_block_number) { // we only refund relayer if all calls have updated chain state return Ok(()) } @@ -291,44 +345,44 @@ where } // check if parachain state has been updated - match call_type { - CallType::AllFinalityAndDelivery(_, parachain_heads_info, _) | - CallType::ParachainFinalityAndDelivery(parachain_heads_info, _) => { - if !SubmitParachainHeadsHelper::::was_successful(¶chain_heads_info) { - // we only refund relayer if all calls have updated chain state - return Ok(()) - } - }, - _ => (), + if let Some(para_proof_info) = call_info.submit_parachain_heads_info() { + if !SubmitParachainHeadsHelper::::was_successful( + para_proof_info, + ) { + // we only refund relayer if all calls have updated chain state + return Ok(()) + } } // 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. - let messages_proof_info = call_type.receive_messages_proof_info(); - if !ReceiveMessagesProofHelper::::was_partially_successful(&messages_proof_info) { + let msgs_proof_info = call_info.receive_messages_proof_info(); + if !ReceiveMessagesProofHelper::::was_partially_successful( + msgs_proof_info, + ) { return Ok(()) } // 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 - // (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 // cost of this attack is nothing. Hence we use zero as tip here. let tip = Zero::zero(); - // compute the relayer reward - let reward = FEE::compute_fee(info, post_info, len, tip); - - // finally - register reward in relayers pallet - RelayersPallet::::register_relayer_reward(LID::get(), &relayer, reward); + // compute the relayer refund + let refund = Refund::compute_refund(info, post_info, len, tip); + // finally - register refund in relayers pallet + RelayersPallet::::register_relayer_reward(Msgs::Id::get(), &relayer, refund); log::trace!( target: "runtime::bridge", - "RefundRelayerForMessagesFromParachain from parachain {} via {:?} has registered {:?} reward: {:?}", - PID::get(), - LID::get(), + "{} from parachain {} via {:?} has registered reward: {:?} for {:?}", + Self::IDENTIFIER, + Para::Id::get(), + Msgs::Id::get(), + refund, relayer, - reward, ); Ok(()) @@ -353,18 +407,17 @@ mod tests { }; parameter_types! { - pub TestParachain: u32 = 1000; + TestParachain: u32 = 1000; pub TestLaneId: LaneId = TEST_LANE_ID; } - type TestExtension = RefundRelayerForMessagesFromParachain< - TestRuntime, - (), - (), - (), - TestParachain, - TestLaneId, + bp_runtime::generate_static_str_provider!(TestExtension); + type TestExtension = RefundBridgedParachainMessages< TestRuntime, + RefundableParachain<(), TestParachain>, + RefundableMessagesLane<(), TestLaneId>, + ActualFeeRefund, + StrTestExtension, >; fn relayer_account_at_this_chain() -> ThisChainAccountId { @@ -470,7 +523,7 @@ mod tests { fn all_finality_pre_dispatch_data() -> PreDispatchData { PreDispatchData { relayer: relayer_account_at_this_chain(), - call_type: CallType::AllFinalityAndDelivery( + call_info: CallInfo::AllFinalityAndDelivery( 200, SubmitParachainHeadsInfo { at_relay_block_number: 200, @@ -489,7 +542,7 @@ mod tests { fn parachain_finality_pre_dispatch_data() -> PreDispatchData { PreDispatchData { relayer: relayer_account_at_this_chain(), - call_type: CallType::ParachainFinalityAndDelivery( + call_info: CallInfo::ParachainFinalityAndDelivery( SubmitParachainHeadsInfo { at_relay_block_number: 200, para_id: ParaId(TestParachain::get()), @@ -507,7 +560,7 @@ mod tests { fn delivery_pre_dispatch_data() -> PreDispatchData { PreDispatchData { relayer: relayer_account_at_this_chain(), - call_type: CallType::Delivery(ReceiveMessagesProofInfo { + call_info: CallInfo::Delivery(ReceiveMessagesProofInfo { lane_id: TEST_LANE_ID, best_proof_nonce: 200, best_stored_nonce: 100, @@ -520,14 +573,14 @@ mod tests { } 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) } fn run_pre_dispatch( call: RuntimeCall, ) -> Result>, TransactionValidityError> { - let extension: TestExtension = RefundRelayerForMessagesFromParachain(PhantomData); + let extension: TestExtension = RefundBridgedParachainMessages(PhantomData); extension.pre_dispatch(&relayer_account_at_this_chain(), &call, &DispatchInfo::default(), 0) } diff --git a/bridges/modules/parachains/src/call_ext.rs b/bridges/modules/parachains/src/call_ext.rs index 41649336579e..5aed9e80ba0e 100644 --- a/bridges/modules/parachains/src/call_ext.rs +++ b/bridges/modules/parachains/src/call_ext.rs @@ -17,14 +17,11 @@ use crate::{Config, Pallet, RelayBlockNumber}; use bp_parachains::BestParaHeadHash; use bp_polkadot_core::parachains::{ParaHash, ParaId}; -use frame_support::{dispatch::CallableCallFor, traits::IsSubType}; -use sp_runtime::{ - transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction}, - RuntimeDebug, -}; +use frame_support::{dispatch::CallableCallFor, traits::IsSubType, RuntimeDebug}; +use sp_runtime::transaction_validity::{InvalidTransaction, TransactionValidity, ValidTransaction}; /// Info about a `SubmitParachainHeads` call which tries to update a single parachain. -#[derive(Copy, Clone, PartialEq, RuntimeDebug)] +#[derive(PartialEq, RuntimeDebug)] pub struct SubmitParachainHeadsInfo { pub at_relay_block_number: RelayBlockNumber, pub para_id: ParaId, diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index 75151ccb7237..0121b4ab84eb 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -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 []; + + impl $crate::StaticStrProvider for [] { + const STR: &'static str = stringify!($str); + } + } + }; +} + #[cfg(test)] mod tests { 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"); + } } diff --git a/bridges/relays/client-millau/src/lib.rs b/bridges/relays/client-millau/src/lib.rs index 711b4f32cc63..4c4c1370a6a5 100644 --- a/bridges/relays/client-millau/src/lib.rs +++ b/bridges/relays/client-millau/src/lib.rs @@ -95,7 +95,7 @@ impl ChainWithTransactions for Millau { frame_system::CheckWeight::::new(), pallet_transaction_payment::ChargeTransactionPayment::::from(unsigned.tip), millau_runtime::BridgeRejectObsoleteHeadersAndMessages, - millau_runtime::BridgeRefundRialtoParachainRelayers::default(), + millau_runtime::BridgeRefundRialtoParachainMessages::default(), ), ( (),