diff --git a/bin/runtime-common/src/messages.rs b/bin/runtime-common/src/messages.rs index d53887192..f4d184a05 100644 --- a/bin/runtime-common/src/messages.rs +++ b/bin/runtime-common/src/messages.rs @@ -548,75 +548,6 @@ pub mod target { } } - /// Dispatching Bridged -> This chain messages. - #[derive(RuntimeDebug, Clone, Copy)] - pub struct FromBridgedChainMessageDispatch { - _marker: PhantomData<(B, ThisRuntime, ThisCurrency, ThisDispatchInstance)>, - } - - impl - MessageDispatch>, BalanceOf>> - for FromBridgedChainMessageDispatch - where - BalanceOf>: Saturating + FixedPointOperand, - ThisDispatchInstance: 'static, - ThisRuntime: pallet_bridge_dispatch::Config< - ThisDispatchInstance, - BridgeMessageId = (LaneId, MessageNonce), - > + pallet_transaction_payment::Config, - ::OnChargeTransaction: - pallet_transaction_payment::OnChargeTransaction< - ThisRuntime, - Balance = BalanceOf>, - >, - ThisCurrency: Currency>, Balance = BalanceOf>>, - pallet_bridge_dispatch::Pallet: - bp_message_dispatch::MessageDispatch< - AccountIdOf>, - (LaneId, MessageNonce), - Message = FromBridgedChainMessagePayload, - >, - { - type DispatchPayload = FromBridgedChainMessagePayload; - - fn dispatch_weight( - message: &DispatchMessage>>, - ) -> frame_support::weights::Weight { - message.data.payload.as_ref().map(|payload| payload.weight).unwrap_or(0) - } - - fn dispatch( - relayer_account: &AccountIdOf>, - message: DispatchMessage>>, - ) -> MessageDispatchResult { - let message_id = (message.key.lane_id, message.key.nonce); - pallet_bridge_dispatch::Pallet::::dispatch( - B::BRIDGED_CHAIN_ID, - B::THIS_CHAIN_ID, - message_id, - message.data.payload.map_err(drop), - |dispatch_origin, dispatch_weight| { - let unadjusted_weight_fee = ThisRuntime::WeightToFee::calc(&dispatch_weight); - let fee_multiplier = - pallet_transaction_payment::Pallet::::next_fee_multiplier(); - let adjusted_weight_fee = - fee_multiplier.saturating_mul_int(unadjusted_weight_fee); - if !adjusted_weight_fee.is_zero() { - ThisCurrency::transfer( - dispatch_origin, - relayer_account, - adjusted_weight_fee, - ExistenceRequirement::AllowDeath, - ) - .map_err(drop) - } else { - Ok(()) - } - }, - ) - } - } - /// Return maximal dispatch weight of the message we're able to receive. pub fn maximal_incoming_message_dispatch_weight(maximal_extrinsic_weight: Weight) -> Weight { maximal_extrinsic_weight / 2 diff --git a/modules/dispatch/src/lib.rs b/modules/dispatch/src/lib.rs index 56b3c7a60..c9607e667 100644 --- a/modules/dispatch/src/lib.rs +++ b/modules/dispatch/src/lib.rs @@ -25,7 +25,9 @@ // Generated by `decl_event!` #![allow(clippy::unused_unit)] -use bp_message_dispatch::{CallOrigin, MessageDispatch, MessagePayload, SpecVersion}; +use bp_message_dispatch::{ + CallFilter, CallOrigin, IntoDispatchOrigin, MessageDispatch, MessagePayload, SpecVersion, +}; use bp_runtime::{ derive_account_id, messages::{DispatchFeePayment, MessageDispatchResult}, @@ -35,7 +37,7 @@ use codec::Encode; use frame_support::{ dispatch::Dispatchable, ensure, - traits::{Contains, Get}, + traits::{Get}, weights::{extract_actual_weight, GetDispatchInfo}, }; use frame_system::RawOrigin; @@ -81,7 +83,7 @@ pub mod pallet { /// /// The pallet will filter all incoming calls right before they're dispatched. If this /// filter rejects the call, special event (`Event::MessageCallRejected`) is emitted. - type CallFilter: Contains<>::Call>; + type CallFilter: CallFilter>::Call>; /// The type that is used to wrap the `Self::Call` when it is moved over bridge. /// /// The idea behind this is to avoid `Call` conversion/decoding until we'll be sure @@ -93,6 +95,12 @@ pub mod pallet { /// /// Used when deriving target chain AccountIds from source chain AccountIds. type AccountIdConverter: sp_runtime::traits::Convert; + /// The type is used to customize the dispatch call origin. + type IntoDispatchOrigin: IntoDispatchOrigin< + Self::AccountId, + >::Call, + Self::Origin, + >; } type BridgeMessageIdOf = >::BridgeMessageId; @@ -138,7 +146,9 @@ pub mod pallet { } } -impl, I: 'static> MessageDispatch for Pallet { +impl, I: 'static> + MessageDispatch>::Call> for Pallet +{ type Message = MessagePayload< T::SourceChainAccountId, T::TargetChainAccountPublic, @@ -150,7 +160,7 @@ impl, I: 'static> MessageDispatch message.weight } - fn dispatch Result<(), ()>>( + fn dispatch>::Call) -> Result<(), ()>>( source_chain: ChainId, target_chain: ChainId, id: T::BridgeMessageId, @@ -260,8 +270,11 @@ impl, I: 'static> MessageDispatch }, }; + // generate dispatch origin from origin account + let origin = T::IntoDispatchOrigin::into_dispatch_origin(&origin_account, &call); + // filter the call - if !T::CallFilter::contains(&call) { + if !T::CallFilter::contains(&origin, &call) { log::trace!( target: "runtime::bridge-dispatch", "Message {:?}/{:?}: the call ({:?}) is rejected by filter", @@ -299,8 +312,7 @@ impl, I: 'static> MessageDispatch // pay dispatch fee right before dispatch let pay_dispatch_fee_at_target_chain = message.dispatch_fee_payment == DispatchFeePayment::AtTargetChain; - if pay_dispatch_fee_at_target_chain - && pay_dispatch_fee(&origin_account, message.weight).is_err() + if pay_dispatch_fee_at_target_chain && pay_dispatch_fee(&origin, &call).is_err() { { log::trace!( target: "runtime::bridge-dispatch", @@ -319,9 +331,6 @@ impl, I: 'static> MessageDispatch } dispatch_result.dispatch_fee_paid_during_dispatch = pay_dispatch_fee_at_target_chain; - // finally dispatch message - let origin = RawOrigin::Signed(origin_account).into(); - log::trace!(target: "runtime::bridge-dispatch", "Message being dispatched is: {:.4096?}", &call); let result = call.dispatch(origin); let actual_call_weight = extract_actual_weight(&result, &dispatch_info); @@ -532,6 +541,7 @@ mod tests { type SourceChainAccountId = AccountId; type TargetChainAccountPublic = TestAccountPublic; type TargetChainSignature = TestSignature; + type IntoDispatchOrigin = TestIntoDispatchOrigin; } #[derive(Decode, Encode)] @@ -545,12 +555,20 @@ mod tests { pub struct TestCallFilter; - impl Contains for TestCallFilter { - fn contains(call: &Call) -> bool { + impl CallFilter for TestCallFilter { + fn contains(_origin: &Origin, call: &Call) -> bool { !matches!(*call, Call::System(frame_system::Call::fill_block { .. })) } } + pub struct TestIntoDispatchOrigin; + + impl IntoDispatchOrigin for TestIntoDispatchOrigin { + fn into_dispatch_origin(id: &AccountId, _call: &Call) -> Origin { + frame_system::RawOrigin::Signed(*id).into() + } + } + const TEST_SPEC_VERSION: SpecVersion = 0; const TEST_WEIGHT: Weight = 1_000_000_000; @@ -564,7 +582,9 @@ mod tests { call: Call, ) -> as MessageDispatch< AccountId, + ::Origin, ::BridgeMessageId, + ::Call, >>::Message { MessagePayload { spec_version: TEST_SPEC_VERSION, @@ -578,8 +598,9 @@ mod tests { fn prepare_root_message( call: Call, ) -> as MessageDispatch< - AccountId, - ::BridgeMessageId, + ::Origin, + ::BridgeMessageId, + ::Call, >>::Message { prepare_message(CallOrigin::SourceRoot, call) } @@ -587,8 +608,9 @@ mod tests { fn prepare_target_message( call: Call, ) -> as MessageDispatch< - AccountId, - ::BridgeMessageId, + ::Origin, + ::BridgeMessageId, + ::Call, >>::Message { let origin = CallOrigin::TargetAccount(1, TestAccountPublic(1), TestSignature(1)); prepare_message(origin, call) @@ -597,8 +619,9 @@ mod tests { fn prepare_source_message( call: Call, ) -> as MessageDispatch< - AccountId, - ::BridgeMessageId, + ::Origin, + ::BridgeMessageId, + ::Call, >>::Message { let origin = CallOrigin::SourceAccount(1); prepare_message(origin, call)