Migrate dispatch pallet to frame v2 (#1089)

* pallet-bridge-dispatch -> frame v2

* fix metadata
This commit is contained in:
Svyatoslav Nikolsky
2021-08-11 11:32:09 +03:00
committed by Bastian Köcher
parent b1db3df199
commit 239790fc72
4 changed files with 95 additions and 89 deletions
@@ -69,7 +69,7 @@ pub type FromRialtoMessageDispatch = messages::target::FromBridgedChainMessageDi
WithRialtoMessageBridge, WithRialtoMessageBridge,
crate::Runtime, crate::Runtime,
pallet_balances::Pallet<Runtime>, pallet_balances::Pallet<Runtime>,
pallet_bridge_dispatch::DefaultInstance, (),
>; >;
/// Millau <-> Rialto message bridge. /// Millau <-> Rialto message bridge.
@@ -63,7 +63,7 @@ pub type FromMillauMessageDispatch = messages::target::FromBridgedChainMessageDi
WithMillauMessageBridge, WithMillauMessageBridge,
crate::Runtime, crate::Runtime,
pallet_balances::Pallet<Runtime>, pallet_balances::Pallet<Runtime>,
pallet_bridge_dispatch::DefaultInstance, (),
>; >;
/// Messages proof for Millau -> Rialto messages. /// Messages proof for Millau -> Rialto messages.
+1 -4
View File
@@ -492,15 +492,12 @@ pub mod target {
for FromBridgedChainMessageDispatch<B, ThisRuntime, ThisCurrency, ThisDispatchInstance> for FromBridgedChainMessageDispatch<B, ThisRuntime, ThisCurrency, ThisDispatchInstance>
where where
BalanceOf<ThisChain<B>>: Saturating + FixedPointOperand, BalanceOf<ThisChain<B>>: Saturating + FixedPointOperand,
ThisDispatchInstance: frame_support::traits::Instance, ThisDispatchInstance: 'static,
ThisRuntime: pallet_bridge_dispatch::Config<ThisDispatchInstance, MessageId = (LaneId, MessageNonce)> ThisRuntime: pallet_bridge_dispatch::Config<ThisDispatchInstance, MessageId = (LaneId, MessageNonce)>
+ pallet_transaction_payment::Config, + pallet_transaction_payment::Config,
<ThisRuntime as pallet_transaction_payment::Config>::OnChargeTransaction: <ThisRuntime as pallet_transaction_payment::Config>::OnChargeTransaction:
pallet_transaction_payment::OnChargeTransaction<ThisRuntime, Balance = BalanceOf<ThisChain<B>>>, pallet_transaction_payment::OnChargeTransaction<ThisRuntime, Balance = BalanceOf<ThisChain<B>>>,
ThisCurrency: Currency<AccountIdOf<ThisChain<B>>, Balance = BalanceOf<ThisChain<B>>>, ThisCurrency: Currency<AccountIdOf<ThisChain<B>>, Balance = BalanceOf<ThisChain<B>>>,
<ThisRuntime as pallet_bridge_dispatch::Config<ThisDispatchInstance>>::Event: From<
pallet_bridge_dispatch::RawEvent<(LaneId, MessageNonce), AccountIdOf<ThisChain<B>>, ThisDispatchInstance>,
>,
pallet_bridge_dispatch::Pallet<ThisRuntime, ThisDispatchInstance>: bp_message_dispatch::MessageDispatch< pallet_bridge_dispatch::Pallet<ThisRuntime, ThisDispatchInstance>: bp_message_dispatch::MessageDispatch<
AccountIdOf<ThisChain<B>>, AccountIdOf<ThisChain<B>>,
(LaneId, MessageNonce), (LaneId, MessageNonce),
+92 -83
View File
@@ -26,116 +26,124 @@
// Generated by `decl_event!` // Generated by `decl_event!`
#![allow(clippy::unused_unit)] #![allow(clippy::unused_unit)]
use bp_message_dispatch::{CallOrigin, MessageDispatch, MessagePayload, SpecVersion, Weight}; use bp_message_dispatch::{CallOrigin, MessageDispatch, MessagePayload, SpecVersion};
use bp_runtime::{ use bp_runtime::{
derive_account_id, derive_account_id,
messages::{DispatchFeePayment, MessageDispatchResult}, messages::{DispatchFeePayment, MessageDispatchResult},
ChainId, SourceAccount, ChainId, SourceAccount,
}; };
use codec::{Decode, Encode}; use codec::Encode;
use frame_support::{ use frame_support::{
decl_event, decl_module, decl_storage, dispatch::Dispatchable,
dispatch::{Dispatchable, Parameter},
ensure, ensure,
traits::{Filter, Get}, traits::{Filter, Get},
weights::{extract_actual_weight, GetDispatchInfo}, weights::{extract_actual_weight, GetDispatchInfo},
}; };
use frame_system::RawOrigin; use frame_system::RawOrigin;
use sp_runtime::{ use sp_runtime::traits::{BadOrigin, Convert, IdentifyAccount, MaybeDisplay, Verify};
traits::{BadOrigin, Convert, IdentifyAccount, MaybeDisplay, MaybeSerializeDeserialize, Member, Verify}, use sp_std::{fmt::Debug, prelude::*};
DispatchResult,
};
use sp_std::{fmt::Debug, marker::PhantomData, prelude::*};
/// The module configuration trait. pub use pallet::*;
pub trait Config<I = DefaultInstance>: frame_system::Config {
/// The overarching event type.
type Event: From<Event<Self, I>> + Into<<Self as frame_system::Config>::Event>;
/// Id of the message. Whenever message is passed to the dispatch module, it emits
/// event with this id + dispatch result. Could be e.g. (LaneId, MessageNonce) if
/// it comes from the messages module.
type MessageId: Parameter;
/// Type of account ID on source chain.
type SourceChainAccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + Default;
/// Type of account public key on target chain.
type TargetChainAccountPublic: Parameter + IdentifyAccount<AccountId = Self::AccountId>;
/// Type of signature that may prove that the message has been signed by
/// owner of `TargetChainAccountPublic`.
type TargetChainSignature: Parameter + Verify<Signer = Self::TargetChainAccountPublic>;
/// The overarching dispatch call type.
type Call: Parameter
+ GetDispatchInfo
+ Dispatchable<
Origin = <Self as frame_system::Config>::Origin,
PostInfo = frame_support::dispatch::PostDispatchInfo,
>;
/// Pre-dispatch filter for incoming calls.
///
/// 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: Filter<<Self as Config<I>>::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
/// that all other stuff (like `spec_version`) is ok. If we would try to decode
/// `Call` which has been encoded using previous `spec_version`, then we might end
/// up with decoding error, instead of `MessageVersionSpecMismatch`.
type EncodedCall: Decode + Encode + Into<Result<<Self as Config<I>>::Call, ()>>;
/// A type which can be turned into an AccountId from a 256-bit hash.
///
/// Used when deriving target chain AccountIds from source chain AccountIds.
type AccountIdConverter: sp_runtime::traits::Convert<sp_core::hash::H256, Self::AccountId>;
}
decl_storage! { #[frame_support::pallet]
trait Store for Pallet<T: Config<I>, I: Instance = DefaultInstance> as Dispatch {} pub mod pallet {
} use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
decl_event!( #[pallet::config]
pub enum Event<T, I = DefaultInstance> where pub trait Config<I: 'static = ()>: frame_system::Config {
<T as Config<I>>::MessageId, /// The overarching event type.
AccountId = <T as frame_system::Config>::AccountId, type Event: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::Event>;
{ /// Id of the message. Whenever message is passed to the dispatch module, it emits
/// event with this id + dispatch result. Could be e.g. (LaneId, MessageNonce) if
/// it comes from the messages module.
type MessageId: Parameter;
/// Type of account ID on source chain.
type SourceChainAccountId: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + Ord + Default;
/// Type of account public key on target chain.
type TargetChainAccountPublic: Parameter + IdentifyAccount<AccountId = Self::AccountId>;
/// Type of signature that may prove that the message has been signed by
/// owner of `TargetChainAccountPublic`.
type TargetChainSignature: Parameter + Verify<Signer = Self::TargetChainAccountPublic>;
/// The overarching dispatch call type.
type Call: Parameter
+ GetDispatchInfo
+ Dispatchable<
Origin = <Self as frame_system::Config>::Origin,
PostInfo = frame_support::dispatch::PostDispatchInfo,
>;
/// Pre-dispatch filter for incoming calls.
///
/// 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: Filter<<Self as Config<I>>::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
/// that all other stuff (like `spec_version`) is ok. If we would try to decode
/// `Call` which has been encoded using previous `spec_version`, then we might end
/// up with decoding error, instead of `MessageVersionSpecMismatch`.
type EncodedCall: Decode + Encode + Into<Result<<Self as Config<I>>::Call, ()>>;
/// A type which can be turned into an AccountId from a 256-bit hash.
///
/// Used when deriving target chain AccountIds from source chain AccountIds.
type AccountIdConverter: sp_runtime::traits::Convert<sp_core::hash::H256, Self::AccountId>;
}
type MessageIdOf<T, I> = <T as Config<I>>::MessageId;
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);
#[pallet::hooks]
impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {}
#[pallet::call]
impl<T: Config<I>, I: 'static> Pallet<T, I> {}
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
#[pallet::metadata(<T as frame_system::Config>::AccountId = "AccountId", MessageIdOf<T, I> = "MessageId")]
pub enum Event<T: Config<I>, I: 'static = ()> {
/// Message has been rejected before reaching dispatch. /// Message has been rejected before reaching dispatch.
MessageRejected(ChainId, MessageId), MessageRejected(ChainId, MessageIdOf<T, I>),
/// Message has been rejected by dispatcher because of spec version mismatch. /// Message has been rejected by dispatcher because of spec version mismatch.
/// Last two arguments are: expected and passed spec version. /// Last two arguments are: expected and passed spec version.
MessageVersionSpecMismatch(ChainId, MessageId, SpecVersion, SpecVersion), MessageVersionSpecMismatch(ChainId, MessageIdOf<T, I>, SpecVersion, SpecVersion),
/// Message has been rejected by dispatcher because of weight mismatch. /// Message has been rejected by dispatcher because of weight mismatch.
/// Last two arguments are: expected and passed call weight. /// Last two arguments are: expected and passed call weight.
MessageWeightMismatch(ChainId, MessageId, Weight, Weight), MessageWeightMismatch(ChainId, MessageIdOf<T, I>, Weight, Weight),
/// Message signature mismatch. /// Message signature mismatch.
MessageSignatureMismatch(ChainId, MessageId), MessageSignatureMismatch(ChainId, MessageIdOf<T, I>),
/// We have failed to decode Call from the message. /// We have failed to decode Call from the message.
MessageCallDecodeFailed(ChainId, MessageId), MessageCallDecodeFailed(ChainId, MessageIdOf<T, I>),
/// The call from the message has been rejected by the call filter. /// The call from the message has been rejected by the call filter.
MessageCallRejected(ChainId, MessageId), MessageCallRejected(ChainId, MessageIdOf<T, I>),
/// The origin account has failed to pay fee for dispatching the message. /// The origin account has failed to pay fee for dispatching the message.
MessageDispatchPaymentFailed(ChainId, MessageId, AccountId, Weight), MessageDispatchPaymentFailed(
ChainId,
MessageIdOf<T, I>,
<T as frame_system::Config>::AccountId,
Weight,
),
/// Message has been dispatched with given result. /// Message has been dispatched with given result.
MessageDispatched(ChainId, MessageId, DispatchResult), MessageDispatched(ChainId, MessageIdOf<T, I>, DispatchResult),
/// Phantom member, never used. Needed to handle multiple pallet instances. /// Phantom member, never used. Needed to handle multiple pallet instances.
_Dummy(PhantomData<I>), _Dummy(PhantomData<I>),
} }
);
decl_module! {
/// Call Dispatch FRAME Pallet.
pub struct Module<T: Config<I>, I: Instance = DefaultInstance> for enum Call where origin: T::Origin {
/// Deposit one of this module's events by using the default implementation.
fn deposit_event() = default;
}
} }
impl<T: Config<I>, I: Instance> MessageDispatch<T::AccountId, T::MessageId> for Pallet<T, I> { impl<T: Config<I>, I: 'static> MessageDispatch<T::AccountId, T::MessageId> for Pallet<T, I> {
type Message = type Message =
MessagePayload<T::SourceChainAccountId, T::TargetChainAccountPublic, T::TargetChainSignature, T::EncodedCall>; MessagePayload<T::SourceChainAccountId, T::TargetChainAccountPublic, T::TargetChainSignature, T::EncodedCall>;
fn dispatch_weight(message: &Self::Message) -> Weight { fn dispatch_weight(message: &Self::Message) -> bp_message_dispatch::Weight {
message.weight message.weight
} }
fn dispatch<P: FnOnce(&T::AccountId, Weight) -> Result<(), ()>>( fn dispatch<P: FnOnce(&T::AccountId, bp_message_dispatch::Weight) -> Result<(), ()>>(
source_chain: ChainId, source_chain: ChainId,
target_chain: ChainId, target_chain: ChainId,
id: T::MessageId, id: T::MessageId,
@@ -152,7 +160,7 @@ impl<T: Config<I>, I: Instance> MessageDispatch<T::AccountId, T::MessageId> for
source_chain, source_chain,
id, id,
); );
Self::deposit_event(RawEvent::MessageRejected(source_chain, id)); Self::deposit_event(Event::MessageRejected(source_chain, id));
return MessageDispatchResult { return MessageDispatchResult {
dispatch_result: false, dispatch_result: false,
unspent_weight: 0, unspent_weight: 0,
@@ -177,7 +185,7 @@ impl<T: Config<I>, I: Instance> MessageDispatch<T::AccountId, T::MessageId> for
expected_version, expected_version,
message.spec_version, message.spec_version,
); );
Self::deposit_event(RawEvent::MessageVersionSpecMismatch( Self::deposit_event(Event::MessageVersionSpecMismatch(
source_chain, source_chain,
id, id,
expected_version, expected_version,
@@ -196,7 +204,7 @@ impl<T: Config<I>, I: Instance> MessageDispatch<T::AccountId, T::MessageId> for
source_chain, source_chain,
id, id,
); );
Self::deposit_event(RawEvent::MessageCallDecodeFailed(source_chain, id)); Self::deposit_event(Event::MessageCallDecodeFailed(source_chain, id));
return dispatch_result; return dispatch_result;
} }
}; };
@@ -228,7 +236,7 @@ impl<T: Config<I>, I: Instance> MessageDispatch<T::AccountId, T::MessageId> for
target_account, target_account,
target_signature, target_signature,
); );
Self::deposit_event(RawEvent::MessageSignatureMismatch(source_chain, id)); Self::deposit_event(Event::MessageSignatureMismatch(source_chain, id));
return dispatch_result; return dispatch_result;
} }
@@ -252,7 +260,7 @@ impl<T: Config<I>, I: Instance> MessageDispatch<T::AccountId, T::MessageId> for
id, id,
call, call,
); );
Self::deposit_event(RawEvent::MessageCallRejected(source_chain, id)); Self::deposit_event(Event::MessageCallRejected(source_chain, id));
return dispatch_result; return dispatch_result;
} }
@@ -270,7 +278,7 @@ impl<T: Config<I>, I: Instance> MessageDispatch<T::AccountId, T::MessageId> for
expected_weight, expected_weight,
message.weight, message.weight,
); );
Self::deposit_event(RawEvent::MessageWeightMismatch( Self::deposit_event(Event::MessageWeightMismatch(
source_chain, source_chain,
id, id,
expected_weight, expected_weight,
@@ -289,7 +297,7 @@ impl<T: Config<I>, I: Instance> MessageDispatch<T::AccountId, T::MessageId> for
id, id,
message.weight, message.weight,
); );
Self::deposit_event(RawEvent::MessageDispatchPaymentFailed( Self::deposit_event(Event::MessageDispatchPaymentFailed(
source_chain, source_chain,
id, id,
origin_account, origin_account,
@@ -319,7 +327,7 @@ impl<T: Config<I>, I: Instance> MessageDispatch<T::AccountId, T::MessageId> for
result, result,
); );
Self::deposit_event(RawEvent::MessageDispatched( Self::deposit_event(Event::MessageDispatched(
source_chain, source_chain,
id, id,
result.map(drop).map_err(|e| e.error), result.map(drop).map_err(|e| e.error),
@@ -397,6 +405,7 @@ mod tests {
#![allow(clippy::from_over_into)] #![allow(clippy::from_over_into)]
use super::*; use super::*;
use codec::Decode;
use frame_support::{parameter_types, weights::Weight}; use frame_support::{parameter_types, weights::Weight};
use frame_system::{EventRecord, Phase}; use frame_system::{EventRecord, Phase};
use sp_core::H256; use sp_core::H256;