diff --git a/bridges/bin/millau/node/src/chain_spec.rs b/bridges/bin/millau/node/src/chain_spec.rs index 846dfa6930..583510fc34 100644 --- a/bridges/bin/millau/node/src/chain_spec.rs +++ b/bridges/bin/millau/node/src/chain_spec.rs @@ -136,7 +136,7 @@ impl Alternative { get_account_id_from_seed::("Harry//stash"), pallet_bridge_messages::Pallet::< millau_runtime::Runtime, - pallet_bridge_messages::DefaultInstance, + millau_runtime::WithRialtoMessagesInstance, >::relayer_fund_account_id(), derive_account_from_rialto_id(bp_runtime::SourceAccount::Account( get_account_id_from_seed::("Alice"), diff --git a/bridges/bin/millau/runtime/src/lib.rs b/bridges/bin/millau/runtime/src/lib.rs index cc004b8629..ed7580906f 100644 --- a/bridges/bin/millau/runtime/src/lib.rs +++ b/bridges/bin/millau/runtime/src/lib.rs @@ -366,7 +366,7 @@ parameter_types! { } /// Instance of the messages pallet used to relay messages to/from Rialto chain. -pub type WithRialtoMessagesInstance = pallet_bridge_messages::DefaultInstance; +pub type WithRialtoMessagesInstance = (); impl pallet_bridge_messages::Config for Runtime { type Event = Event; diff --git a/bridges/bin/millau/runtime/src/rialto_messages.rs b/bridges/bin/millau/runtime/src/rialto_messages.rs index 5b3d08688c..34b3b231c8 100644 --- a/bridges/bin/millau/runtime/src/rialto_messages.rs +++ b/bridges/bin/millau/runtime/src/rialto_messages.rs @@ -80,10 +80,10 @@ impl MessageBridge for WithRialtoMessageBridge { const RELAYER_FEE_PERCENT: u32 = 10; const THIS_CHAIN_ID: ChainId = MILLAU_CHAIN_ID; const BRIDGED_CHAIN_ID: ChainId = RIALTO_CHAIN_ID; + const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_rialto::WITH_MILLAU_MESSAGES_PALLET_NAME; type ThisChain = Millau; type BridgedChain = Rialto; - type BridgedMessagesInstance = crate::WithRialtoMessagesInstance; fn bridged_balance_to_this_balance(bridged_balance: bp_rialto::Balance) -> bp_millau::Balance { bp_millau::Balance::try_from(RialtoToMillauConversionRate::get().saturating_mul_int(bridged_balance)) diff --git a/bridges/bin/rialto/node/src/chain_spec.rs b/bridges/bin/rialto/node/src/chain_spec.rs index 99645e14cb..60b1af24e3 100644 --- a/bridges/bin/rialto/node/src/chain_spec.rs +++ b/bridges/bin/rialto/node/src/chain_spec.rs @@ -137,7 +137,7 @@ impl Alternative { get_account_id_from_seed::("Harry//stash"), pallet_bridge_messages::Pallet::< rialto_runtime::Runtime, - pallet_bridge_messages::DefaultInstance, + rialto_runtime::WithMillauMessagesInstance, >::relayer_fund_account_id(), derive_account_from_millau_id(bp_runtime::SourceAccount::Account( get_account_id_from_seed::("Alice"), diff --git a/bridges/bin/rialto/runtime/src/lib.rs b/bridges/bin/rialto/runtime/src/lib.rs index 1a34061592..75ba22389a 100644 --- a/bridges/bin/rialto/runtime/src/lib.rs +++ b/bridges/bin/rialto/runtime/src/lib.rs @@ -494,7 +494,7 @@ parameter_types! { } /// Instance of the messages pallet used to relay messages to/from Millau chain. -pub type WithMillauMessagesInstance = pallet_bridge_messages::DefaultInstance; +pub type WithMillauMessagesInstance = (); impl pallet_bridge_messages::Config for Runtime { type Event = Event; @@ -1021,14 +1021,12 @@ impl_runtime_apis! { Self::endow_account(&rialto_public.clone().into_account()); } - let make_millau_message_key = |message_key: MessageKey| storage_keys::message_key::< - ::BridgedMessagesInstance, - >( + let make_millau_message_key = |message_key: MessageKey| storage_keys::message_key( + ::BRIDGED_MESSAGES_PALLET_NAME, &message_key.lane_id, message_key.nonce, ).0; - let make_millau_outbound_lane_data_key = |lane_id| storage_keys::outbound_lane_data_key::< - ::BridgedMessagesInstance, - >( + let make_millau_outbound_lane_data_key = |lane_id| storage_keys::outbound_lane_data_key( + ::BRIDGED_MESSAGES_PALLET_NAME, &lane_id, ).0; @@ -1074,9 +1072,8 @@ impl_runtime_apis! { prepare_message_delivery_proof::( params, - |lane_id| pallet_bridge_messages::storage_keys::inbound_lane_data_key::< - ::BridgedMessagesInstance, - >( + |lane_id| pallet_bridge_messages::storage_keys::inbound_lane_data_key( + ::BRIDGED_MESSAGES_PALLET_NAME, &lane_id, ).0, |state_root| bp_millau::Header::new( diff --git a/bridges/bin/rialto/runtime/src/millau_messages.rs b/bridges/bin/rialto/runtime/src/millau_messages.rs index ac79d8eca6..bb24a95f9c 100644 --- a/bridges/bin/rialto/runtime/src/millau_messages.rs +++ b/bridges/bin/rialto/runtime/src/millau_messages.rs @@ -80,10 +80,10 @@ impl MessageBridge for WithMillauMessageBridge { const RELAYER_FEE_PERCENT: u32 = 10; const THIS_CHAIN_ID: ChainId = RIALTO_CHAIN_ID; const BRIDGED_CHAIN_ID: ChainId = MILLAU_CHAIN_ID; + const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_millau::WITH_RIALTO_MESSAGES_PALLET_NAME; type ThisChain = Rialto; type BridgedChain = Millau; - type BridgedMessagesInstance = crate::WithMillauMessagesInstance; fn bridged_balance_to_this_balance(bridged_balance: bp_millau::Balance) -> bp_rialto::Balance { bp_rialto::Balance::try_from(MillauToRialtoConversionRate::get().saturating_mul_int(bridged_balance)) diff --git a/bridges/bin/runtime-common/src/messages.rs b/bridges/bin/runtime-common/src/messages.rs index 974920c528..a7591b2e57 100644 --- a/bridges/bin/runtime-common/src/messages.rs +++ b/bridges/bin/runtime-common/src/messages.rs @@ -32,7 +32,7 @@ use bp_runtime::{ }; use codec::{Decode, Encode}; use frame_support::{ - traits::{Currency, ExistenceRequirement, Instance}, + traits::{Currency, ExistenceRequirement}, weights::{Weight, WeightToFeePolynomial}, RuntimeDebug, }; @@ -53,13 +53,15 @@ pub trait MessageBridge { const THIS_CHAIN_ID: ChainId; /// Identifier of the Bridged chain. const BRIDGED_CHAIN_ID: ChainId; + /// Name of the paired messages pallet instance at the Bridged chain. + /// + /// Should be the name that is used in the `construct_runtime!()` macro. + const BRIDGED_MESSAGES_PALLET_NAME: &'static str; /// This chain in context of message bridge. type ThisChain: ThisChainWithMessages; /// Bridged chain in context of message bridge. type BridgedChain: BridgedChainWithMessages; - /// Instance of the `pallet-bridge-messages` pallet at the Bridged chain. - type BridgedMessagesInstance: Instance; /// Convert Bridged chain balance into This chain balance. fn bridged_balance_to_this_balance(bridged_balance: BalanceOf>) -> BalanceOf>; @@ -391,7 +393,7 @@ pub mod source { // Messages delivery proof is just proof of single storage key read => any error // is fatal. let storage_inbound_lane_data_key = - pallet_bridge_messages::storage_keys::inbound_lane_data_key::(&lane); + pallet_bridge_messages::storage_keys::inbound_lane_data_key(B::BRIDGED_MESSAGES_PALLET_NAME, &lane); let raw_inbound_lane_data = storage .read_value(storage_inbound_lane_data_key.0.as_ref()) .map_err(|_| "Failed to read inbound lane state from storage proof")? @@ -563,7 +565,6 @@ pub mod target { ) -> Result>>>, &'static str> where ThisRuntime: pallet_bridge_grandpa::Config, - ThisRuntime: pallet_bridge_messages::Config, HashOf>: Into>::BridgedChain>>, { @@ -628,14 +629,15 @@ pub mod target { { fn read_raw_outbound_lane_data(&self, lane_id: &LaneId) -> Option> { let storage_outbound_lane_data_key = - pallet_bridge_messages::storage_keys::outbound_lane_data_key::(lane_id); + pallet_bridge_messages::storage_keys::outbound_lane_data_key(B::BRIDGED_MESSAGES_PALLET_NAME, lane_id); self.storage .read_value(storage_outbound_lane_data_key.0.as_ref()) .ok()? } fn read_raw_message(&self, message_key: &MessageKey) -> Option> { - let storage_message_key = pallet_bridge_messages::storage_keys::message_key::( + let storage_message_key = pallet_bridge_messages::storage_keys::message_key( + B::BRIDGED_MESSAGES_PALLET_NAME, &message_key.lane_id, message_key.nonce, ); @@ -745,10 +747,10 @@ mod tests { const RELAYER_FEE_PERCENT: u32 = 10; const THIS_CHAIN_ID: ChainId = *b"this"; const BRIDGED_CHAIN_ID: ChainId = *b"brdg"; + const BRIDGED_MESSAGES_PALLET_NAME: &'static str = ""; type ThisChain = ThisChain; type BridgedChain = BridgedChain; - type BridgedMessagesInstance = pallet_bridge_messages::DefaultInstance; fn bridged_balance_to_this_balance(bridged_balance: BridgedChainBalance) -> ThisChainBalance { ThisChainBalance(bridged_balance.0 * BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE as u32) @@ -763,10 +765,10 @@ mod tests { const RELAYER_FEE_PERCENT: u32 = 20; const THIS_CHAIN_ID: ChainId = *b"brdg"; const BRIDGED_CHAIN_ID: ChainId = *b"this"; + const BRIDGED_MESSAGES_PALLET_NAME: &'static str = ""; type ThisChain = BridgedChain; type BridgedChain = ThisChain; - type BridgedMessagesInstance = pallet_bridge_messages::DefaultInstance; fn bridged_balance_to_this_balance(_this_balance: ThisChainBalance) -> BridgedChainBalance { unreachable!() diff --git a/bridges/bin/runtime-common/src/messages_api.rs b/bridges/bin/runtime-common/src/messages_api.rs index d0f4180b5c..b09a88e627 100644 --- a/bridges/bin/runtime-common/src/messages_api.rs +++ b/bridges/bin/runtime-common/src/messages_api.rs @@ -20,7 +20,6 @@ use crate::messages::{source::FromThisChainMessagePayload, MessageBridge}; use bp_messages::{LaneId, MessageDetails, MessageNonce}; use codec::Decode; -use frame_support::traits::Instance; use sp_std::vec::Vec; /// Implementation of the `To*OutboundLaneApi::message_details`. @@ -31,7 +30,7 @@ pub fn outbound_message_details( ) -> Vec> where Runtime: pallet_bridge_messages::Config, - MessagesPalletInstance: Instance, + MessagesPalletInstance: 'static, BridgeConfig: MessageBridge, { (begin..=end) diff --git a/bridges/modules/messages/src/benchmarking.rs b/bridges/modules/messages/src/benchmarking.rs index e2a3237eb0..4adf073191 100644 --- a/bridges/modules/messages/src/benchmarking.rs +++ b/bridges/modules/messages/src/benchmarking.rs @@ -19,7 +19,7 @@ use crate::weights_ext::EXPECTED_DEFAULT_MESSAGE_LENGTH; use crate::{ inbound_lane::InboundLaneStorage, inbound_lane_storage, outbound_lane, outbound_lane::ReceivalConfirmationResult, - Call, Instance, + Call, }; use bp_messages::{ @@ -27,7 +27,7 @@ use bp_messages::{ MessageData, MessageNonce, OutboundLaneData, UnrewardedRelayer, UnrewardedRelayersState, }; use bp_runtime::messages::DispatchFeePayment; -use frame_benchmarking::{account, benchmarks_instance}; +use frame_benchmarking::{account, benchmarks_instance_pallet}; use frame_support::{traits::Get, weights::Weight}; use frame_system::RawOrigin; use sp_std::{ @@ -43,7 +43,7 @@ pub const MESSAGE_FEE: u64 = 100_000_000_000; const SEED: u32 = 0; /// Pallet we're benchmarking here. -pub struct Pallet, I: crate::Instance>(crate::Pallet); +pub struct Pallet, I: 'static>(crate::Pallet); /// Proof size requirements. pub enum ProofSize { @@ -91,7 +91,7 @@ pub struct MessageDeliveryProofParams { } /// Trait that must be implemented by runtime. -pub trait Config: crate::Config { +pub trait Config: crate::Config { /// Lane id to use in benchmarks. fn bench_lane_id() -> LaneId { Default::default() @@ -123,7 +123,7 @@ pub trait Config: crate::Config { fn is_message_dispatched(nonce: MessageNonce) -> bool; } -benchmarks_instance! { +benchmarks_instance_pallet! { // // Benchmarks that are used directly by the runtime. // @@ -898,7 +898,7 @@ benchmarks_instance! { } } -fn send_regular_message, I: Instance>() { +fn send_regular_message, I: 'static>() { let mut outbound_lane = outbound_lane::(T::bench_lane_id()); outbound_lane.send_message(MessageData { payload: vec![], @@ -906,7 +906,7 @@ fn send_regular_message, I: Instance>() { }); } -fn send_regular_message_with_payload, I: Instance>(payload: Vec) { +fn send_regular_message_with_payload, I: 'static>(payload: Vec) { let mut outbound_lane = outbound_lane::(T::bench_lane_id()); outbound_lane.send_message(MessageData { payload, @@ -914,7 +914,7 @@ fn send_regular_message_with_payload, I: Instance>(payload: Vec }); } -fn confirm_message_delivery, I: Instance>(nonce: MessageNonce) { +fn confirm_message_delivery, I: 'static>(nonce: MessageNonce) { let mut outbound_lane = outbound_lane::(T::bench_lane_id()); let latest_received_nonce = outbound_lane.data().latest_received_nonce; let mut relayers = VecDeque::with_capacity((nonce - latest_received_nonce) as usize); @@ -930,7 +930,7 @@ fn confirm_message_delivery, I: Instance>(nonce: MessageNonce) { )); } -fn receive_messages, I: Instance>(nonce: MessageNonce) { +fn receive_messages, I: 'static>(nonce: MessageNonce) { let mut inbound_lane_storage = inbound_lane_storage::(T::bench_lane_id()); inbound_lane_storage.set_data(InboundLaneData { relayers: vec![UnrewardedRelayer { @@ -943,7 +943,7 @@ fn receive_messages, I: Instance>(nonce: MessageNonce) { }); } -fn ensure_relayer_rewarded, I: Instance>(relayer_id: &T::AccountId, old_balance: &T::OutboundMessageFee) { +fn ensure_relayer_rewarded, I: 'static>(relayer_id: &T::AccountId, old_balance: &T::OutboundMessageFee) { let new_balance = T::account_balance(relayer_id); assert!( new_balance > *old_balance, diff --git a/bridges/modules/messages/src/inbound_lane.rs b/bridges/modules/messages/src/inbound_lane.rs index 83d17dc3c0..ae5de1c152 100644 --- a/bridges/modules/messages/src/inbound_lane.rs +++ b/bridges/modules/messages/src/inbound_lane.rs @@ -179,11 +179,11 @@ mod tests { dispatch_result, message_data, run_test, unrewarded_relayer, TestMessageDispatch, TestRuntime, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_RELAYER_A, TEST_RELAYER_B, TEST_RELAYER_C, }, - DefaultInstance, RuntimeInboundLaneStorage, + RuntimeInboundLaneStorage, }; fn receive_regular_message( - lane: &mut InboundLane>, + lane: &mut InboundLane>, nonce: MessageNonce, ) { assert_eq!( diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index 8f7a6c8b71..7c6bacfb66 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -56,15 +56,8 @@ use bp_messages::{ }; use bp_runtime::{ChainId, Size}; use codec::{Decode, Encode}; -use frame_support::{ - decl_error, decl_event, decl_module, decl_storage, - dispatch::DispatchResultWithPostInfo, - ensure, fail, - traits::Get, - weights::{DispatchClass, Pays, PostDispatchInfo, Weight}, - Parameter, StorageMap, -}; -use frame_system::{ensure_signed, RawOrigin}; +use frame_support::{fail, traits::Get, weights::PostDispatchInfo}; +use frame_system::RawOrigin; use num_traits::{SaturatingAdd, Zero}; use sp_runtime::traits::BadOrigin; use sp_std::{cell::RefCell, cmp::PartialOrd, marker::PhantomData, prelude::*}; @@ -82,223 +75,158 @@ pub mod benchmarking; #[cfg(test)] mod mock; -/// The module configuration trait -pub trait Config: frame_system::Config { - // General types +pub use pallet::*; - /// They are overarching event type. - type Event: From> + Into<::Event>; - /// Benchmarks results from runtime we're plugged into. - type WeightInfo: WeightInfoExt; - /// Pallet parameter that is opaque to the pallet itself, but may be used by the runtime - /// for integrating the pallet. - /// - /// All pallet parameters may only be updated either by the root, or by the pallet owner. - type Parameter: MessagesParameter; +#[frame_support::pallet] +pub mod pallet { + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; - /// Maximal number of messages that may be pruned during maintenance. Maintenance occurs - /// whenever new message is sent. The reason is that if you want to use lane, you should - /// be ready to pay for its maintenance. - type MaxMessagesToPruneAtOnce: Get; - /// Maximal number of unrewarded relayer entries at inbound lane. Unrewarded means that the - /// relayer has delivered messages, but either confirmations haven't been delivered back to the - /// source chain, or we haven't received reward confirmations yet. - /// - /// This constant limits maximal number of entries in the `InboundLaneData::relayers`. Keep - /// in mind that the same relayer account may take several (non-consecutive) entries in this - /// set. - type MaxUnrewardedRelayerEntriesAtInboundLane: Get; - /// Maximal number of unconfirmed messages at inbound lane. Unconfirmed means that the - /// message has been delivered, but either confirmations haven't been delivered back to the - /// source chain, or we haven't received reward confirmations for these messages yet. - /// - /// This constant limits difference between last message from last entry of the - /// `InboundLaneData::relayers` and first message at the first entry. - /// - /// There is no point of making this parameter lesser than MaxUnrewardedRelayerEntriesAtInboundLane, - /// because then maximal number of relayer entries will be limited by maximal number of messages. - /// - /// This value also represents maximal number of messages in single delivery transaction. Transaction - /// that is declaring more messages than this value, will be rejected. Even if these messages are - /// from different lanes. - type MaxUnconfirmedMessagesAtInboundLane: Get; + #[pallet::config] + pub trait Config: frame_system::Config { + // General types - /// Payload type of outbound messages. This payload is dispatched on the bridged chain. - type OutboundPayload: Parameter + Size; - /// Message fee type of outbound messages. This fee is paid on this chain. - type OutboundMessageFee: Default + From + PartialOrd + Parameter + SaturatingAdd + Zero; - - /// Payload type of inbound messages. This payload is dispatched on this chain. - type InboundPayload: Decode; - /// Message fee type of inbound messages. This fee is paid on the bridged chain. - type InboundMessageFee: Decode; - /// Identifier of relayer that deliver messages to this chain. Relayer reward is paid on the bridged chain. - type InboundRelayer: Parameter; - - /// A type which can be turned into an AccountId from a 256-bit hash. - /// - /// Used when deriving the shared relayer fund account. - type AccountIdConverter: sp_runtime::traits::Convert; - - // Types that are used by outbound_lane (on source chain). - - /// Target header chain. - type TargetHeaderChain: TargetHeaderChain; - /// Message payload verifier. - type LaneMessageVerifier: LaneMessageVerifier; - /// Message delivery payment. - type MessageDeliveryAndDispatchPayment: MessageDeliveryAndDispatchPayment; - /// Handler for delivered messages. - type OnDeliveryConfirmed: OnDeliveryConfirmed; - - // Types that are used by inbound_lane (on target chain). - - /// Source header chain, as it is represented on target chain. - type SourceHeaderChain: SourceHeaderChain; - /// Message dispatch. - type MessageDispatch: MessageDispatch< - Self::AccountId, - Self::InboundMessageFee, - DispatchPayload = Self::InboundPayload, - >; - - /// Chain Id for the bridged chain. - type BridgedChainId: Get; -} - -/// Shortcut to messages proof type for Config. -type MessagesProofOf = - <>::SourceHeaderChain as SourceHeaderChain<>::InboundMessageFee>>::MessagesProof; -/// Shortcut to messages delivery proof type for Config. -type MessagesDeliveryProofOf = <>::TargetHeaderChain as TargetHeaderChain< - >::OutboundPayload, - ::AccountId, ->>::MessagesDeliveryProof; - -decl_error! { - pub enum Error for Pallet, I: Instance> { - /// All pallet operations are halted. - Halted, - /// Message has been treated as invalid by chain verifier. - MessageRejectedByChainVerifier, - /// Message has been treated as invalid by lane verifier. - MessageRejectedByLaneVerifier, - /// Submitter has failed to pay fee for delivering and dispatching messages. - FailedToWithdrawMessageFee, - /// The transaction brings too many messages. - TooManyMessagesInTheProof, - /// Invalid messages has been submitted. - InvalidMessagesProof, - /// Invalid messages delivery proof has been submitted. - InvalidMessagesDeliveryProof, - /// The bridged chain has invalid `UnrewardedRelayers` in its storage (fatal for the lane). - InvalidUnrewardedRelayers, - /// The relayer has declared invalid unrewarded relayers state in the `receive_messages_delivery_proof` call. - InvalidUnrewardedRelayersState, - /// The message someone is trying to work with (i.e. increase fee) is already-delivered. - MessageIsAlreadyDelivered, - /// The message someone is trying to work with (i.e. increase fee) is not yet sent. - MessageIsNotYetSent, - /// The number of actually confirmed messages is going to be larger than the number of messages in the proof. - /// This may mean that this or bridged chain storage is corrupted. - TryingToConfirmMoreMessagesThanExpected, - } -} - -decl_storage! { - trait Store for Pallet, I: Instance = DefaultInstance> as BridgeMessages { - /// Optional pallet owner. - /// - /// Pallet owner has a right to halt all pallet operations and then resume it. If it is - /// `None`, then there are no direct ways to halt/resume pallet operations, but other - /// runtime methods may still be used to do that (i.e. democracy::referendum to update halt - /// flag directly or call the `halt_operations`). - pub PalletOwner get(fn module_owner): Option; - /// The current operating mode of the pallet. - /// - /// Depending on the mode either all, some, or no transactions will be allowed. - pub PalletOperatingMode get(fn operating_mode) config(): OperatingMode; - /// Map of lane id => inbound lane data. - pub InboundLanes: map hasher(blake2_128_concat) LaneId => InboundLaneData; - /// Map of lane id => outbound lane data. - pub OutboundLanes: map hasher(blake2_128_concat) LaneId => OutboundLaneData; - /// All queued outbound messages. - pub OutboundMessages: map hasher(blake2_128_concat) MessageKey => Option>; - } - add_extra_genesis { - config(phantom): sp_std::marker::PhantomData; - config(owner): Option; - build(|config| { - if let Some(ref owner) = config.owner { - >::put(owner); - } - }) - } -} - -decl_event!( - pub enum Event - where - AccountId = ::AccountId, - Parameter = >::Parameter, - { - /// Pallet parameter has been updated. - ParameterUpdated(Parameter), - /// Message has been accepted and is waiting to be delivered. - MessageAccepted(LaneId, MessageNonce), - /// Messages in the inclusive range have been delivered to the bridged chain. - MessagesDelivered(LaneId, DeliveredMessages), - /// Phantom member, never used. - Dummy(PhantomData<(AccountId, I)>), - } -); - -decl_module! { - pub struct Module, 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; + /// The overarching event type. + type Event: From> + IsType<::Event>; + /// Benchmarks results from runtime we're plugged into. + type WeightInfo: WeightInfoExt; /// Gets the chain id value from the instance. - const BridgedChainId: ChainId = T::BridgedChainId::get(); + #[pallet::constant] + type BridgedChainId: Get; + /// Pallet parameter that is opaque to the pallet itself, but may be used by the runtime + /// for integrating the pallet. + /// + /// All pallet parameters may only be updated either by the root, or by the pallet owner. + type Parameter: MessagesParameter; + /// Maximal number of messages that may be pruned during maintenance. Maintenance occurs + /// whenever new message is sent. The reason is that if you want to use lane, you should + /// be ready to pay for its maintenance. + type MaxMessagesToPruneAtOnce: Get; + /// Maximal number of unrewarded relayer entries at inbound lane. Unrewarded means that the + /// relayer has delivered messages, but either confirmations haven't been delivered back to the + /// source chain, or we haven't received reward confirmations yet. + /// + /// This constant limits maximal number of entries in the `InboundLaneData::relayers`. Keep + /// in mind that the same relayer account may take several (non-consecutive) entries in this + /// set. + type MaxUnrewardedRelayerEntriesAtInboundLane: Get; + /// Maximal number of unconfirmed messages at inbound lane. Unconfirmed means that the + /// message has been delivered, but either confirmations haven't been delivered back to the + /// source chain, or we haven't received reward confirmations for these messages yet. + /// + /// This constant limits difference between last message from last entry of the + /// `InboundLaneData::relayers` and first message at the first entry. + /// + /// There is no point of making this parameter lesser than MaxUnrewardedRelayerEntriesAtInboundLane, + /// because then maximal number of relayer entries will be limited by maximal number of messages. + /// + /// This value also represents maximal number of messages in single delivery transaction. Transaction + /// that is declaring more messages than this value, will be rejected. Even if these messages are + /// from different lanes. + type MaxUnconfirmedMessagesAtInboundLane: Get; + + /// Payload type of outbound messages. This payload is dispatched on the bridged chain. + type OutboundPayload: Parameter + Size; + /// Message fee type of outbound messages. This fee is paid on this chain. + type OutboundMessageFee: Default + From + PartialOrd + Parameter + SaturatingAdd + Zero; + + /// Payload type of inbound messages. This payload is dispatched on this chain. + type InboundPayload: Decode; + /// Message fee type of inbound messages. This fee is paid on the bridged chain. + type InboundMessageFee: Decode; + /// Identifier of relayer that deliver messages to this chain. Relayer reward is paid on the bridged chain. + type InboundRelayer: Parameter; + + /// A type which can be turned into an AccountId from a 256-bit hash. + /// + /// Used when deriving the shared relayer fund account. + type AccountIdConverter: sp_runtime::traits::Convert; + + // Types that are used by outbound_lane (on source chain). + + /// Target header chain. + type TargetHeaderChain: TargetHeaderChain; + /// Message payload verifier. + type LaneMessageVerifier: LaneMessageVerifier; + /// Message delivery payment. + type MessageDeliveryAndDispatchPayment: MessageDeliveryAndDispatchPayment< + Self::AccountId, + Self::OutboundMessageFee, + >; + /// Handler for delivered messages. + type OnDeliveryConfirmed: OnDeliveryConfirmed; + + // Types that are used by inbound_lane (on target chain). + + /// Source header chain, as it is represented on target chain. + type SourceHeaderChain: SourceHeaderChain; + /// Message dispatch. + type MessageDispatch: MessageDispatch< + Self::AccountId, + Self::InboundMessageFee, + DispatchPayload = Self::InboundPayload, + >; + } + + /// Shortcut to messages proof type for Config. + type MessagesProofOf = + <>::SourceHeaderChain as SourceHeaderChain<>::InboundMessageFee>>::MessagesProof; + /// Shortcut to messages delivery proof type for Config. + type MessagesDeliveryProofOf = <>::TargetHeaderChain as TargetHeaderChain< + >::OutboundPayload, + ::AccountId, + >>::MessagesDeliveryProof; + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet { /// Ensure runtime invariants. fn on_runtime_upgrade() -> Weight { - let reads = T::MessageDeliveryAndDispatchPayment::initialize( - &Self::relayer_fund_account_id() - ); + let reads = T::MessageDeliveryAndDispatchPayment::initialize(&Self::relayer_fund_account_id()); T::DbWeight::get().reads(reads as u64) } + } + #[pallet::call] + impl, I: 'static> Pallet { /// Change `PalletOwner`. /// /// May only be called either by root, or by `PalletOwner`. - #[weight = (T::DbWeight::get().reads_writes(1, 1), DispatchClass::Operational)] - pub fn set_owner(origin, new_owner: Option) { + #[pallet::weight((T::DbWeight::get().reads_writes(1, 1), DispatchClass::Operational))] + pub fn set_owner(origin: OriginFor, new_owner: Option) -> DispatchResult { ensure_owner_or_root::(origin)?; match new_owner { Some(new_owner) => { PalletOwner::::put(&new_owner); log::info!(target: "runtime::bridge-messages", "Setting pallet Owner to: {:?}", new_owner); - }, + } None => { PalletOwner::::kill(); log::info!(target: "runtime::bridge-messages", "Removed Owner of pallet."); - }, + } } + Ok(()) } /// Halt or resume all/some pallet operations. /// /// May only be called either by root, or by `PalletOwner`. - #[weight = (T::DbWeight::get().reads_writes(1, 1), DispatchClass::Operational)] - pub fn set_operating_mode(origin, operating_mode: OperatingMode) { + #[pallet::weight((T::DbWeight::get().reads_writes(1, 1), DispatchClass::Operational))] + pub fn set_operating_mode(origin: OriginFor, operating_mode: OperatingMode) -> DispatchResult { ensure_owner_or_root::(origin)?; - >::put(operating_mode); + PalletOperatingMode::::put(operating_mode); log::info!( target: "runtime::bridge-messages", "Setting messages pallet operating mode to {:?}.", operating_mode, ); + Ok(()) } /// Update pallet parameter. @@ -306,17 +234,18 @@ decl_module! { /// May only be called either by root, or by `PalletOwner`. /// /// The weight is: single read for permissions check + 2 writes for parameter value and event. - #[weight = (T::DbWeight::get().reads_writes(1, 2), DispatchClass::Operational)] - pub fn update_pallet_parameter(origin, parameter: T::Parameter) { + #[pallet::weight((T::DbWeight::get().reads_writes(1, 2), DispatchClass::Operational))] + pub fn update_pallet_parameter(origin: OriginFor, parameter: T::Parameter) -> DispatchResult { ensure_owner_or_root::(origin)?; parameter.save(); - Self::deposit_event(RawEvent::ParameterUpdated(parameter)); + Self::deposit_event(Event::ParameterUpdated(parameter)); + Ok(()) } /// Send message over lane. - #[weight = T::WeightInfo::send_message_weight(payload)] + #[pallet::weight(T::WeightInfo::send_message_weight(payload))] pub fn send_message( - origin, + origin: OriginFor, lane_id: LaneId, payload: T::OutboundPayload, delivery_and_dispatch_fee: T::OutboundMessageFee, @@ -328,17 +257,16 @@ decl_module! { let mut actual_weight = T::WeightInfo::send_message_weight(&payload); // let's first check if message can be delivered to target chain - T::TargetHeaderChain::verify_message(&payload) - .map_err(|err| { - log::trace!( - target: "runtime::bridge-messages", - "Message to lane {:?} is rejected by target chain: {:?}", - lane_id, - err, - ); + T::TargetHeaderChain::verify_message(&payload).map_err(|err| { + log::trace!( + target: "runtime::bridge-messages", + "Message to lane {:?} is rejected by target chain: {:?}", + lane_id, + err, + ); - Error::::MessageRejectedByChainVerifier - })?; + Error::::MessageRejectedByChainVerifier + })?; // now let's enforce any additional lane rules let mut lane = outbound_lane::(lane_id); @@ -348,7 +276,8 @@ decl_module! { &lane_id, &lane.data(), &payload, - ).map_err(|err| { + ) + .map_err(|err| { log::trace!( target: "runtime::bridge-messages", "Message to lane {:?} is rejected by lane verifier: {:?}", @@ -364,7 +293,8 @@ decl_module! { &submitter, &delivery_and_dispatch_fee, &Self::relayer_fund_account_id(), - ).map_err(|err| { + ) + .map_err(|err| { log::trace!( target: "runtime::bridge-messages", "Message to lane {:?} is rejected because submitter {:?} is unable to pay fee {:?}: {:?}", @@ -402,7 +332,7 @@ decl_module! { encoded_payload_len, ); - Self::deposit_event(RawEvent::MessageAccepted(lane_id, nonce)); + Self::deposit_event(Event::MessageAccepted(lane_id, nonce)); Ok(PostDispatchInfo { actual_weight: Some(actual_weight), @@ -411,9 +341,9 @@ decl_module! { } /// Pay additional fee for the message. - #[weight = T::WeightInfo::maximal_increase_message_fee()] + #[pallet::weight(T::WeightInfo::maximal_increase_message_fee())] pub fn increase_message_fee( - origin, + origin: OriginFor, lane_id: LaneId, nonce: MessageNonce, additional_fee: T::OutboundMessageFee, @@ -425,8 +355,14 @@ decl_module! { // if someone tries to pay for not-yet-sent message, we're rejeting this intention, or // we're risking to have mess in the storage let lane = outbound_lane::(lane_id); - ensure!(nonce > lane.data().latest_received_nonce, Error::::MessageIsAlreadyDelivered); - ensure!(nonce <= lane.data().latest_generated_nonce, Error::::MessageIsNotYetSent); + ensure!( + nonce > lane.data().latest_received_nonce, + Error::::MessageIsAlreadyDelivered + ); + ensure!( + nonce <= lane.data().latest_generated_nonce, + Error::::MessageIsNotYetSent + ); // withdraw additional fee from submitter let submitter = origin.into().map_err(|_| BadOrigin)?; @@ -434,7 +370,8 @@ decl_module! { &submitter, &additional_fee, &Self::relayer_fund_account_id(), - ).map_err(|err| { + ) + .map_err(|err| { log::trace!( target: "runtime::bridge-messages", "Submitter {:?} can't pay additional fee {:?} for the message {:?}/{:?}: {:?}", @@ -478,9 +415,9 @@ decl_module! { /// The weight of the call assumes that the transaction always brings outbound lane /// state update. Because of that, the submitter (relayer) has no benefit of not including /// this data in the transaction, so reward confirmations lags should be minimal. - #[weight = T::WeightInfo::receive_messages_proof_weight(proof, *messages_count, *dispatch_weight)] + #[pallet::weight(T::WeightInfo::receive_messages_proof_weight(proof, *messages_count, *dispatch_weight))] pub fn receive_messages_proof( - origin, + origin: OriginFor, relayer_id_at_bridged_chain: T::InboundRelayer, proof: MessagesProofOf, messages_count: u32, @@ -505,11 +442,7 @@ decl_module! { // // The DeclaredWeight is exactly what's computed here. Unfortunately it is impossible // to get pre-computed value (and it has been already computed by the executive). - let declared_weight = T::WeightInfo::receive_messages_proof_weight( - &proof, - messages_count, - dispatch_weight, - ); + let declared_weight = T::WeightInfo::receive_messages_proof_weight(&proof, messages_count, dispatch_weight); let mut actual_weight = declared_weight; // verify messages proof && convert proof into messages @@ -518,15 +451,15 @@ decl_module! { T::InboundMessageFee, T::InboundPayload, >(proof, messages_count) - .map_err(|err| { - log::trace!( - target: "runtime::bridge-messages", - "Rejecting invalid messages proof: {:?}", - err, - ); + .map_err(|err| { + log::trace!( + target: "runtime::bridge-messages", + "Rejecting invalid messages proof: {:?}", + err, + ); - Error::::InvalidMessagesProof - })?; + Error::::InvalidMessagesProof + })?; // dispatch messages and (optionally) update lane(s) state(s) let mut total_messages = 0; @@ -582,27 +515,28 @@ decl_module! { let (unspent_weight, refund_pay_dispatch_fee) = match receival_result { ReceivalResult::Dispatched(dispatch_result) => { valid_messages += 1; - (dispatch_result.unspent_weight, !dispatch_result.dispatch_fee_paid_during_dispatch) - }, + ( + dispatch_result.unspent_weight, + !dispatch_result.dispatch_fee_paid_during_dispatch, + ) + } ReceivalResult::InvalidNonce - | ReceivalResult::TooManyUnrewardedRelayers - | ReceivalResult::TooManyUnconfirmedMessages => (dispatch_weight, true), + | ReceivalResult::TooManyUnrewardedRelayers + | ReceivalResult::TooManyUnconfirmedMessages => (dispatch_weight, true), }; let unspent_weight = sp_std::cmp::min(unspent_weight, dispatch_weight); dispatch_weight_left -= dispatch_weight - unspent_weight; - actual_weight = actual_weight - .saturating_sub(unspent_weight) - .saturating_sub( - // delivery call weight formula assumes that the fee is paid at - // this (target) chain. If the message is prepaid at the source - // chain, let's refund relayer with this extra cost. - if refund_pay_dispatch_fee { - T::WeightInfo::pay_inbound_dispatch_fee_overhead() - } else { - 0 - } - ); + actual_weight = actual_weight.saturating_sub(unspent_weight).saturating_sub( + // delivery call weight formula assumes that the fee is paid at + // this (target) chain. If the message is prepaid at the source + // chain, let's refund relayer with this extra cost. + if refund_pay_dispatch_fee { + T::WeightInfo::pay_inbound_dispatch_fee_overhead() + } else { + 0 + }, + ); } } @@ -622,13 +556,13 @@ decl_module! { } /// Receive messages delivery proof from bridged chain. - #[weight = T::WeightInfo::receive_messages_delivery_proof_weight( + #[pallet::weight(T::WeightInfo::receive_messages_delivery_proof_weight( proof, relayers_state, T::DbWeight::get(), - )] + ))] pub fn receive_messages_delivery_proof( - origin, + origin: OriginFor, proof: MessagesDeliveryProofOf, relayers_state: UnrewardedRelayersState, ) -> DispatchResultWithPostInfo { @@ -644,11 +578,8 @@ decl_module! { // The DeclaredWeight is exactly what's computed here. Unfortunately it is impossible // to get pre-computed value (and it has been already computed by the executive). let single_message_callback_overhead = T::WeightInfo::single_message_callback_overhead(T::DbWeight::get()); - let declared_weight = T::WeightInfo::receive_messages_delivery_proof_weight( - &proof, - &relayers_state, - T::DbWeight::get(), - ); + let declared_weight = + T::WeightInfo::receive_messages_delivery_proof_weight(&proof, &relayers_state, T::DbWeight::get()); let mut actual_weight = declared_weight; let confirmation_relayer = ensure_signed(origin)?; @@ -665,8 +596,8 @@ decl_module! { // verify that the relayer has declared correct `lane_data::relayers` state // (we only care about total number of entries and messages, because this affects call weight) ensure!( - total_unrewarded_messages(&lane_data.relayers) - .unwrap_or(MessageNonce::MAX) == relayers_state.total_messages + total_unrewarded_messages(&lane_data.relayers).unwrap_or(MessageNonce::MAX) + == relayers_state.total_messages && lane_data.relayers.len() as MessageNonce == relayers_state.unrewarded_relayer_entries, Error::::InvalidUnrewardedRelayersState ); @@ -675,43 +606,38 @@ decl_module! { let mut lane = outbound_lane::(lane_id); let mut relayers_rewards: RelayersRewards<_, T::OutboundMessageFee> = RelayersRewards::new(); let last_delivered_nonce = lane_data.last_delivered_nonce(); - let confirmed_messages = match lane.confirm_delivery( - relayers_state.total_messages, - last_delivered_nonce, - &lane_data.relayers, - ) { - ReceivalConfirmationResult::ConfirmedMessages(confirmed_messages) => Some(confirmed_messages), - ReceivalConfirmationResult::NoNewConfirmations => None, - ReceivalConfirmationResult::TryingToConfirmMoreMessagesThanExpected(to_confirm_messages_count) => { - log::trace!( - target: "runtime::bridge-messages", - "Messages delivery proof contains too many messages to confirm: {} vs declared {}", - to_confirm_messages_count, - relayers_state.total_messages, - ); + let confirmed_messages = + match lane.confirm_delivery(relayers_state.total_messages, last_delivered_nonce, &lane_data.relayers) { + ReceivalConfirmationResult::ConfirmedMessages(confirmed_messages) => Some(confirmed_messages), + ReceivalConfirmationResult::NoNewConfirmations => None, + ReceivalConfirmationResult::TryingToConfirmMoreMessagesThanExpected(to_confirm_messages_count) => { + log::trace!( + target: "runtime::bridge-messages", + "Messages delivery proof contains too many messages to confirm: {} vs declared {}", + to_confirm_messages_count, + relayers_state.total_messages, + ); - fail!(Error::::TryingToConfirmMoreMessagesThanExpected); - }, - error => { - log::trace!( - target: "runtime::bridge-messages", - "Messages delivery proof contains invalid unrewarded relayers vec: {:?}", - error, - ); + fail!(Error::::TryingToConfirmMoreMessagesThanExpected); + } + error => { + log::trace!( + target: "runtime::bridge-messages", + "Messages delivery proof contains invalid unrewarded relayers vec: {:?}", + error, + ); - fail!(Error::::InvalidUnrewardedRelayers); - }, - }; + fail!(Error::::InvalidUnrewardedRelayers); + } + }; if let Some(confirmed_messages) = confirmed_messages { // handle messages delivery confirmation - let preliminary_callback_overhead = relayers_state.total_messages.saturating_mul( - single_message_callback_overhead - ); - let actual_callback_weight = T::OnDeliveryConfirmed::on_messages_delivered( - &lane_id, - &confirmed_messages, - ); + let preliminary_callback_overhead = relayers_state + .total_messages + .saturating_mul(single_message_callback_overhead); + let actual_callback_weight = + T::OnDeliveryConfirmed::on_messages_delivered(&lane_id, &confirmed_messages); match preliminary_callback_overhead.checked_sub(actual_callback_weight) { Some(difference) if difference == 0 => (), Some(difference) => { @@ -724,7 +650,7 @@ decl_module! { difference, ); actual_weight -= difference; - }, + } None => { debug_assert!(false, "The delivery confirmation callback is wrong"); log::trace!( @@ -739,7 +665,7 @@ decl_module! { // emit 'delivered' event let received_range = confirmed_messages.begin..=confirmed_messages.end; - Self::deposit_event(RawEvent::MessagesDelivered(lane_id, confirmed_messages)); + Self::deposit_event(Event::MessagesDelivered(lane_id, confirmed_messages)); // remember to reward relayers that have delivered messages // this loop is bounded by `T::MaxUnrewardedRelayerEntriesAtInboundLane` on the bridged chain @@ -751,10 +677,8 @@ decl_module! { // this loop is bound by `T::MaxUnconfirmedMessagesAtInboundLane` on the bridged chain let mut relayer_reward = relayers_rewards.entry(entry.relayer).or_default(); for nonce in nonce_begin..nonce_end + 1 { - let message_data = OutboundMessages::::get(MessageKey { - lane_id, - nonce, - }).expect("message was just confirmed; we never prune unconfirmed messages; qed"); + let message_data = OutboundMessages::::get(MessageKey { lane_id, nonce }) + .expect("message was just confirmed; we never prune unconfirmed messages; qed"); relayer_reward.reward = relayer_reward.reward.saturating_add(&message_data.fee); relayer_reward.messages += 1; } @@ -784,102 +708,199 @@ decl_module! { }) } } -} -impl, I: Instance> Pallet { - /// Get stored data of the outbound message with given nonce. - pub fn outbound_message_data(lane: LaneId, nonce: MessageNonce) -> Option> { - OutboundMessages::::get(MessageKey { lane_id: lane, nonce }) + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + #[pallet::metadata(T::Parameter = "Parameter")] + pub enum Event, I: 'static = ()> { + /// Pallet parameter has been updated. + ParameterUpdated(T::Parameter), + /// Message has been accepted and is waiting to be delivered. + MessageAccepted(LaneId, MessageNonce), + /// Messages in the inclusive range have been delivered to the bridged chain. + MessagesDelivered(LaneId, DeliveredMessages), } - /// Get nonce of the latest generated message at given outbound lane. - pub fn outbound_latest_generated_nonce(lane: LaneId) -> MessageNonce { - OutboundLanes::::get(&lane).latest_generated_nonce + #[pallet::error] + pub enum Error { + /// All pallet operations are halted. + Halted, + /// Message has been treated as invalid by chain verifier. + MessageRejectedByChainVerifier, + /// Message has been treated as invalid by lane verifier. + MessageRejectedByLaneVerifier, + /// Submitter has failed to pay fee for delivering and dispatching messages. + FailedToWithdrawMessageFee, + /// The transaction brings too many messages. + TooManyMessagesInTheProof, + /// Invalid messages has been submitted. + InvalidMessagesProof, + /// Invalid messages delivery proof has been submitted. + InvalidMessagesDeliveryProof, + /// The bridged chain has invalid `UnrewardedRelayers` in its storage (fatal for the lane). + InvalidUnrewardedRelayers, + /// The relayer has declared invalid unrewarded relayers state in the `receive_messages_delivery_proof` call. + InvalidUnrewardedRelayersState, + /// The message someone is trying to work with (i.e. increase fee) is already-delivered. + MessageIsAlreadyDelivered, + /// The message someone is trying to work with (i.e. increase fee) is not yet sent. + MessageIsNotYetSent, + /// The number of actually confirmed messages is going to be larger than the number of messages in the proof. + /// This may mean that this or bridged chain storage is corrupted. + TryingToConfirmMoreMessagesThanExpected, } - /// Get nonce of the latest confirmed message at given outbound lane. - pub fn outbound_latest_received_nonce(lane: LaneId) -> MessageNonce { - OutboundLanes::::get(&lane).latest_received_nonce + /// Optional pallet owner. + /// + /// Pallet owner has a right to halt all pallet operations and then resume it. If it is + /// `None`, then there are no direct ways to halt/resume pallet operations, but other + /// runtime methods may still be used to do that (i.e. democracy::referendum to update halt + /// flag directly or call the `halt_operations`). + #[pallet::storage] + #[pallet::getter(fn module_owner)] + pub type PalletOwner, I: 'static = ()> = StorageValue<_, T::AccountId>; + + /// The current operating mode of the pallet. + /// + /// Depending on the mode either all, some, or no transactions will be allowed. + #[pallet::storage] + #[pallet::getter(fn operating_mode)] + pub type PalletOperatingMode, I: 'static = ()> = StorageValue<_, OperatingMode, ValueQuery>; + + /// Map of lane id => inbound lane data. + #[pallet::storage] + pub type InboundLanes, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, LaneId, InboundLaneData, ValueQuery>; + + /// Map of lane id => outbound lane data. + #[pallet::storage] + pub type OutboundLanes, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, LaneId, OutboundLaneData, ValueQuery>; + + /// All queued outbound messages. + #[pallet::storage] + pub type OutboundMessages, I: 'static = ()> = + StorageMap<_, Blake2_128Concat, MessageKey, MessageData>; + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()> { + /// Initial pallet operating mode. + pub operating_mode: OperatingMode, + /// Initial pallet owner. + pub owner: Option, + /// Dummy marker. + pub phantom: sp_std::marker::PhantomData, } - /// Get nonce of the latest received message at given inbound lane. - pub fn inbound_latest_received_nonce(lane: LaneId) -> MessageNonce { - InboundLanes::::get(&lane).last_delivered_nonce() - } - - /// Get nonce of the latest confirmed message at given inbound lane. - pub fn inbound_latest_confirmed_nonce(lane: LaneId) -> MessageNonce { - InboundLanes::::get(&lane).last_confirmed_nonce - } - - /// Get state of unrewarded relayers set. - pub fn inbound_unrewarded_relayers_state(lane: bp_messages::LaneId) -> bp_messages::UnrewardedRelayersState { - let relayers = InboundLanes::::get(&lane).relayers; - bp_messages::UnrewardedRelayersState { - unrewarded_relayer_entries: relayers.len() as _, - messages_in_oldest_entry: relayers - .front() - .map(|entry| 1 + entry.messages.end - entry.messages.begin) - .unwrap_or(0), - total_messages: total_unrewarded_messages(&relayers).unwrap_or(MessageNonce::MAX), + #[cfg(feature = "std")] + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + Self { + operating_mode: Default::default(), + owner: Default::default(), + phantom: Default::default(), + } } } - /// AccountId of the shared relayer fund account. - /// - /// This account is passed to `MessageDeliveryAndDispatchPayment` trait, and depending - /// on the implementation it can be used to store relayers rewards. - /// See [InstantCurrencyPayments] for a concrete implementation. - pub fn relayer_fund_account_id() -> T::AccountId { - use sp_runtime::traits::Convert; - let encoded_id = bp_runtime::derive_relayer_fund_account_id(bp_runtime::NO_INSTANCE_ID); - T::AccountIdConverter::convert(encoded_id) + #[pallet::genesis_build] + impl, I: 'static> GenesisBuild for GenesisConfig { + fn build(&self) { + PalletOperatingMode::::put(&self.operating_mode); + if let Some(ref owner) = self.owner { + PalletOwner::::put(owner); + } + } + } + + impl, I: 'static> Pallet { + /// Get stored data of the outbound message with given nonce. + pub fn outbound_message_data(lane: LaneId, nonce: MessageNonce) -> Option> { + OutboundMessages::::get(MessageKey { lane_id: lane, nonce }) + } + + /// Get nonce of the latest generated message at given outbound lane. + pub fn outbound_latest_generated_nonce(lane: LaneId) -> MessageNonce { + OutboundLanes::::get(&lane).latest_generated_nonce + } + + /// Get nonce of the latest confirmed message at given outbound lane. + pub fn outbound_latest_received_nonce(lane: LaneId) -> MessageNonce { + OutboundLanes::::get(&lane).latest_received_nonce + } + + /// Get nonce of the latest received message at given inbound lane. + pub fn inbound_latest_received_nonce(lane: LaneId) -> MessageNonce { + InboundLanes::::get(&lane).last_delivered_nonce() + } + + /// Get nonce of the latest confirmed message at given inbound lane. + pub fn inbound_latest_confirmed_nonce(lane: LaneId) -> MessageNonce { + InboundLanes::::get(&lane).last_confirmed_nonce + } + + /// Get state of unrewarded relayers set. + pub fn inbound_unrewarded_relayers_state(lane: bp_messages::LaneId) -> bp_messages::UnrewardedRelayersState { + let relayers = InboundLanes::::get(&lane).relayers; + bp_messages::UnrewardedRelayersState { + unrewarded_relayer_entries: relayers.len() as _, + messages_in_oldest_entry: relayers + .front() + .map(|entry| 1 + entry.messages.end - entry.messages.begin) + .unwrap_or(0), + total_messages: total_unrewarded_messages(&relayers).unwrap_or(MessageNonce::MAX), + } + } + + /// AccountId of the shared relayer fund account. + /// + /// This account is passed to `MessageDeliveryAndDispatchPayment` trait, and depending + /// on the implementation it can be used to store relayers rewards. + /// See [InstantCurrencyPayments] for a concrete implementation. + pub fn relayer_fund_account_id() -> T::AccountId { + use sp_runtime::traits::Convert; + let encoded_id = bp_runtime::derive_relayer_fund_account_id(bp_runtime::NO_INSTANCE_ID); + T::AccountIdConverter::convert(encoded_id) + } } } /// Getting storage keys for messages and lanes states. These keys are normally used when building /// messages and lanes states proofs. -/// -/// Keep in mind that all functions in this module are **NOT** using passed `T` argument, so any -/// runtime can be passed. E.g. if you're verifying proof from Runtime1 in Runtime2, you only have -/// access to Runtime2 and you may pass it to the functions, where required. This is because our -/// maps are not using any Runtime-specific data in the keys. -/// -/// On the other side, passing correct instance is required. So if proof has been crafted by the -/// Instance1, you should verify it using Instance1. This is inconvenient if you're using different -/// instances on different sides of the bridge. I.e. in Runtime1 it is Instance2, but on Runtime2 -/// it is Instance42. But there's no other way, but to craft this key manually (which is what I'm -/// trying to avoid here) - by using strings like "Instance2", "OutboundMessages", etc. pub mod storage_keys { use super::*; - use frame_support::{traits::Instance, StorageHasher}; + use frame_support::StorageHasher; use sp_core::storage::StorageKey; /// Storage key of the outbound message in the runtime storage. - pub fn message_key(lane: &LaneId, nonce: MessageNonce) -> StorageKey { - storage_map_final_key::("OutboundMessages", &MessageKey { lane_id: *lane, nonce }.encode()) + pub fn message_key(pallet_prefix: &str, lane: &LaneId, nonce: MessageNonce) -> StorageKey { + storage_map_final_key( + pallet_prefix, + "OutboundMessages", + &MessageKey { lane_id: *lane, nonce }.encode(), + ) } /// Storage key of the outbound message lane state in the runtime storage. - pub fn outbound_lane_data_key(lane: &LaneId) -> StorageKey { - storage_map_final_key::("OutboundLanes", lane) + pub fn outbound_lane_data_key(pallet_prefix: &str, lane: &LaneId) -> StorageKey { + storage_map_final_key(pallet_prefix, "OutboundLanes", lane) } /// Storage key of the inbound message lane state in the runtime storage. - pub fn inbound_lane_data_key(lane: &LaneId) -> StorageKey { - storage_map_final_key::("InboundLanes", lane) + pub fn inbound_lane_data_key(pallet_prefix: &str, lane: &LaneId) -> StorageKey { + storage_map_final_key(pallet_prefix, "InboundLanes", lane) } /// This is a copypaste of the `frame_support::storage::generator::StorageMap::storage_map_final_key`. - fn storage_map_final_key(map_name: &str, key: &[u8]) -> StorageKey { - let module_prefix_hashed = frame_support::Twox128::hash(I::PREFIX.as_bytes()); + fn storage_map_final_key(pallet_prefix: &str, map_name: &str, key: &[u8]) -> StorageKey { + let pallet_prefix_hashed = frame_support::Twox128::hash(pallet_prefix.as_bytes()); let storage_prefix_hashed = frame_support::Twox128::hash(map_name.as_bytes()); let key_hashed = frame_support::Blake2_128Concat::hash(key); let mut final_key = - Vec::with_capacity(module_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.len()); + Vec::with_capacity(pallet_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.len()); - final_key.extend_from_slice(&module_prefix_hashed[..]); + final_key.extend_from_slice(&pallet_prefix_hashed[..]); final_key.extend_from_slice(&storage_prefix_hashed[..]); final_key.extend_from_slice(key_hashed.as_ref()); @@ -888,7 +909,7 @@ pub mod storage_keys { } /// Ensure that the origin is either root, or `PalletOwner`. -fn ensure_owner_or_root, I: Instance>(origin: T::Origin) -> Result<(), BadOrigin> { +fn ensure_owner_or_root, I: 'static>(origin: T::Origin) -> Result<(), BadOrigin> { match origin.into() { Ok(RawOrigin::Root) => Ok(()), Ok(RawOrigin::Signed(ref signer)) if Some(signer) == Pallet::::module_owner().as_ref() => Ok(()), @@ -897,8 +918,8 @@ fn ensure_owner_or_root, I: Instance>(origin: T::Origin) -> Result< } /// Ensure that the pallet is in normal operational mode. -fn ensure_normal_operating_mode, I: Instance>() -> Result<(), Error> { - if PalletOperatingMode::::get() != OperatingMode::Normal { +fn ensure_normal_operating_mode, I: 'static>() -> Result<(), Error> { + if PalletOperatingMode::::get() != OperatingMode::Normal { Err(Error::::Halted) } else { Ok(()) @@ -906,8 +927,8 @@ fn ensure_normal_operating_mode, I: Instance>() -> Result<(), Error } /// Ensure that the pallet is not halted. -fn ensure_not_halted, I: Instance>() -> Result<(), Error> { - if PalletOperatingMode::::get() == OperatingMode::Halted { +fn ensure_not_halted, I: 'static>() -> Result<(), Error> { + if PalletOperatingMode::::get() == OperatingMode::Halted { Err(Error::::Halted) } else { Ok(()) @@ -915,12 +936,12 @@ fn ensure_not_halted, I: Instance>() -> Result<(), Error> { } /// Creates new inbound lane object, backed by runtime storage. -fn inbound_lane, I: Instance>(lane_id: LaneId) -> InboundLane> { +fn inbound_lane, I: 'static>(lane_id: LaneId) -> InboundLane> { InboundLane::new(inbound_lane_storage::(lane_id)) } /// Creates new runtime inbound lane storage. -fn inbound_lane_storage, I: Instance>(lane_id: LaneId) -> RuntimeInboundLaneStorage { +fn inbound_lane_storage, I: 'static>(lane_id: LaneId) -> RuntimeInboundLaneStorage { RuntimeInboundLaneStorage { lane_id, cached_data: RefCell::new(None), @@ -929,7 +950,7 @@ fn inbound_lane_storage, I: Instance>(lane_id: LaneId) -> RuntimeIn } /// Creates new outbound lane object, backed by runtime storage. -fn outbound_lane, I: Instance>(lane_id: LaneId) -> OutboundLane> { +fn outbound_lane, I: 'static>(lane_id: LaneId) -> OutboundLane> { OutboundLane::new(RuntimeOutboundLaneStorage { lane_id, _phantom: Default::default(), @@ -937,13 +958,13 @@ fn outbound_lane, I: Instance>(lane_id: LaneId) -> OutboundLane, I = DefaultInstance> { +struct RuntimeInboundLaneStorage, I: 'static = ()> { lane_id: LaneId, cached_data: RefCell>>, _phantom: PhantomData, } -impl, I: Instance> InboundLaneStorage for RuntimeInboundLaneStorage { +impl, I: 'static> InboundLaneStorage for RuntimeInboundLaneStorage { type MessageFee = T::InboundMessageFee; type Relayer = T::InboundRelayer; @@ -983,12 +1004,12 @@ impl, I: Instance> InboundLaneStorage for RuntimeInboundLaneStorage } /// Runtime outbound lane storage. -struct RuntimeOutboundLaneStorage { +struct RuntimeOutboundLaneStorage { lane_id: LaneId, _phantom: PhantomData<(T, I)>, } -impl, I: Instance> OutboundLaneStorage for RuntimeOutboundLaneStorage { +impl, I: 'static> OutboundLaneStorage for RuntimeOutboundLaneStorage { type MessageFee = T::OutboundMessageFee; fn id(&self) -> LaneId { @@ -996,11 +1017,11 @@ impl, I: Instance> OutboundLaneStorage for RuntimeOutboundLaneStora } fn data(&self) -> OutboundLaneData { - OutboundLanes::::get(&self.lane_id) + OutboundLanes::::get(&self.lane_id) } fn set_data(&mut self, data: OutboundLaneData) { - OutboundLanes::::insert(&self.lane_id, data) + OutboundLanes::::insert(&self.lane_id, data) } #[cfg(test)] @@ -1063,7 +1084,7 @@ mod tests { PAYLOAD_REJECTED_BY_TARGET_CHAIN, REGULAR_PAYLOAD, TEST_LANE_ID, TEST_RELAYER_A, TEST_RELAYER_B, }; use bp_messages::{UnrewardedRelayer, UnrewardedRelayersState}; - use frame_support::{assert_noop, assert_ok}; + use frame_support::{assert_noop, assert_ok, weights::Weight}; use frame_system::{EventRecord, Pallet as System, Phase}; use hex_literal::hex; use sp_runtime::DispatchError; @@ -1076,7 +1097,7 @@ mod tests { fn send_regular_message() -> Weight { get_ready_for_events(); - let message_nonce = outbound_lane::(TEST_LANE_ID) + let message_nonce = outbound_lane::(TEST_LANE_ID) .data() .latest_generated_nonce + 1; @@ -1095,7 +1116,7 @@ mod tests { System::::events(), vec![EventRecord { phase: Phase::Initialization, - event: TestEvent::Messages(RawEvent::MessageAccepted(TEST_LANE_ID, message_nonce)), + event: TestEvent::Messages(Event::MessageAccepted(TEST_LANE_ID, message_nonce)), topics: vec![], }], ); @@ -1138,10 +1159,7 @@ mod tests { System::::events(), vec![EventRecord { phase: Phase::Initialization, - event: TestEvent::Messages(RawEvent::MessagesDelivered( - TEST_LANE_ID, - DeliveredMessages::new(1, true), - )), + event: TestEvent::Messages(Event::MessagesDelivered(TEST_LANE_ID, DeliveredMessages::new(1, true),)), topics: vec![], }], ); @@ -1242,7 +1260,7 @@ mod tests { System::::events(), vec![EventRecord { phase: Phase::Initialization, - event: TestEvent::Messages(RawEvent::ParameterUpdated(parameter)), + event: TestEvent::Messages(Event::ParameterUpdated(parameter)), topics: vec![], }], ); @@ -1266,7 +1284,7 @@ mod tests { System::::events(), vec![EventRecord { phase: Phase::Initialization, - event: TestEvent::Messages(RawEvent::ParameterUpdated(parameter)), + event: TestEvent::Messages(Event::ParameterUpdated(parameter)), topics: vec![], }], ); @@ -1327,7 +1345,7 @@ mod tests { // send message first to be able to check that delivery_proof fails later send_regular_message(); - PalletOperatingMode::::put(OperatingMode::Halted); + PalletOperatingMode::::put(OperatingMode::Halted); assert_noop!( Pallet::::send_message( @@ -1336,12 +1354,12 @@ mod tests { REGULAR_PAYLOAD, REGULAR_PAYLOAD.declared_weight, ), - Error::::Halted, + Error::::Halted, ); assert_noop!( Pallet::::increase_message_fee(Origin::signed(1), TEST_LANE_ID, 1, 1,), - Error::::Halted, + Error::::Halted, ); assert_noop!( @@ -1352,7 +1370,7 @@ mod tests { 1, REGULAR_PAYLOAD.declared_weight, ), - Error::::Halted, + Error::::Halted, ); assert_noop!( @@ -1371,7 +1389,7 @@ mod tests { total_messages: 1, }, ), - Error::::Halted, + Error::::Halted, ); }); } @@ -1382,7 +1400,7 @@ mod tests { // send message first to be able to check that delivery_proof fails later send_regular_message(); - PalletOperatingMode::::put(OperatingMode::RejectingOutboundMessages); + PalletOperatingMode::::put(OperatingMode::RejectingOutboundMessages); assert_noop!( Pallet::::send_message( @@ -1391,7 +1409,7 @@ mod tests { REGULAR_PAYLOAD, REGULAR_PAYLOAD.declared_weight, ), - Error::::Halted, + Error::::Halted, ); assert_ok!(Pallet::::increase_message_fee( @@ -1445,7 +1463,7 @@ mod tests { PAYLOAD_REJECTED_BY_TARGET_CHAIN, PAYLOAD_REJECTED_BY_TARGET_CHAIN.declared_weight ), - Error::::MessageRejectedByChainVerifier, + Error::::MessageRejectedByChainVerifier, ); }); } @@ -1456,7 +1474,7 @@ mod tests { // messages with zero fee are rejected by lane verifier assert_noop!( Pallet::::send_message(Origin::signed(1), TEST_LANE_ID, REGULAR_PAYLOAD, 0), - Error::::MessageRejectedByLaneVerifier, + Error::::MessageRejectedByLaneVerifier, ); }); } @@ -1472,7 +1490,7 @@ mod tests { REGULAR_PAYLOAD, REGULAR_PAYLOAD.declared_weight ), - Error::::FailedToWithdrawMessageFee, + Error::::FailedToWithdrawMessageFee, ); }); } @@ -1496,7 +1514,7 @@ mod tests { fn receive_messages_proof_updates_confirmed_message_nonce() { run_test(|| { // say we have received 10 messages && last confirmed message is 8 - InboundLanes::::insert( + InboundLanes::::insert( TEST_LANE_ID, InboundLaneData { last_confirmed_nonce: 8, @@ -1573,14 +1591,14 @@ mod tests { fn receive_messages_proof_rejects_invalid_proof() { run_test(|| { assert_noop!( - Pallet::::receive_messages_proof( + Pallet::::receive_messages_proof( Origin::signed(1), TEST_RELAYER_A, Err(()).into(), 1, 0, ), - Error::::InvalidMessagesProof, + Error::::InvalidMessagesProof, ); }); } @@ -1589,14 +1607,14 @@ mod tests { fn receive_messages_proof_rejects_proof_with_too_many_messages() { run_test(|| { assert_noop!( - Pallet::::receive_messages_proof( + Pallet::::receive_messages_proof( Origin::signed(1), TEST_RELAYER_A, Ok(vec![message(1, REGULAR_PAYLOAD)]).into(), u32::MAX, 0, ), - Error::::TooManyMessagesInTheProof, + Error::::TooManyMessagesInTheProof, ); }); } @@ -1608,7 +1626,7 @@ mod tests { receive_messages_delivery_proof(); assert_eq!( - OutboundLanes::::get(&TEST_LANE_ID).latest_received_nonce, + OutboundLanes::::get(&TEST_LANE_ID).latest_received_nonce, 1, ); }); @@ -1696,7 +1714,7 @@ mod tests { TestMessagesDeliveryProof(Err(())), Default::default(), ), - Error::::InvalidMessagesDeliveryProof, + Error::::InvalidMessagesDeliveryProof, ); }); } @@ -1726,7 +1744,7 @@ mod tests { ..Default::default() }, ), - Error::::InvalidUnrewardedRelayersState, + Error::::InvalidUnrewardedRelayersState, ); // when number of messages is invalid @@ -1751,7 +1769,7 @@ mod tests { ..Default::default() }, ), - Error::::InvalidUnrewardedRelayersState, + Error::::InvalidUnrewardedRelayersState, ); }); } @@ -1762,7 +1780,7 @@ mod tests { let mut invalid_message = message(1, REGULAR_PAYLOAD); invalid_message.data.payload = Vec::new(); - assert_ok!(Pallet::::receive_messages_proof( + assert_ok!(Pallet::::receive_messages_proof( Origin::signed(1), TEST_RELAYER_A, Ok(vec![invalid_message]).into(), @@ -1783,7 +1801,7 @@ mod tests { let mut invalid_message = message(2, REGULAR_PAYLOAD); invalid_message.data.payload = Vec::new(); - assert_ok!(Pallet::::receive_messages_proof( + assert_ok!(Pallet::::receive_messages_proof( Origin::signed(1), TEST_RELAYER_A, Ok(vec![ @@ -1807,7 +1825,7 @@ mod tests { fn storage_message_key_computed_properly() { // If this test fails, then something has been changed in module storage that is breaking all // previously crafted messages proofs. - let storage_key = storage_keys::message_key::(&*b"test", 42).0; + let storage_key = storage_keys::message_key("BridgeMessages", &*b"test", 42).0; assert_eq!( storage_key, hex!("dd16c784ebd3390a9bc0357c7511ed018a395e6242c6813b196ca31ed0547ea79446af0e09063bd4a7874aef8a997cec746573742a00000000000000").to_vec(), @@ -1820,7 +1838,7 @@ mod tests { fn outbound_lane_data_key_computed_properly() { // If this test fails, then something has been changed in module storage that is breaking all // previously crafted outbound lane state proofs. - let storage_key = storage_keys::outbound_lane_data_key::(&*b"test").0; + let storage_key = storage_keys::outbound_lane_data_key("BridgeMessages", &*b"test").0; assert_eq!( storage_key, hex!("dd16c784ebd3390a9bc0357c7511ed0196c246acb9b55077390e3ca723a0ca1f44a8995dd50b6657a037a7839304535b74657374").to_vec(), @@ -1833,7 +1851,7 @@ mod tests { fn inbound_lane_data_key_computed_properly() { // If this test fails, then something has been changed in module storage that is breaking all // previously crafted inbound lane state proofs. - let storage_key = storage_keys::inbound_lane_data_key::(&*b"test").0; + let storage_key = storage_keys::inbound_lane_data_key("BridgeMessages", &*b"test").0; assert_eq!( storage_key, hex!("dd16c784ebd3390a9bc0357c7511ed01e5f83cf83f2127eb47afdc35d6e43fab44a8995dd50b6657a037a7839304535b74657374").to_vec(), @@ -1849,7 +1867,7 @@ mod tests { let message2 = message(2, message_payload(0, Weight::MAX / 2)); let message3 = message(3, message_payload(0, Weight::MAX / 2)); - assert_ok!(Pallet::::receive_messages_proof( + assert_ok!(Pallet::::receive_messages_proof( Origin::signed(1), TEST_RELAYER_A, // this may cause overflow if source chain storage is invalid @@ -1868,8 +1886,8 @@ mod tests { receive_messages_delivery_proof(); assert_noop!( - Pallet::::increase_message_fee(Origin::signed(1), TEST_LANE_ID, 1, 100,), - Error::::MessageIsAlreadyDelivered, + Pallet::::increase_message_fee(Origin::signed(1), TEST_LANE_ID, 1, 100,), + Error::::MessageIsAlreadyDelivered, ); }); } @@ -1878,8 +1896,8 @@ mod tests { fn increase_message_fee_fails_if_message_is_not_yet_sent() { run_test(|| { assert_noop!( - Pallet::::increase_message_fee(Origin::signed(1), TEST_LANE_ID, 1, 100,), - Error::::MessageIsNotYetSent, + Pallet::::increase_message_fee(Origin::signed(1), TEST_LANE_ID, 1, 100,), + Error::::MessageIsNotYetSent, ); }); } @@ -1892,8 +1910,8 @@ mod tests { TestMessageDeliveryAndDispatchPayment::reject_payments(); assert_noop!( - Pallet::::increase_message_fee(Origin::signed(1), TEST_LANE_ID, 1, 100,), - Error::::FailedToWithdrawMessageFee, + Pallet::::increase_message_fee(Origin::signed(1), TEST_LANE_ID, 1, 100,), + Error::::FailedToWithdrawMessageFee, ); }); } @@ -1903,7 +1921,7 @@ mod tests { run_test(|| { send_regular_message(); - assert_ok!(Pallet::::increase_message_fee( + assert_ok!(Pallet::::increase_message_fee( Origin::signed(1), TEST_LANE_ID, 1, @@ -2120,7 +2138,7 @@ mod tests { ))), UnrewardedRelayersState::default(), ), - Error::::TryingToConfirmMoreMessagesThanExpected, + Error::::TryingToConfirmMoreMessagesThanExpected, ); }); } diff --git a/bridges/primitives/chain-millau/src/lib.rs b/bridges/primitives/chain-millau/src/lib.rs index d9f4fd51f9..34d59ce2ef 100644 --- a/bridges/primitives/chain-millau/src/lib.rs +++ b/bridges/primitives/chain-millau/src/lib.rs @@ -245,6 +245,9 @@ pub fn max_extrinsic_size() -> u32 { *BlockLength::get().max.get(DispatchClass::Normal) } +/// Name of the With-Rialto messages pallet instance in the Millau runtime. +pub const WITH_RIALTO_MESSAGES_PALLET_NAME: &str = "BridgeRialtoMessages"; + /// Name of the `MillauFinalityApi::best_finalized` runtime method. pub const BEST_FINALIZED_MILLAU_HEADER_METHOD: &str = "MillauFinalityApi_best_finalized"; diff --git a/bridges/primitives/chain-rialto/src/lib.rs b/bridges/primitives/chain-rialto/src/lib.rs index 10eac7deb8..57fe5d4bfa 100644 --- a/bridges/primitives/chain-rialto/src/lib.rs +++ b/bridges/primitives/chain-rialto/src/lib.rs @@ -214,6 +214,9 @@ pub fn max_extrinsic_size() -> u32 { *BlockLength::get().max.get(DispatchClass::Normal) } +/// Name of the With-Millau messages pallet instance in the Millau runtime. +pub const WITH_MILLAU_MESSAGES_PALLET_NAME: &str = "BridgeMillauMessages"; + /// Name of the `RialtoFinalityApi::best_finalized` runtime method. pub const BEST_FINALIZED_RIALTO_HEADER_METHOD: &str = "RialtoFinalityApi_best_finalized"; diff --git a/bridges/primitives/chain-rococo/src/lib.rs b/bridges/primitives/chain-rococo/src/lib.rs index d76ec8e679..2d5769a39c 100644 --- a/bridges/primitives/chain-rococo/src/lib.rs +++ b/bridges/primitives/chain-rococo/src/lib.rs @@ -72,6 +72,9 @@ pub fn derive_account_from_wococo_id(id: bp_runtime::SourceAccount) - AccountIdConverter::convert(encoded_id) } +/// Name of the With-Wococo messages pallet instance in the Rococo runtime. +pub const WITH_WOCOCO_MESSAGES_PALLET_NAME: &str = "BridgeWococoMessages"; + /// Name of the `RococoFinalityApi::best_finalized` runtime method. pub const BEST_FINALIZED_ROCOCO_HEADER_METHOD: &str = "RococoFinalityApi_best_finalized"; /// Name of the `RococoFinalityApi::is_known_header` runtime method. diff --git a/bridges/primitives/chain-wococo/src/lib.rs b/bridges/primitives/chain-wococo/src/lib.rs index e0d49ffe85..b846e00321 100644 --- a/bridges/primitives/chain-wococo/src/lib.rs +++ b/bridges/primitives/chain-wococo/src/lib.rs @@ -37,6 +37,9 @@ pub fn derive_account_from_rococo_id(id: bp_runtime::SourceAccount) - AccountIdConverter::convert(encoded_id) } +/// Name of the With-Rococo messages pallet instance in the Wococo runtime. +pub const WITH_ROCOCO_MESSAGES_PALLET_NAME: &str = "BridgeRococoMessages"; + /// Name of the `WococoFinalityApi::best_finalized` runtime method. pub const BEST_FINALIZED_WOCOCO_HEADER_METHOD: &str = "WococoFinalityApi_best_finalized"; /// Name of the `WococoFinalityApi::is_known_header` runtime method. diff --git a/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs b/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs index 93662a9d6f..6b861c28d4 100644 --- a/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs +++ b/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs @@ -23,7 +23,6 @@ use frame_support::dispatch::GetDispatchInfo; use sp_core::{Bytes, Pair}; use bp_messages::MessageNonce; -use bp_runtime::{MILLAU_CHAIN_ID, RIALTO_CHAIN_ID}; use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; use messages_relay::message_lane::MessageLane; use relay_millau_client::{HeaderId as MillauHeaderId, Millau, SigningParams as MillauSigningParams}; @@ -62,6 +61,9 @@ impl SubstrateMessageLane for MillauMessagesToRialto { const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_millau::BEST_FINALIZED_MILLAU_HEADER_METHOD; const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str = bp_rialto::BEST_FINALIZED_RIALTO_HEADER_METHOD; + const MESSAGE_PALLET_NAME_AT_SOURCE: &'static str = bp_millau::WITH_RIALTO_MESSAGES_PALLET_NAME; + const MESSAGE_PALLET_NAME_AT_TARGET: &'static str = bp_rialto::WITH_MILLAU_MESSAGES_PALLET_NAME; + type SourceChain = Millau; type TargetChain = Rialto; @@ -135,12 +137,10 @@ impl SubstrateMessageLane for MillauMessagesToRialto { } /// Millau node as messages source. -type MillauSourceClient = - SubstrateMessagesSource; +type MillauSourceClient = SubstrateMessagesSource; /// Rialto node as messages target. -type RialtoTargetClient = - SubstrateMessagesTarget; +type RialtoTargetClient = SubstrateMessagesTarget; /// Run Millau-to-Rialto messages sync. pub async fn run( @@ -212,14 +212,12 @@ pub async fn run( source_client.clone(), lane.clone(), lane_id, - RIALTO_CHAIN_ID, params.target_to_source_headers_relay, ), RialtoTargetClient::new( params.target_client, lane, lane_id, - MILLAU_CHAIN_ID, metrics_values, params.source_to_target_headers_relay, ), diff --git a/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs b/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs index 2b7f32f2d4..f2ee1f82f5 100644 --- a/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs +++ b/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs @@ -23,7 +23,6 @@ use frame_support::dispatch::GetDispatchInfo; use sp_core::{Bytes, Pair}; use bp_messages::MessageNonce; -use bp_runtime::{MILLAU_CHAIN_ID, RIALTO_CHAIN_ID}; use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; use messages_relay::message_lane::MessageLane; use relay_millau_client::{HeaderId as MillauHeaderId, Millau, SigningParams as MillauSigningParams}; @@ -62,6 +61,9 @@ impl SubstrateMessageLane for RialtoMessagesToMillau { const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_rialto::BEST_FINALIZED_RIALTO_HEADER_METHOD; const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str = bp_millau::BEST_FINALIZED_MILLAU_HEADER_METHOD; + const MESSAGE_PALLET_NAME_AT_SOURCE: &'static str = bp_rialto::WITH_MILLAU_MESSAGES_PALLET_NAME; + const MESSAGE_PALLET_NAME_AT_TARGET: &'static str = bp_millau::WITH_RIALTO_MESSAGES_PALLET_NAME; + type SourceChain = Rialto; type TargetChain = Millau; @@ -135,12 +137,10 @@ impl SubstrateMessageLane for RialtoMessagesToMillau { } /// Rialto node as messages source. -type RialtoSourceClient = - SubstrateMessagesSource; +type RialtoSourceClient = SubstrateMessagesSource; /// Millau node as messages target. -type MillauTargetClient = - SubstrateMessagesTarget; +type MillauTargetClient = SubstrateMessagesTarget; /// Run Rialto-to-Millau messages sync. pub async fn run( @@ -211,14 +211,12 @@ pub async fn run( source_client.clone(), lane.clone(), lane_id, - MILLAU_CHAIN_ID, params.target_to_source_headers_relay, ), MillauTargetClient::new( params.target_client, lane, lane_id, - RIALTO_CHAIN_ID, metrics_values, params.source_to_target_headers_relay, ), diff --git a/bridges/relays/bin-substrate/src/chains/rococo_messages_to_wococo.rs b/bridges/relays/bin-substrate/src/chains/rococo_messages_to_wococo.rs index 043e6c89e4..3abedc0ca3 100644 --- a/bridges/relays/bin-substrate/src/chains/rococo_messages_to_wococo.rs +++ b/bridges/relays/bin-substrate/src/chains/rococo_messages_to_wococo.rs @@ -22,7 +22,6 @@ use codec::Encode; use sp_core::{Bytes, Pair}; use bp_messages::MessageNonce; -use bp_runtime::{ROCOCO_CHAIN_ID, WOCOCO_CHAIN_ID}; use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; use messages_relay::message_lane::MessageLane; use relay_rococo_client::{HeaderId as RococoHeaderId, Rococo, SigningParams as RococoSigningParams}; @@ -61,6 +60,9 @@ impl SubstrateMessageLane for RococoMessagesToWococo { const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_rococo::BEST_FINALIZED_ROCOCO_HEADER_METHOD; const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str = bp_wococo::BEST_FINALIZED_WOCOCO_HEADER_METHOD; + const MESSAGE_PALLET_NAME_AT_SOURCE: &'static str = bp_rococo::WITH_WOCOCO_MESSAGES_PALLET_NAME; + const MESSAGE_PALLET_NAME_AT_TARGET: &'static str = bp_wococo::WITH_ROCOCO_MESSAGES_PALLET_NAME; + type SourceChain = Rococo; type TargetChain = Wococo; @@ -136,20 +138,10 @@ impl SubstrateMessageLane for RococoMessagesToWococo { } /// Rococo node as messages source. -type RococoSourceClient = SubstrateMessagesSource< - Rococo, - Wococo, - RococoMessagesToWococo, - relay_rococo_client::runtime::WithWococoMessagesInstance, ->; +type RococoSourceClient = SubstrateMessagesSource; /// Wococo node as messages target. -type WococoTargetClient = SubstrateMessagesTarget< - Rococo, - Wococo, - RococoMessagesToWococo, - relay_wococo_client::runtime::WithRococoMessagesInstance, ->; +type WococoTargetClient = SubstrateMessagesTarget; /// Run Rococo-to-Wococo messages sync. pub async fn run( @@ -226,14 +218,12 @@ pub async fn run( source_client.clone(), lane.clone(), lane_id, - WOCOCO_CHAIN_ID, params.target_to_source_headers_relay, ), WococoTargetClient::new( params.target_client, lane, lane_id, - ROCOCO_CHAIN_ID, metrics_values, params.source_to_target_headers_relay, ), diff --git a/bridges/relays/bin-substrate/src/chains/wococo_messages_to_rococo.rs b/bridges/relays/bin-substrate/src/chains/wococo_messages_to_rococo.rs index d068dc2f11..d4cff289e2 100644 --- a/bridges/relays/bin-substrate/src/chains/wococo_messages_to_rococo.rs +++ b/bridges/relays/bin-substrate/src/chains/wococo_messages_to_rococo.rs @@ -22,7 +22,6 @@ use codec::Encode; use sp_core::{Bytes, Pair}; use bp_messages::MessageNonce; -use bp_runtime::{ROCOCO_CHAIN_ID, WOCOCO_CHAIN_ID}; use bridge_runtime_common::messages::target::FromBridgedChainMessagesProof; use messages_relay::message_lane::MessageLane; use relay_rococo_client::{HeaderId as RococoHeaderId, Rococo, SigningParams as RococoSigningParams}; @@ -60,6 +59,9 @@ impl SubstrateMessageLane for WococoMessagesToRococo { const BEST_FINALIZED_SOURCE_HEADER_ID_AT_TARGET: &'static str = bp_wococo::BEST_FINALIZED_WOCOCO_HEADER_METHOD; const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str = bp_rococo::BEST_FINALIZED_ROCOCO_HEADER_METHOD; + const MESSAGE_PALLET_NAME_AT_SOURCE: &'static str = bp_wococo::WITH_ROCOCO_MESSAGES_PALLET_NAME; + const MESSAGE_PALLET_NAME_AT_TARGET: &'static str = bp_rococo::WITH_WOCOCO_MESSAGES_PALLET_NAME; + type SourceChain = Wococo; type TargetChain = Rococo; @@ -135,20 +137,10 @@ impl SubstrateMessageLane for WococoMessagesToRococo { } /// Wococo node as messages source. -type WococoSourceClient = SubstrateMessagesSource< - Wococo, - Rococo, - WococoMessagesToRococo, - relay_wococo_client::runtime::WithRococoMessagesInstance, ->; +type WococoSourceClient = SubstrateMessagesSource; /// Rococo node as messages target. -type RococoTargetClient = SubstrateMessagesTarget< - Wococo, - Rococo, - WococoMessagesToRococo, - relay_rococo_client::runtime::WithWococoMessagesInstance, ->; +type RococoTargetClient = SubstrateMessagesTarget; /// Run Wococo-to-Rococo messages sync. pub async fn run( @@ -225,14 +217,12 @@ pub async fn run( source_client.clone(), lane.clone(), lane_id, - ROCOCO_CHAIN_ID, params.target_to_source_headers_relay, ), RococoTargetClient::new( params.target_client, lane, lane_id, - WOCOCO_CHAIN_ID, metrics_values, params.source_to_target_headers_relay, ), diff --git a/bridges/relays/client-rococo/src/runtime.rs b/bridges/relays/client-rococo/src/runtime.rs index 77d10529bf..0a8187b1f0 100644 --- a/bridges/relays/client-rococo/src/runtime.rs +++ b/bridges/relays/client-rococo/src/runtime.rs @@ -22,9 +22,6 @@ use bp_runtime::Chain; use codec::{Decode, Encode}; use frame_support::weights::Weight; -/// Instance of messages pallet that is used to bridge with Wococo chain. -pub type WithWococoMessagesInstance = pallet_bridge_messages::Instance1; - /// Unchecked Rococo extrinsic. pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic; diff --git a/bridges/relays/client-wococo/src/runtime.rs b/bridges/relays/client-wococo/src/runtime.rs index e3e7ce7b31..6a2f7e401a 100644 --- a/bridges/relays/client-wococo/src/runtime.rs +++ b/bridges/relays/client-wococo/src/runtime.rs @@ -22,9 +22,6 @@ use bp_runtime::Chain; use codec::{Decode, Encode}; use frame_support::weights::Weight; -/// Instance of messages pallet that is used to bridge with Rococo chain. -pub type WithRococoMessagesInstance = pallet_bridge_messages::DefaultInstance; - /// Unchecked Wococo extrinsic. pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic; diff --git a/bridges/relays/lib-substrate-relay/src/messages_lane.rs b/bridges/relays/lib-substrate-relay/src/messages_lane.rs index 15b75ae945..c859e0f9e2 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_lane.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_lane.rs @@ -81,6 +81,11 @@ pub trait SubstrateMessageLane: 'static + Clone + Send + Sync { /// Name of the runtime method that returns id of best finalized target header at source chain. const BEST_FINALIZED_TARGET_HEADER_ID_AT_SOURCE: &'static str; + /// Name of the messages pallet as it is declared in the `construct_runtime!()` at source chain. + const MESSAGE_PALLET_NAME_AT_SOURCE: &'static str; + /// Name of the messages pallet as it is declared in the `construct_runtime!()` at target chain. + const MESSAGE_PALLET_NAME_AT_TARGET: &'static str; + /// Source chain. type SourceChain: Chain; /// Target chain. diff --git a/bridges/relays/lib-substrate-relay/src/messages_source.rs b/bridges/relays/lib-substrate-relay/src/messages_source.rs index 08e4964de7..a442ebfb44 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_source.rs @@ -24,12 +24,12 @@ use crate::on_demand_headers::OnDemandHeadersRelay; use async_trait::async_trait; use bp_messages::{LaneId, MessageNonce, UnrewardedRelayersState}; -use bp_runtime::{messages::DispatchFeePayment, ChainId}; +use bp_runtime::messages::DispatchFeePayment; use bridge_runtime_common::messages::{ source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, }; use codec::{Decode, Encode}; -use frame_support::{traits::Instance, weights::Weight}; +use frame_support::weights::Weight; use messages_relay::message_lane::MessageLane; use messages_relay::{ message_lane::{SourceHeaderIdOf, TargetHeaderIdOf}, @@ -42,7 +42,7 @@ use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf, Hea use relay_utils::{relay_loop::Client as RelayClient, BlockNumberBase, HeaderId}; use sp_core::Bytes; use sp_runtime::{traits::Header as HeaderT, DeserializeOwned}; -use std::{marker::PhantomData, ops::RangeInclusive}; +use std::ops::RangeInclusive; /// Intermediate message proof returned by the source Substrate node. Includes everything /// required to submit to the target node: cumulative dispatch weight of bundled messages and @@ -50,55 +50,47 @@ use std::{marker::PhantomData, ops::RangeInclusive}; pub type SubstrateMessagesProof = (Weight, FromBridgedChainMessagesProof>); /// Substrate client as Substrate messages source. -pub struct SubstrateMessagesSource { +pub struct SubstrateMessagesSource { client: Client, lane: P, lane_id: LaneId, - instance: ChainId, target_to_source_headers_relay: Option>, - _phantom: PhantomData, } -impl SubstrateMessagesSource { +impl SubstrateMessagesSource { /// Create new Substrate headers source. pub fn new( client: Client, lane: P, lane_id: LaneId, - instance: ChainId, target_to_source_headers_relay: Option>, ) -> Self { SubstrateMessagesSource { client, lane, lane_id, - instance, target_to_source_headers_relay, - _phantom: Default::default(), } } } -impl Clone for SubstrateMessagesSource { +impl Clone for SubstrateMessagesSource { fn clone(&self) -> Self { Self { client: self.client.clone(), lane: self.lane.clone(), lane_id: self.lane_id, - instance: self.instance, target_to_source_headers_relay: self.target_to_source_headers_relay.clone(), - _phantom: Default::default(), } } } #[async_trait] -impl RelayClient for SubstrateMessagesSource +impl RelayClient for SubstrateMessagesSource where SC: Chain, TC: Chain, P: SubstrateMessageLane, - I: Send + Sync + Instance, { type Error = SubstrateError; @@ -108,7 +100,7 @@ where } #[async_trait] -impl SourceClient for SubstrateMessagesSource +impl SourceClient for SubstrateMessagesSource where SC: Chain< Hash = ::SourceHeaderHash, @@ -132,7 +124,6 @@ where >, ::TargetHeaderNumber: Decode, ::TargetHeaderHash: Decode, - I: Send + Sync + Instance, { async fn state(&self) -> Result, SubstrateError> { // we can't continue to deliver confirmations if source node is out of sync, because @@ -217,12 +208,17 @@ where let mut storage_keys = Vec::with_capacity(nonces.end().saturating_sub(*nonces.start()) as usize + 1); let mut message_nonce = *nonces.start(); while message_nonce <= *nonces.end() { - let message_key = pallet_bridge_messages::storage_keys::message_key::(&self.lane_id, message_nonce); + let message_key = pallet_bridge_messages::storage_keys::message_key( + P::MESSAGE_PALLET_NAME_AT_SOURCE, + &self.lane_id, + message_nonce, + ); storage_keys.push(message_key); message_nonce += 1; } if proof_parameters.outbound_state_proof_required { - storage_keys.push(pallet_bridge_messages::storage_keys::outbound_lane_data_key::( + storage_keys.push(pallet_bridge_messages::storage_keys::outbound_lane_data_key( + P::MESSAGE_PALLET_NAME_AT_SOURCE, &self.lane_id, )); } diff --git a/bridges/relays/lib-substrate-relay/src/messages_target.rs b/bridges/relays/lib-substrate-relay/src/messages_target.rs index 4cafcc4866..1db8345931 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_target.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_target.rs @@ -24,12 +24,11 @@ use crate::on_demand_headers::OnDemandHeadersRelay; use async_trait::async_trait; use bp_messages::{LaneId, MessageNonce, UnrewardedRelayersState}; -use bp_runtime::ChainId; use bridge_runtime_common::messages::{ source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, }; use codec::{Decode, Encode}; -use frame_support::{traits::Instance, weights::Weight}; +use frame_support::weights::Weight; use messages_relay::message_lane::MessageLane; use messages_relay::{ message_lane::{SourceHeaderIdOf, TargetHeaderIdOf}, @@ -40,7 +39,7 @@ use relay_substrate_client::{Chain, Client, Error as SubstrateError, HashOf}; use relay_utils::{relay_loop::Client as RelayClient, BlockNumberBase, HeaderId}; use sp_core::Bytes; use sp_runtime::{traits::Header as HeaderT, DeserializeOwned, FixedPointNumber, FixedU128}; -use std::{convert::TryFrom, marker::PhantomData, ops::RangeInclusive}; +use std::{convert::TryFrom, ops::RangeInclusive}; /// Message receiving proof returned by the target Substrate node. pub type SubstrateMessagesReceivingProof = ( @@ -49,23 +48,20 @@ pub type SubstrateMessagesReceivingProof = ( ); /// Substrate client as Substrate messages target. -pub struct SubstrateMessagesTarget { +pub struct SubstrateMessagesTarget { client: Client, lane: P, lane_id: LaneId, - instance: ChainId, metric_values: StandaloneMessagesMetrics, source_to_target_headers_relay: Option>, - _phantom: PhantomData, } -impl SubstrateMessagesTarget { +impl SubstrateMessagesTarget { /// Create new Substrate headers target. pub fn new( client: Client, lane: P, lane_id: LaneId, - instance: ChainId, metric_values: StandaloneMessagesMetrics, source_to_target_headers_relay: Option>, ) -> Self { @@ -73,35 +69,30 @@ impl SubstrateMessagesTarget Clone for SubstrateMessagesTarget { +impl Clone for SubstrateMessagesTarget { fn clone(&self) -> Self { Self { client: self.client.clone(), lane: self.lane.clone(), lane_id: self.lane_id, - instance: self.instance, metric_values: self.metric_values.clone(), source_to_target_headers_relay: self.source_to_target_headers_relay.clone(), - _phantom: Default::default(), } } } #[async_trait] -impl RelayClient for SubstrateMessagesTarget +impl RelayClient for SubstrateMessagesTarget where SC: Chain, TC: Chain, P: SubstrateMessageLane, - I: Send + Sync + Instance, { type Error = SubstrateError; @@ -111,7 +102,7 @@ where } #[async_trait] -impl TargetClient for SubstrateMessagesTarget +impl TargetClient for SubstrateMessagesTarget where SC: Chain< Hash = ::SourceHeaderHash, @@ -135,7 +126,6 @@ where >, ::SourceHeaderNumber: Decode, ::SourceHeaderHash: Decode, - I: Send + Sync + Instance, { async fn state(&self) -> Result, SubstrateError> { // we can't continue to deliver messages if target node is out of sync, because @@ -212,7 +202,10 @@ where SubstrateError, > { let (id, relayers_state) = self.unrewarded_relayers_state(id).await?; - let inbound_data_key = pallet_bridge_messages::storage_keys::inbound_lane_data_key::(&self.lane_id); + let inbound_data_key = pallet_bridge_messages::storage_keys::inbound_lane_data_key( + P::MESSAGE_PALLET_NAME_AT_TARGET, + &self.lane_id, + ); let proof = self .client .prove_storage(vec![inbound_data_key], id.1)