diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index f16c1da14543..ab566ab9f213 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -1481,7 +1481,7 @@ construct_runtime! { Paras: parachains_paras::{Pallet, Call, Storage, Event, Config} = 56, Initializer: parachains_initializer::{Pallet, Call, Storage} = 57, Dmp: parachains_dmp::{Pallet, Call, Storage} = 58, - ParasUmp: parachains_ump::{Pallet, Call, Storage, Event} = 59, + Ump: parachains_ump::{Pallet, Call, Storage, Event} = 59, Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event} = 60, ParasSessionInfo: parachains_session_info::{Pallet, Call, Storage} = 61, diff --git a/runtime/parachains/src/inclusion.rs b/runtime/parachains/src/inclusion.rs index 171c9f90f993..222941e75b52 100644 --- a/runtime/parachains/src/inclusion.rs +++ b/runtime/parachains/src/inclusion.rs @@ -922,7 +922,7 @@ impl CandidateCheckContext { para_id, processed_downward_messages, )?; - >::check_upward_messages(&self.config, para_id, upward_messages)?; + >::check_upward_messages(&self.config, para_id, upward_messages)?; >::check_hrmp_watermark( para_id, self.relay_parent_number, diff --git a/runtime/parachains/src/initializer.rs b/runtime/parachains/src/initializer.rs index 41e0c7adb07d..4a6fea384bd2 100644 --- a/runtime/parachains/src/initializer.rs +++ b/runtime/parachains/src/initializer.rs @@ -140,7 +140,7 @@ pub mod pallet { session_info::Module::::initializer_initialize(now) + T::DisputesHandler::initializer_initialize(now) + dmp::Pallet::::initializer_initialize(now) + - ump::Module::::initializer_initialize(now) + + ump::Pallet::::initializer_initialize(now) + hrmp::Pallet::::initializer_initialize(now); HasInitialized::::set(Some(())); @@ -151,7 +151,7 @@ pub mod pallet { fn on_finalize(_: T::BlockNumber) { // reverse initialization order. hrmp::Pallet::::initializer_finalize(); - ump::Module::::initializer_finalize(); + ump::Pallet::::initializer_finalize(); dmp::Pallet::::initializer_finalize(); T::DisputesHandler::initializer_finalize(); session_info::Module::::initializer_finalize(); @@ -239,7 +239,7 @@ impl Pallet { session_info::Module::::initializer_on_new_session(¬ification); T::DisputesHandler::initializer_on_new_session(¬ification); dmp::Pallet::::initializer_on_new_session(¬ification, &outgoing_paras); - ump::Module::::initializer_on_new_session(¬ification, &outgoing_paras); + ump::Pallet::::initializer_on_new_session(¬ification, &outgoing_paras); hrmp::Pallet::::initializer_on_new_session(¬ification, &outgoing_paras); } diff --git a/runtime/parachains/src/paras_inherent.rs b/runtime/parachains/src/paras_inherent.rs index 34eddcb945cf..6cee5d4ae7e4 100644 --- a/runtime/parachains/src/paras_inherent.rs +++ b/runtime/parachains/src/paras_inherent.rs @@ -210,7 +210,7 @@ decl_module! { >::occupied(&occupied); // Give some time slice to dispatch pending upward messages. - >::process_pending_upward_messages(); + >::process_pending_upward_messages(); // And track that we've finished processing the inherent for this block. Included::set(Some(())); diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index 5f2dff984175..24d9976b5ff7 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -20,10 +20,12 @@ use crate::{ }; use sp_std::{prelude::*, fmt, marker::PhantomData, convert::TryFrom}; use sp_std::collections::{btree_map::BTreeMap, vec_deque::VecDeque}; -use frame_support::{decl_module, decl_event, decl_storage, StorageMap, StorageValue, weights::Weight, traits::Get}; +use frame_support::pallet_prelude::*; use primitives::v1::{Id as ParaId, UpwardMessage}; use xcm::v0::Outcome; +pub use pallet::*; + /// All upward messages coming from parachains will be funneled into an implementation of this trait. /// /// The message is opaque from the perspective of UMP. The message size can range from 0 to @@ -65,7 +67,6 @@ pub struct XcmSink(PhantomData<(XcmExecutor, Config)>); impl, C: Config> UmpSink for XcmSink { fn process_upward_message(origin: ParaId, data: &[u8], max_weight: Weight) -> Result { - use parity_scale_codec::Decode; use xcm::VersionedXcm; use xcm::v0::{Xcm, Junction, MultiLocation, Error as XcmError}; @@ -74,11 +75,11 @@ impl, C: Config> UmpSink for XcmSink::try_from); match maybe_msg { Err(_) => { - Module::::deposit_event(Event::InvalidFormat(id)); + Pallet::::deposit_event(Event::InvalidFormat(id)); Ok(0) }, Ok(Err(())) => { - Module::::deposit_event(Event::UnsupportedVersion(id)); + Pallet::::deposit_event(Event::UnsupportedVersion(id)); Ok(0) }, Ok(Ok(xcm_message)) => { @@ -89,7 +90,7 @@ impl, C: Config> UmpSink for XcmSink Err((id, required)), outcome => { let weight_used = outcome.weight_used(); - Module::::deposit_event(Event::ExecutedUpward(id, outcome)); + Pallet::::deposit_event(Event::ExecutedUpward(id, outcome)); Ok(weight_used) } } @@ -151,61 +152,33 @@ impl fmt::Debug for AcceptanceCheckErr { } } -pub trait Config: frame_system::Config + configuration::Config { - /// The aggregate event. - type Event: From + Into<::Event>; +#[frame_support::pallet] +pub mod pallet { + use super::*; - /// A place where all received upward messages are funneled. - type UmpSink: UmpSink; + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); - /// The factor by which the weight limit it multiplied for the first UMP message to execute with. - /// - /// An amount less than 100 keeps more available weight in the queue for messages after the first, and potentially - /// stalls the queue in doing so. More than 100 will provide additional weight for the first message only. - /// - /// Generally you'll want this to be a bit more - 150 or 200 would be good values. - type FirstMessageFactorPercent: Get; -} + #[pallet::config] + pub trait Config: frame_system::Config + configuration::Config { + /// The aggregate event. + type Event: From + IsType<::Event>; -decl_storage! { - trait Store for Module as Ump { - /// The messages waiting to be handled by the relay-chain originating from a certain parachain. - /// - /// Note that some upward messages might have been already processed by the inclusion logic. E.g. - /// channel management messages. - /// - /// The messages are processed in FIFO order. - RelayDispatchQueues: map hasher(twox_64_concat) ParaId => VecDeque; - /// Size of the dispatch queues. Caches sizes of the queues in `RelayDispatchQueue`. - /// - /// First item in the tuple is the count of messages and second - /// is the total length (in bytes) of the message payloads. - /// - /// Note that this is an auxiliary mapping: it's possible to tell the byte size and the number of - /// messages only looking at `RelayDispatchQueues`. This mapping is separate to avoid the cost of - /// loading the whole message queue if only the total size and count are required. - /// - /// Invariant: - /// - The set of keys should exactly match the set of keys of `RelayDispatchQueues`. - // NOTE that this field is used by parachains via merkle storage proofs, therefore changing - // the format will require migration of parachains. - RelayDispatchQueueSize: map hasher(twox_64_concat) ParaId => (u32, u32); - /// The ordered list of `ParaId`s that have a `RelayDispatchQueue` entry. + /// A place where all received upward messages are funneled. + type UmpSink: UmpSink; + + /// The factor by which the weight limit it multiplied for the first UMP message to execute with. /// - /// Invariant: - /// - The set of items from this vector should be exactly the set of the keys in - /// `RelayDispatchQueues` and `RelayDispatchQueueSize`. - NeedsDispatch: Vec; - /// This is the para that gets will get dispatched first during the next upward dispatchable queue - /// execution round. + /// An amount less than 100 keeps more available weight in the queue for messages after the first, and potentially + /// stalls the queue in doing so. More than 100 will provide additional weight for the first message only. /// - /// Invariant: - /// - If `Some(para)`, then `para` must be present in `NeedsDispatch`. - NextDispatchRoundStartWith: Option; + /// Generally you'll want this to be a bit more - 150 or 200 would be good values. + type FirstMessageFactorPercent: Get; } -} -decl_event! { + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { /// Upward message is invalid XCM. /// \[ id \] @@ -223,18 +196,66 @@ decl_event! { /// \[ para, count, size \] UpwardMessagesReceived(ParaId, u32, u32), } -} -decl_module! { - /// The UMP module. - pub struct Module for enum Call where origin: ::Origin { - /// Deposit one of this module's events by using the default implementation. - fn deposit_event() = default; - } + /// The messages waiting to be handled by the relay-chain originating from a certain parachain. + /// + /// Note that some upward messages might have been already processed by the inclusion logic. E.g. + /// channel management messages. + /// + /// The messages are processed in FIFO order. + #[pallet::storage] + pub type RelayDispatchQueues = StorageMap< + _, + Twox64Concat, + ParaId, + VecDeque, + ValueQuery + >; + + /// Size of the dispatch queues. Caches sizes of the queues in `RelayDispatchQueue`. + /// + /// First item in the tuple is the count of messages and second + /// is the total length (in bytes) of the message payloads. + /// + /// Note that this is an auxiliary mapping: it's possible to tell the byte size and the number of + /// messages only looking at `RelayDispatchQueues`. This mapping is separate to avoid the cost of + /// loading the whole message queue if only the total size and count are required. + /// + /// Invariant: + /// - The set of keys should exactly match the set of keys of `RelayDispatchQueues`. + // NOTE that this field is used by parachains via merkle storage proofs, therefore changing + // the format will require migration of parachains. + #[pallet::storage] + pub type RelayDispatchQueueSize = StorageMap< + _, + Twox64Concat, + ParaId, + (u32, u32), + ValueQuery + >; + + /// The ordered list of `ParaId`s that have a `RelayDispatchQueue` entry. + /// + /// Invariant: + /// - The set of items from this vector should be exactly the set of the keys in + /// `RelayDispatchQueues` and `RelayDispatchQueueSize`. + #[pallet::storage] + pub type NeedsDispatch = StorageValue<_, Vec, ValueQuery>; + + /// This is the para that gets will get dispatched first during the next upward dispatchable queue + /// execution round. + /// + /// Invariant: + /// - If `Some(para)`, then `para` must be present in `NeedsDispatch`. + #[pallet::storage] + pub type NextDispatchRoundStartWith = StorageValue<_, ParaId>; + + #[pallet::call] + impl Pallet {} } /// Routines related to the upward message passing. -impl Module { +impl Pallet { /// Block initialization logic, called by initializer. pub(crate) fn initializer_initialize(_now: T::BlockNumber) -> Weight { 0 @@ -455,8 +476,8 @@ impl QueueCache { /// - `became_empty` is true if the queue _became_ empty. fn dequeue(&mut self, para: ParaId) -> (Option, bool) { let cache_entry = self.0.entry(para).or_insert_with(|| { - let queue = as Store>::RelayDispatchQueues::get(¶); - let (count, total_size) = as Store>::RelayDispatchQueueSize::get(¶); + let queue = as Store>::RelayDispatchQueues::get(¶); + let (count, total_size) = as Store>::RelayDispatchQueueSize::get(¶); QueueCacheEntry { queue, count, @@ -489,11 +510,11 @@ impl QueueCache { { if queue.is_empty() { // remove the entries altogether. - as Store>::RelayDispatchQueues::remove(¶); - as Store>::RelayDispatchQueueSize::remove(¶); + as Store>::RelayDispatchQueues::remove(¶); + as Store>::RelayDispatchQueueSize::remove(¶); } else { - as Store>::RelayDispatchQueues::insert(¶, queue); - as Store>::RelayDispatchQueueSize::insert(¶, (count, total_size)); + as Store>::RelayDispatchQueues::insert(¶, queue); + as Store>::RelayDispatchQueueSize::insert(¶, (count, total_size)); } } } @@ -516,8 +537,8 @@ struct NeedsDispatchCursor { impl NeedsDispatchCursor { fn new() -> Self { - let needs_dispatch: Vec = as Store>::NeedsDispatch::get(); - let start_with = as Store>::NextDispatchRoundStartWith::get(); + let needs_dispatch: Vec = as Store>::NeedsDispatch::get(); + let start_with = as Store>::NextDispatchRoundStartWith::get(); let initial_index = match start_with { Some(para) => match needs_dispatch.binary_search(¶) { @@ -571,8 +592,8 @@ impl NeedsDispatchCursor { /// Flushes the dispatcher state into the persistent storage. fn flush(self) { let next_one = self.peek(); - as Store>::NextDispatchRoundStartWith::set(next_one); - as Store>::NeedsDispatch::put(self.needs_dispatch); + as Store>::NextDispatchRoundStartWith::set(next_one); + as Store>::NeedsDispatch::put(self.needs_dispatch); } } @@ -709,7 +730,6 @@ mod tests { use super::*; use super::mock_sink::Probe; use crate::mock::{Configuration, Ump, new_test_ext, MockGenesisConfig}; - use frame_support::IterableStorageMap; use std::collections::HashSet; struct GenesisConfigBuilder { diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index 6ef324e59ff3..a62654bb6d99 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -1071,7 +1071,7 @@ construct_runtime! { Paras: parachains_paras::{Pallet, Call, Storage, Event, Config} = 47, Initializer: parachains_initializer::{Pallet, Call, Storage} = 48, Dmp: parachains_dmp::{Pallet, Call, Storage} = 49, - ParasUmp: parachains_ump::{Pallet, Call, Storage, Event} = 50, + Ump: parachains_ump::{Pallet, Call, Storage, Event} = 50, Hrmp: parachains_hrmp::{Pallet, Call, Storage, Event} = 51, ParasSessionInfo: parachains_session_info::{Pallet, Call, Storage} = 52,