From b0f1de029d8a7db43eda979468c3d79e9a5a7742 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Wed, 4 Aug 2021 15:57:32 +0000 Subject: [PATCH 01/24] Introduce new config: ump_max_individual_weight --- runtime/parachains/src/configuration.rs | 145 +++++++++++++++++++++++- 1 file changed, 144 insertions(+), 1 deletion(-) diff --git a/runtime/parachains/src/configuration.rs b/runtime/parachains/src/configuration.rs index b675bf9034cb..0d6c8dfd0ab7 100644 --- a/runtime/parachains/src/configuration.rs +++ b/runtime/parachains/src/configuration.rs @@ -19,7 +19,7 @@ //! Configuration can change only at session boundaries and is buffered until then. use crate::shared; -use frame_support::pallet_prelude::*; +use frame_support::{pallet_prelude::*, weights::constants::WEIGHT_PER_MILLIS}; use frame_system::pallet_prelude::*; use parity_scale_codec::{Decode, Encode}; use primitives::v1::{Balance, SessionIndex, MAX_CODE_SIZE, MAX_POV_SIZE}; @@ -28,6 +28,8 @@ use sp_std::prelude::*; pub use pallet::*; +const LOG_TARGET: &str = "runtime::configuration"; + /// All configuration of the runtime with respect to parachains and parathreads. #[derive(Clone, Encode, Decode, PartialEq, sp_core::RuntimeDebug)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] @@ -168,6 +170,9 @@ pub struct HostConfiguration { pub needed_approvals: u32, /// The number of samples to do of the `RelayVRFModulo` approval assignment criterion. pub relay_vrf_modulo_samples: u32, + /// The maximum amount of weight any individual upward message may consume. Messages above this + /// weight go into the overweight queue and may only be serviced explicitly. + pub ump_max_individual_weight: Weight, } impl> Default for HostConfiguration { @@ -213,6 +218,11 @@ impl> Default for HostConfiguration, new: Weight) -> DispatchResult { + ensure_root(origin)?; + Self::update_config_member(|config| { + sp_std::mem::replace(&mut config.ump_max_individual_weight, new) != new + }); + Ok(()) + } } #[pallet::hooks] impl Hooks> for Pallet { + fn on_runtime_upgrade() -> Weight { + #[derive(Clone, Encode, Decode, PartialEq, sp_core::RuntimeDebug)] + #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] + struct PreMigrationHostConfiguration { + max_code_size: u32, + max_head_data_size: u32, + max_upward_queue_count: u32, + max_upward_queue_size: u32, + max_upward_message_size: u32, + max_upward_message_num_per_candidate: u32, + hrmp_max_message_num_per_candidate: u32, + validation_upgrade_frequency: BlockNumber, + validation_upgrade_delay: BlockNumber, + max_pov_size: u32, + max_downward_message_size: u32, + ump_service_total_weight: Weight, + hrmp_max_parachain_outbound_channels: u32, + hrmp_max_parathread_outbound_channels: u32, + hrmp_open_request_ttl: u32, + hrmp_sender_deposit: Balance, + hrmp_recipient_deposit: Balance, + hrmp_channel_max_capacity: u32, + hrmp_channel_max_total_size: u32, + hrmp_max_parachain_inbound_channels: u32, + hrmp_max_parathread_inbound_channels: u32, + hrmp_channel_max_message_size: u32, + code_retention_period: BlockNumber, + parathread_cores: u32, + parathread_retries: u32, + group_rotation_frequency: BlockNumber, + chain_availability_period: BlockNumber, + thread_availability_period: BlockNumber, + scheduling_lookahead: u32, + max_validators_per_core: Option, + max_validators: Option, + dispute_period: SessionIndex, + dispute_post_conclusion_acceptance_period: BlockNumber, + dispute_max_spam_slots: u32, + dispute_conclusion_by_time_out_period: BlockNumber, + no_show_slots: u32, + n_delay_tranches: u32, + zeroth_delay_tranche_width: u32, + needed_approvals: u32, + relay_vrf_modulo_samples: u32, + // the difference from `HostConfiguration` (i.e. the current version) is one field: `HostConfiguration` + // defines `ump_max_individual_weight`. + } + + // Unusual formatting is justified: + // - make it easier to verify that fields assign what they supposed to assign. + // - this code is transient and will be removed after all migrations are done. + // - this code is important enough to optimize for legibility sacrificing consistency. + #[rustfmt::skip] + let translate = |pre: PreMigrationHostConfiguration>| -> HostConfiguration> { + HostConfiguration { + +max_code_size : pre.max_code_size, +max_head_data_size : pre.max_head_data_size, +max_upward_queue_count : pre.max_upward_queue_count, +max_upward_queue_size : pre.max_upward_queue_size, +max_upward_message_size : pre.max_upward_message_size, +max_upward_message_num_per_candidate : pre.max_upward_message_num_per_candidate, +hrmp_max_message_num_per_candidate : pre.hrmp_max_message_num_per_candidate, +validation_upgrade_frequency : pre.validation_upgrade_frequency, +validation_upgrade_delay : pre.validation_upgrade_delay, +max_pov_size : pre.max_pov_size, +max_downward_message_size : pre.max_downward_message_size, +ump_service_total_weight : pre.ump_service_total_weight, +hrmp_max_parachain_outbound_channels : pre.hrmp_max_parachain_outbound_channels, +hrmp_max_parathread_outbound_channels : pre.hrmp_max_parathread_outbound_channels, +hrmp_open_request_ttl : pre.hrmp_open_request_ttl, +hrmp_sender_deposit : pre.hrmp_sender_deposit, +hrmp_recipient_deposit : pre.hrmp_recipient_deposit, +hrmp_channel_max_capacity : pre.hrmp_channel_max_capacity, +hrmp_channel_max_total_size : pre.hrmp_channel_max_total_size, +hrmp_max_parachain_inbound_channels : pre.hrmp_max_parachain_inbound_channels, +hrmp_max_parathread_inbound_channels : pre.hrmp_max_parathread_inbound_channels, +hrmp_channel_max_message_size : pre.hrmp_channel_max_message_size, +code_retention_period : pre.code_retention_period, +parathread_cores : pre.parathread_cores, +parathread_retries : pre.parathread_retries, +group_rotation_frequency : pre.group_rotation_frequency, +chain_availability_period : pre.chain_availability_period, +thread_availability_period : pre.thread_availability_period, +scheduling_lookahead : pre.scheduling_lookahead, +max_validators_per_core : pre.max_validators_per_core, +max_validators : pre.max_validators, +dispute_period : pre.dispute_period, +dispute_post_conclusion_acceptance_period: pre.dispute_post_conclusion_acceptance_period, +dispute_max_spam_slots : pre.dispute_max_spam_slots, +dispute_conclusion_by_time_out_period : pre.dispute_conclusion_by_time_out_period, +no_show_slots : pre.no_show_slots, +n_delay_tranches : pre.n_delay_tranches, +zeroth_delay_tranche_width : pre.zeroth_delay_tranche_width, +needed_approvals : pre.needed_approvals, +relay_vrf_modulo_samples : pre.relay_vrf_modulo_samples, + + // The newly added field will be fetched from the defaults. + ..Default::default() + } + }; + + if let Err(_) = ::ActiveConfig::translate(|pre| pre.map(translate)) { + // `Err` is returned when the pre-migration type cannot be deserialized. This + // cannot happen if the migration run correctly, i.e. against the expected version. + // + // This happening almost sure will lead to a panic somewhere else. Corruption seems + // to be unlikely to be caused by this. So we just log. Maybe it'll work out still? + log::error!( + target: LOG_TARGET, + "unexpected error when performing translation of the configuration type during runtime upgrade." + ); + } + + T::DbWeight::get().reads_writes(1, 1) + } + fn integrity_test() { assert_eq!( &ActiveConfig::::hashed_key(), @@ -899,6 +1036,7 @@ mod tests { hrmp_max_parachain_outbound_channels: 100, hrmp_max_parathread_outbound_channels: 200, hrmp_max_message_num_per_candidate: 20, + ump_max_individual_weight: 909, }; assert!(::PendingConfig::get(shared::SESSION_DELAY).is_none()); @@ -1065,6 +1203,11 @@ mod tests { new_config.hrmp_max_message_num_per_candidate, ) .unwrap(); + Configuration::set_ump_max_individual_weight( + Origin::root(), + new_config.ump_max_individual_weight, + ) + .unwrap(); assert_eq!( ::PendingConfig::get(shared::SESSION_DELAY), From fe3ef6b0cd768e33f90474c993a867c456462c9b Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Wed, 4 Aug 2021 16:00:33 +0000 Subject: [PATCH 02/24] Implement overweight msg stashing --- runtime/parachains/src/ump.rs | 109 +++++++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 7 deletions(-) diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index ae04d2d460df..680ea9750444 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -18,7 +18,8 @@ use crate::{ configuration::{self, HostConfiguration}, initializer, }; -use frame_support::pallet_prelude::*; +use frame_support::{pallet_prelude::*, traits::EnsureOrigin}; +use frame_system::pallet_prelude::*; use primitives::v1::{Id as ParaId, UpwardMessage}; use sp_std::{ collections::btree_map::BTreeMap, convert::TryFrom, fmt, marker::PhantomData, prelude::*, @@ -70,10 +71,18 @@ impl UmpSink for () { /// if the message content is unique. pub type MessageId = [u8; 32]; +/// Index used to identify overweight messages. +pub type OverweightIndex = u64; + /// A specific implementation of a `UmpSink` where messages are in the XCM format /// and will be forwarded to the XCM Executor. pub struct XcmSink(PhantomData<(XcmExecutor, Config)>); +/// Returns a [`MessageId`] for the given upward message payload. +fn upward_message_id(data: &[u8]) -> MessageId { + sp_io::hashing::blake2_256(data) +} + impl, C: Config> UmpSink for XcmSink { fn process_upward_message( origin: ParaId, @@ -86,7 +95,7 @@ impl, C: Config> UmpSink for XcmSi VersionedXcm, }; - let id = sp_io::hashing::blake2_256(&data[..]); + let id = upward_message_id(&data[..]); let maybe_msg = VersionedXcm::::decode_all_with_depth_limit( xcm::MAX_XCM_DECODE_DEPTH, &mut &data[..], @@ -177,6 +186,9 @@ pub mod pallet { /// /// Generally you'll want this to be a bit more - 150 or 200 would be good values. type FirstMessageFactorPercent: Get; + + /// Origin which is allowed to execute overweight messages. + type ExecuteOverweightOrigin: EnsureOrigin; } #[pallet::event] @@ -197,6 +209,26 @@ pub mod pallet { /// Some downward messages have been received and will be processed. /// \[ para, count, size \] UpwardMessagesReceived(ParaId, u32, u32), + /// The weight budget was exceeded for an individual downward message. + /// + /// This message can be later dispatched manually using `service_overweight` dispatchable + /// using the assigned `overweight_index`. + /// + /// \[ para, id, overweight_index, required \] + OverweightEnqueued(ParaId, MessageId, OverweightIndex, Weight), + /// Downward message from the overweight queue was executed with the given actual weight + /// used. + /// + /// \[ overweight_index, used \] + OverweightServiced(OverweightIndex, Weight), + } + + #[pallet::error] + pub enum Error { + /// The message index given is unknown. + Unknown, + /// The amount of weight given is possibly not enough for executing the message. + OverLimit, } /// The messages waiting to be handled by the relay-chain originating from a certain parachain. @@ -242,8 +274,48 @@ pub mod pallet { #[pallet::storage] pub type NextDispatchRoundStartWith = StorageValue<_, ParaId>; + /// The messages that exceeded max individual message weight budget. + /// + /// These messages stay there until manually dispatched. + #[pallet::storage] + pub type Overweight = + StorageMap<_, Twox64Concat, OverweightIndex, (ParaId, Vec), OptionQuery>; + + /// The number of overweight messages ever recorded in `Overweight` (and thus the lowest free + /// index). + #[pallet::storage] + pub type OverweightCount = StorageValue<_, OverweightIndex, ValueQuery>; + #[pallet::call] - impl Pallet {} + impl Pallet { + /// Service a single overweight upward message. + /// + /// - `origin`: Must pass `ExecuteOverweightOrigin`. + /// - `index`: The index of the overweight message to service. + /// - `weight_limit`: The amount of weight that message execution may take. + /// + /// Errors: + /// - `Unknown`: Message of `index` is unknown. + /// - `OverLimit`: Message execution may use greater than `weight_limit`. + /// + /// Events: + /// - `OverweightServiced`: On success. + #[pallet::weight(weight_limit.saturating_add(1_000_000))] + pub fn service_overweight( + origin: OriginFor, + index: OverweightIndex, + weight_limit: Weight, + ) -> DispatchResultWithPostInfo { + T::ExecuteOverweightOrigin::ensure_origin(origin)?; + + let (sender, data) = Overweight::::get(index).ok_or(Error::::Unknown)?; + let used = T::UmpSink::process_upward_message(sender, &data[..], weight_limit) + .map_err(|_| Error::::OverLimit)?; + Overweight::::remove(index); + Self::deposit_event(Event::OverweightServiced(index, used)); + Ok(Some(used.saturating_add(1_000_000)).into()) + } + } } /// Routines related to the upward message passing. @@ -413,10 +485,20 @@ impl Pallet { queue_cache.consume_front::(dispatchee) }, Err((id, required)) => { - // we process messages in order and don't drop them if we run out of weight, - // so need to break here without calling `consume_front`. - Self::deposit_event(Event::WeightExhausted(id, max_weight, required)); - break + if required > config.ump_max_individual_weight { + // overweight - add to overweight queue and continue with message + // execution consuming the message. + let index = Self::stash_overweight(dispatchee, upward_message); + Self::deposit_event(Event::OverweightEnqueued( + dispatchee, id, index, required, + )); + queue_cache.consume_front::(dispatchee) + } else { + // we process messages in order and don't drop them if we run out of weight, + // so need to break here without calling `consume_front`. + Self::deposit_event(Event::WeightExhausted(id, max_weight, required)); + break + } }, } } else { @@ -438,6 +520,19 @@ impl Pallet { weight_used } + + /// Puts a given upward message into the list of overweight messages allowing it to be executed + /// later. + fn stash_overweight(sender: ParaId, upward_message: Vec) -> OverweightIndex { + let index = ::OverweightCount::mutate(|count| { + let index = *count; + *count += 1; + index + }); + + ::Overweight::insert(index, (sender, upward_message)); + index + } } /// To avoid constant fetching, deserializing and serialization the queues are cached. From be125f3b22a73eed758e5ea91c1718300d05e555 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Wed, 4 Aug 2021 16:01:36 +0000 Subject: [PATCH 03/24] Test --- runtime/parachains/src/mock.rs | 9 +++ runtime/parachains/src/ump.rs | 112 ++++++++++++++++++++++++++++----- 2 files changed, 106 insertions(+), 15 deletions(-) diff --git a/runtime/parachains/src/mock.rs b/runtime/parachains/src/mock.rs index 88e241426d62..5cf8d6237485 100644 --- a/runtime/parachains/src/mock.rs +++ b/runtime/parachains/src/mock.rs @@ -133,6 +133,7 @@ impl crate::ump::Config for Test { type Event = Event; type UmpSink = TestUmpSink; type FirstMessageFactorPercent = FirstMessageFactorPercent; + type ExecuteOverweightOrigin = frame_system::EnsureRoot; } impl crate::hrmp::Config for Test { @@ -309,3 +310,11 @@ pub struct MockGenesisConfig { pub configuration: crate::configuration::GenesisConfig, pub paras: crate::paras::GenesisConfig, } + +pub fn assert_last_event(generic_event: Event) { + let events = frame_system::Pallet::::events(); + let system_event: ::Event = generic_event.into(); + // compare to the last event record + let frame_system::EventRecord { event, .. } = &events[events.len() - 1]; + assert_eq!(event, &system_event); +} diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index 680ea9750444..0b58c031018f 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -22,7 +22,7 @@ use frame_support::{pallet_prelude::*, traits::EnsureOrigin}; use frame_system::pallet_prelude::*; use primitives::v1::{Id as ParaId, UpwardMessage}; use sp_std::{ - collections::btree_map::BTreeMap, convert::TryFrom, fmt, marker::PhantomData, prelude::*, + collections::btree_map::BTreeMap, convert::TryFrom, fmt, marker::PhantomData, prelude::*, mem, }; use xcm::latest::Outcome; @@ -482,17 +482,19 @@ impl Pallet { match T::UmpSink::process_upward_message(dispatchee, upward_message, max_weight) { Ok(used) => { weight_used += used; - queue_cache.consume_front::(dispatchee) + queue_cache.consume_front::(dispatchee).end_of_queue }, Err((id, required)) => { if required > config.ump_max_individual_weight { // overweight - add to overweight queue and continue with message // execution consuming the message. - let index = Self::stash_overweight(dispatchee, upward_message); + let consume_result = queue_cache.consume_front::(dispatchee); + let index = Self::stash_overweight(dispatchee, consume_result.upward_message + .expect("`consume_front` should return the same msg as `peek_front`; if we get into this branch then `peek_front` returned `Some`; thus `upward_message` cannot be `None`; qed")); Self::deposit_event(Event::OverweightEnqueued( dispatchee, id, index, required, )); - queue_cache.consume_front::(dispatchee) + consume_result.end_of_queue } else { // we process messages in order and don't drop them if we run out of weight, // so need to break here without calling `consume_front`. @@ -562,6 +564,11 @@ struct QueueCacheEntry { consumed_size: usize, } +struct ConsumeFrontResult { + end_of_queue: bool, + upward_message: Option, +} + impl QueueCache { fn new() -> Self { Self(BTreeMap::new()) @@ -575,9 +582,6 @@ impl QueueCache { }) } - /// Returns the message at the front of `para`'s queue, or `None` if the queue is empty. - /// - /// Does not mutate the queue. fn peek_front(&mut self, para: ParaId) -> Option<&UpwardMessage> { let entry = self.ensure_cached::(para); entry.queue.get(entry.consumed_count) @@ -586,16 +590,25 @@ impl QueueCache { /// Attempts to remove one message from the front of `para`'s queue. If the queue is empty, then /// does nothing. /// - /// Returns `true` iff there are no more messages in the queue after the removal attempt. - fn consume_front(&mut self, para: ParaId) -> bool { + /// Returns `Some` if the queue is not empty. + fn consume_front(&mut self, para: ParaId) -> ConsumeFrontResult { let cache_entry = self.ensure_cached::(para); - let upward_message = cache_entry.queue.get(cache_entry.consumed_count); + + let upward_message = cache_entry.queue.get_mut(cache_entry.consumed_count); if let Some(msg) = upward_message { cache_entry.consumed_count += 1; cache_entry.consumed_size += msg.len(); - } - cache_entry.consumed_count >= cache_entry.queue.len() + ConsumeFrontResult { + upward_message: Some(mem::take(msg)), + end_of_queue: cache_entry.consumed_count >= cache_entry.queue.len(), + } + } else { + ConsumeFrontResult { + upward_message: None, + end_of_queue: true, + } + } } /// Flushes the updated queues into the storage. @@ -695,8 +708,8 @@ impl NeedsDispatchCursor { #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::mock::{new_test_ext, take_processed, Configuration, MockGenesisConfig, Ump}; - use frame_support::weights::Weight; + use crate::mock::{new_test_ext, take_processed, assert_last_event, Configuration, System, MockGenesisConfig, Ump, Test, Origin}; + use frame_support::{assert_noop, assert_ok, weights::Weight}; use std::collections::HashSet; struct GenesisConfigBuilder { @@ -705,6 +718,7 @@ pub(crate) mod tests { max_upward_queue_count: u32, max_upward_queue_size: u32, ump_service_total_weight: Weight, + ump_max_individual_weight: Weight, } impl Default for GenesisConfigBuilder { @@ -715,6 +729,7 @@ pub(crate) mod tests { max_upward_queue_count: 4, max_upward_queue_size: 64, ump_service_total_weight: 1000, + ump_max_individual_weight: 100, } } } @@ -729,6 +744,7 @@ pub(crate) mod tests { config.max_upward_queue_count = self.max_upward_queue_count; config.max_upward_queue_size = self.max_upward_queue_size; config.ump_service_total_weight = self.ump_service_total_weight; + config.ump_max_individual_weight = self.ump_max_individual_weight; genesis } } @@ -873,7 +889,7 @@ pub(crate) mod tests { let a_msg_2 = (300u32, "a_msg_2").encode(); new_test_ext( - GenesisConfigBuilder { ump_service_total_weight: 500, ..Default::default() }.build(), + GenesisConfigBuilder { ump_service_total_weight: 500, ump_max_individual_weight: 300, ..Default::default() }.build(), ) .execute_with(|| { queue_upward_msg(a, a_msg_1.clone()); @@ -951,4 +967,70 @@ pub(crate) mod tests { assert_eq!(size, 3); }); } + + #[test] + fn service_overweight_unknown() { + // This test just makes sure that 0 is not a valid index and we can use it not worrying in + // the next test. + new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { + assert_noop!(Ump::service_overweight(Origin::root(), 0, 1000), Error::::Unknown); + }); + } + + #[test] + fn overweight_queue_works() { + let para_a = ParaId::from(2021); + + let a_msg_1 = (301u32, "a_msg_1").encode(); + let a_msg_2 = (500u32, "a_msg_2").encode(); + let a_msg_3 = (500u32, "a_msg_3").encode(); + + new_test_ext( + GenesisConfigBuilder { + ump_service_total_weight: 900, + ump_max_individual_weight: 300, + ..Default::default() + } + .build(), + ) + .execute_with(|| { + // HACK: Start with the block number 1. This is needed because should an event be + // emitted during the genesis block they will be implicitly wiped. + System::set_block_number(1); + + + // This one is overweight. However, the weight is plenty and we can afford to execute + // this message, thus expect it. + queue_upward_msg(para_a, a_msg_1.clone()); + Ump::process_pending_upward_messages(); + assert_eq!(take_processed(), vec![(para_a, a_msg_1)]); + + // This is overweight and this message cannot fit into the total weight budget. + queue_upward_msg(para_a, a_msg_2.clone()); + queue_upward_msg(para_a, a_msg_3.clone()); + Ump::process_pending_upward_messages(); + assert_last_event( + Event::OverweightEnqueued(para_a, upward_message_id(&a_msg_3[..]), 0, 500) + .into(), + ); + + // Now verify that if we wanted to service this overweight message with less than enough + // weight it will fail. + assert_noop!( + Ump::service_overweight(Origin::root(), 0, 499), + Error::::OverLimit + ); + + // ... and if we try to service it with just enough weight it will succeed as well. + assert_ok!(Ump::service_overweight(Origin::root(), 0, 500)); + assert_last_event(Event::OverweightServiced(0, 500).into()); + + // ... and if we try to service a message with index that doesn't exist it will error + // out. + assert_noop!( + Ump::service_overweight(Origin::root(), 1, 1000), + Error::::Unknown + ); + }); + } } From 093455bee907e495bb5326115a8ed72bbe11cf83 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 5 Aug 2021 11:53:41 +0000 Subject: [PATCH 04/24] Add migration module. Also introduces a test for migration --- runtime/parachains/src/configuration.rs | 118 +------ .../parachains/src/configuration/migration.rs | 288 ++++++++++++++++++ 2 files changed, 292 insertions(+), 114 deletions(-) create mode 100644 runtime/parachains/src/configuration/migration.rs diff --git a/runtime/parachains/src/configuration.rs b/runtime/parachains/src/configuration.rs index 0d6c8dfd0ab7..c3cbf22f28c4 100644 --- a/runtime/parachains/src/configuration.rs +++ b/runtime/parachains/src/configuration.rs @@ -28,6 +28,8 @@ use sp_std::prelude::*; pub use pallet::*; +mod migration; + const LOG_TARGET: &str = "runtime::configuration"; /// All configuration of the runtime with respect to parachains and parathreads. @@ -269,6 +271,7 @@ pub mod pallet { #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] + #[pallet::storage_version(migration::STORAGE_VERSION)] pub struct Pallet(_); #[pallet::config] @@ -789,120 +792,7 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_runtime_upgrade() -> Weight { - #[derive(Clone, Encode, Decode, PartialEq, sp_core::RuntimeDebug)] - #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] - struct PreMigrationHostConfiguration { - max_code_size: u32, - max_head_data_size: u32, - max_upward_queue_count: u32, - max_upward_queue_size: u32, - max_upward_message_size: u32, - max_upward_message_num_per_candidate: u32, - hrmp_max_message_num_per_candidate: u32, - validation_upgrade_frequency: BlockNumber, - validation_upgrade_delay: BlockNumber, - max_pov_size: u32, - max_downward_message_size: u32, - ump_service_total_weight: Weight, - hrmp_max_parachain_outbound_channels: u32, - hrmp_max_parathread_outbound_channels: u32, - hrmp_open_request_ttl: u32, - hrmp_sender_deposit: Balance, - hrmp_recipient_deposit: Balance, - hrmp_channel_max_capacity: u32, - hrmp_channel_max_total_size: u32, - hrmp_max_parachain_inbound_channels: u32, - hrmp_max_parathread_inbound_channels: u32, - hrmp_channel_max_message_size: u32, - code_retention_period: BlockNumber, - parathread_cores: u32, - parathread_retries: u32, - group_rotation_frequency: BlockNumber, - chain_availability_period: BlockNumber, - thread_availability_period: BlockNumber, - scheduling_lookahead: u32, - max_validators_per_core: Option, - max_validators: Option, - dispute_period: SessionIndex, - dispute_post_conclusion_acceptance_period: BlockNumber, - dispute_max_spam_slots: u32, - dispute_conclusion_by_time_out_period: BlockNumber, - no_show_slots: u32, - n_delay_tranches: u32, - zeroth_delay_tranche_width: u32, - needed_approvals: u32, - relay_vrf_modulo_samples: u32, - // the difference from `HostConfiguration` (i.e. the current version) is one field: `HostConfiguration` - // defines `ump_max_individual_weight`. - } - - // Unusual formatting is justified: - // - make it easier to verify that fields assign what they supposed to assign. - // - this code is transient and will be removed after all migrations are done. - // - this code is important enough to optimize for legibility sacrificing consistency. - #[rustfmt::skip] - let translate = |pre: PreMigrationHostConfiguration>| -> HostConfiguration> { - HostConfiguration { - -max_code_size : pre.max_code_size, -max_head_data_size : pre.max_head_data_size, -max_upward_queue_count : pre.max_upward_queue_count, -max_upward_queue_size : pre.max_upward_queue_size, -max_upward_message_size : pre.max_upward_message_size, -max_upward_message_num_per_candidate : pre.max_upward_message_num_per_candidate, -hrmp_max_message_num_per_candidate : pre.hrmp_max_message_num_per_candidate, -validation_upgrade_frequency : pre.validation_upgrade_frequency, -validation_upgrade_delay : pre.validation_upgrade_delay, -max_pov_size : pre.max_pov_size, -max_downward_message_size : pre.max_downward_message_size, -ump_service_total_weight : pre.ump_service_total_weight, -hrmp_max_parachain_outbound_channels : pre.hrmp_max_parachain_outbound_channels, -hrmp_max_parathread_outbound_channels : pre.hrmp_max_parathread_outbound_channels, -hrmp_open_request_ttl : pre.hrmp_open_request_ttl, -hrmp_sender_deposit : pre.hrmp_sender_deposit, -hrmp_recipient_deposit : pre.hrmp_recipient_deposit, -hrmp_channel_max_capacity : pre.hrmp_channel_max_capacity, -hrmp_channel_max_total_size : pre.hrmp_channel_max_total_size, -hrmp_max_parachain_inbound_channels : pre.hrmp_max_parachain_inbound_channels, -hrmp_max_parathread_inbound_channels : pre.hrmp_max_parathread_inbound_channels, -hrmp_channel_max_message_size : pre.hrmp_channel_max_message_size, -code_retention_period : pre.code_retention_period, -parathread_cores : pre.parathread_cores, -parathread_retries : pre.parathread_retries, -group_rotation_frequency : pre.group_rotation_frequency, -chain_availability_period : pre.chain_availability_period, -thread_availability_period : pre.thread_availability_period, -scheduling_lookahead : pre.scheduling_lookahead, -max_validators_per_core : pre.max_validators_per_core, -max_validators : pre.max_validators, -dispute_period : pre.dispute_period, -dispute_post_conclusion_acceptance_period: pre.dispute_post_conclusion_acceptance_period, -dispute_max_spam_slots : pre.dispute_max_spam_slots, -dispute_conclusion_by_time_out_period : pre.dispute_conclusion_by_time_out_period, -no_show_slots : pre.no_show_slots, -n_delay_tranches : pre.n_delay_tranches, -zeroth_delay_tranche_width : pre.zeroth_delay_tranche_width, -needed_approvals : pre.needed_approvals, -relay_vrf_modulo_samples : pre.relay_vrf_modulo_samples, - - // The newly added field will be fetched from the defaults. - ..Default::default() - } - }; - - if let Err(_) = ::ActiveConfig::translate(|pre| pre.map(translate)) { - // `Err` is returned when the pre-migration type cannot be deserialized. This - // cannot happen if the migration run correctly, i.e. against the expected version. - // - // This happening almost sure will lead to a panic somewhere else. Corruption seems - // to be unlikely to be caused by this. So we just log. Maybe it'll work out still? - log::error!( - target: LOG_TARGET, - "unexpected error when performing translation of the configuration type during runtime upgrade." - ); - } - - T::DbWeight::get().reads_writes(1, 1) + migration::on_runtime_upgrade::() } fn integrity_test() { diff --git a/runtime/parachains/src/configuration/migration.rs b/runtime/parachains/src/configuration/migration.rs new file mode 100644 index 000000000000..b43cf6025e42 --- /dev/null +++ b/runtime/parachains/src/configuration/migration.rs @@ -0,0 +1,288 @@ +// Copyright 2021 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! A module that is responsible for migration of storage. + +use crate::configuration::{self, Config, Pallet, Store}; +use frame_support::{pallet_prelude::*, traits::StorageVersion, weights::Weight}; +use frame_system::pallet_prelude::BlockNumberFor; + +/// The current storage version. +pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + +/// Call this during an next runtime upgrade for this module. +pub fn on_runtime_upgrade() -> Weight { + let mut weight = 0; + + if StorageVersion::get::>() == 0 { + weight += migrate_to_v1::(); + StorageVersion::new(1).put::>(); + } + + weight +} + +mod v0 { + use super::*; + use primitives::v1::{Balance, SessionIndex}; + + #[derive(parity_scale_codec::Encode, parity_scale_codec::Decode, Debug)] + pub struct HostConfiguration { + pub max_code_size: u32, + pub max_head_data_size: u32, + pub max_upward_queue_count: u32, + pub max_upward_queue_size: u32, + pub max_upward_message_size: u32, + pub max_upward_message_num_per_candidate: u32, + pub hrmp_max_message_num_per_candidate: u32, + pub validation_upgrade_frequency: BlockNumber, + pub validation_upgrade_delay: BlockNumber, + pub max_pov_size: u32, + pub max_downward_message_size: u32, + pub ump_service_total_weight: Weight, + pub hrmp_max_parachain_outbound_channels: u32, + pub hrmp_max_parathread_outbound_channels: u32, + pub hrmp_open_request_ttl: u32, + pub hrmp_sender_deposit: Balance, + pub hrmp_recipient_deposit: Balance, + pub hrmp_channel_max_capacity: u32, + pub hrmp_channel_max_total_size: u32, + pub hrmp_max_parachain_inbound_channels: u32, + pub hrmp_max_parathread_inbound_channels: u32, + pub hrmp_channel_max_message_size: u32, + pub code_retention_period: BlockNumber, + pub parathread_cores: u32, + pub parathread_retries: u32, + pub group_rotation_frequency: BlockNumber, + pub chain_availability_period: BlockNumber, + pub thread_availability_period: BlockNumber, + pub scheduling_lookahead: u32, + pub max_validators_per_core: Option, + pub max_validators: Option, + pub dispute_period: SessionIndex, + pub dispute_post_conclusion_acceptance_period: BlockNumber, + pub dispute_max_spam_slots: u32, + pub dispute_conclusion_by_time_out_period: BlockNumber, + pub no_show_slots: u32, + pub n_delay_tranches: u32, + pub zeroth_delay_tranche_width: u32, + pub needed_approvals: u32, + pub relay_vrf_modulo_samples: u32, + } + + impl> Default for HostConfiguration { + fn default() -> Self { + HostConfiguration { + group_rotation_frequency: 1u32.into(), + chain_availability_period: 1u32.into(), + thread_availability_period: 1u32.into(), + no_show_slots: 1u32.into(), + validation_upgrade_frequency: Default::default(), + validation_upgrade_delay: Default::default(), + code_retention_period: Default::default(), + max_code_size: Default::default(), + max_pov_size: Default::default(), + max_head_data_size: Default::default(), + parathread_cores: Default::default(), + parathread_retries: Default::default(), + scheduling_lookahead: Default::default(), + max_validators_per_core: Default::default(), + max_validators: None, + dispute_period: 6, + dispute_post_conclusion_acceptance_period: 100.into(), + dispute_max_spam_slots: 2, + dispute_conclusion_by_time_out_period: 200.into(), + n_delay_tranches: Default::default(), + zeroth_delay_tranche_width: Default::default(), + needed_approvals: Default::default(), + relay_vrf_modulo_samples: Default::default(), + max_upward_queue_count: Default::default(), + max_upward_queue_size: Default::default(), + max_downward_message_size: Default::default(), + ump_service_total_weight: Default::default(), + max_upward_message_size: Default::default(), + max_upward_message_num_per_candidate: Default::default(), + hrmp_open_request_ttl: Default::default(), + hrmp_sender_deposit: Default::default(), + hrmp_recipient_deposit: Default::default(), + hrmp_channel_max_capacity: Default::default(), + hrmp_channel_max_total_size: Default::default(), + hrmp_max_parachain_inbound_channels: Default::default(), + hrmp_max_parathread_inbound_channels: Default::default(), + hrmp_channel_max_message_size: Default::default(), + hrmp_max_parachain_outbound_channels: Default::default(), + hrmp_max_parathread_outbound_channels: Default::default(), + hrmp_max_message_num_per_candidate: Default::default(), + } + } + } +} + +fn migrate_to_v1() -> Weight { + // Unusual formatting is justified: + // - make it easier to verify that fields assign what they supposed to assign. + // - this code is transient and will be removed after all migrations are done. + // - this code is important enough to optimize for legibility sacrificing consistency. + #[rustfmt::skip] + let translate = + |pre: v0::HostConfiguration>| -> configuration::HostConfiguration> + { + super::HostConfiguration { + +max_code_size : pre.max_code_size, +max_head_data_size : pre.max_head_data_size, +max_upward_queue_count : pre.max_upward_queue_count, +max_upward_queue_size : pre.max_upward_queue_size, +max_upward_message_size : pre.max_upward_message_size, +max_upward_message_num_per_candidate : pre.max_upward_message_num_per_candidate, +hrmp_max_message_num_per_candidate : pre.hrmp_max_message_num_per_candidate, +validation_upgrade_frequency : pre.validation_upgrade_frequency, +validation_upgrade_delay : pre.validation_upgrade_delay, +max_pov_size : pre.max_pov_size, +max_downward_message_size : pre.max_downward_message_size, +ump_service_total_weight : pre.ump_service_total_weight, +hrmp_max_parachain_outbound_channels : pre.hrmp_max_parachain_outbound_channels, +hrmp_max_parathread_outbound_channels : pre.hrmp_max_parathread_outbound_channels, +hrmp_open_request_ttl : pre.hrmp_open_request_ttl, +hrmp_sender_deposit : pre.hrmp_sender_deposit, +hrmp_recipient_deposit : pre.hrmp_recipient_deposit, +hrmp_channel_max_capacity : pre.hrmp_channel_max_capacity, +hrmp_channel_max_total_size : pre.hrmp_channel_max_total_size, +hrmp_max_parachain_inbound_channels : pre.hrmp_max_parachain_inbound_channels, +hrmp_max_parathread_inbound_channels : pre.hrmp_max_parathread_inbound_channels, +hrmp_channel_max_message_size : pre.hrmp_channel_max_message_size, +code_retention_period : pre.code_retention_period, +parathread_cores : pre.parathread_cores, +parathread_retries : pre.parathread_retries, +group_rotation_frequency : pre.group_rotation_frequency, +chain_availability_period : pre.chain_availability_period, +thread_availability_period : pre.thread_availability_period, +scheduling_lookahead : pre.scheduling_lookahead, +max_validators_per_core : pre.max_validators_per_core, +max_validators : pre.max_validators, +dispute_period : pre.dispute_period, +dispute_post_conclusion_acceptance_period: pre.dispute_post_conclusion_acceptance_period, +dispute_max_spam_slots : pre.dispute_max_spam_slots, +dispute_conclusion_by_time_out_period : pre.dispute_conclusion_by_time_out_period, +no_show_slots : pre.no_show_slots, +n_delay_tranches : pre.n_delay_tranches, +zeroth_delay_tranche_width : pre.zeroth_delay_tranche_width, +needed_approvals : pre.needed_approvals, +relay_vrf_modulo_samples : pre.relay_vrf_modulo_samples, + +ump_max_individual_weight: >>::default().ump_max_individual_weight, + } + }; + + if let Err(_) = as Store>::ActiveConfig::translate(|pre| pre.map(translate)) { + // `Err` is returned when the pre-migration type cannot be deserialized. This + // cannot happen if the migration run correctly, i.e. against the expected version. + // + // This happening almost sure will lead to a panic somewhere else. Corruption seems + // to be unlikely to be caused by this. So we just log. Maybe it'll work out still? + log::error!( + target: configuration::LOG_TARGET, + "unexpected error when performing translation of the configuration type during storage upgrade to v1." + ); + } + + T::DbWeight::get().reads_writes(1, 1) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::mock::{new_test_ext, Test}; + + #[test] + fn test_migrate_to_v1() { + // Host configuration has lots of fields. However, in this migration we only add a single + // field. The most important part to check are a couple of the last fields. We also pick + // extra fields to check arbitrary, e.g. depending on their position (i.e. the middle) and + // also their type. + // + // We specify only the picked fields and the rest should be provided by the `Default` + // implementation. That implementation is copied over between the two types and should work + // fine. + let v0 = v0::HostConfiguration:: { + relay_vrf_modulo_samples: 0xFEEDBEEFu32, + needed_approvals: 69, + thread_availability_period: 55, + hrmp_recipient_deposit: 1337, + max_pov_size: 1111, + ..Default::default() + }; + + new_test_ext(Default::default()).execute_with(|| { + // Implant the v0 version in the state. + frame_support::storage::unhashed::put_raw( + &configuration::ActiveConfig::::hashed_key(), + &v0.encode(), + ); + + migrate_to_v1::(); + + let v1 = configuration::ActiveConfig::::get(); + + // The same motivation as for the migration code. See `migrate_to_v1`. + #[rustfmt::skip] + { + assert_eq!(v0.max_code_size , v1.max_code_size); + assert_eq!(v0.max_head_data_size , v1.max_head_data_size); + assert_eq!(v0.max_upward_queue_count , v1.max_upward_queue_count); + assert_eq!(v0.max_upward_queue_size , v1.max_upward_queue_size); + assert_eq!(v0.max_upward_message_size , v1.max_upward_message_size); + assert_eq!(v0.max_upward_message_num_per_candidate , v1.max_upward_message_num_per_candidate); + assert_eq!(v0.hrmp_max_message_num_per_candidate , v1.hrmp_max_message_num_per_candidate); + assert_eq!(v0.validation_upgrade_frequency , v1.validation_upgrade_frequency); + assert_eq!(v0.validation_upgrade_delay , v1.validation_upgrade_delay); + assert_eq!(v0.max_pov_size , v1.max_pov_size); + assert_eq!(v0.max_downward_message_size , v1.max_downward_message_size); + assert_eq!(v0.ump_service_total_weight , v1.ump_service_total_weight); + assert_eq!(v0.hrmp_max_parachain_outbound_channels , v1.hrmp_max_parachain_outbound_channels); + assert_eq!(v0.hrmp_max_parathread_outbound_channels , v1.hrmp_max_parathread_outbound_channels); + assert_eq!(v0.hrmp_open_request_ttl , v1.hrmp_open_request_ttl); + assert_eq!(v0.hrmp_sender_deposit , v1.hrmp_sender_deposit); + assert_eq!(v0.hrmp_recipient_deposit , v1.hrmp_recipient_deposit); + assert_eq!(v0.hrmp_channel_max_capacity , v1.hrmp_channel_max_capacity); + assert_eq!(v0.hrmp_channel_max_total_size , v1.hrmp_channel_max_total_size); + assert_eq!(v0.hrmp_max_parachain_inbound_channels , v1.hrmp_max_parachain_inbound_channels); + assert_eq!(v0.hrmp_max_parathread_inbound_channels , v1.hrmp_max_parathread_inbound_channels); + assert_eq!(v0.hrmp_channel_max_message_size , v1.hrmp_channel_max_message_size); + assert_eq!(v0.code_retention_period , v1.code_retention_period); + assert_eq!(v0.parathread_cores , v1.parathread_cores); + assert_eq!(v0.parathread_retries , v1.parathread_retries); + assert_eq!(v0.group_rotation_frequency , v1.group_rotation_frequency); + assert_eq!(v0.chain_availability_period , v1.chain_availability_period); + assert_eq!(v0.thread_availability_period , v1.thread_availability_period); + assert_eq!(v0.scheduling_lookahead , v1.scheduling_lookahead); + assert_eq!(v0.max_validators_per_core , v1.max_validators_per_core); + assert_eq!(v0.max_validators , v1.max_validators); + assert_eq!(v0.dispute_period , v1.dispute_period); + assert_eq!(v0.dispute_post_conclusion_acceptance_period, v1.dispute_post_conclusion_acceptance_period); + assert_eq!(v0.dispute_max_spam_slots , v1.dispute_max_spam_slots); + assert_eq!(v0.dispute_conclusion_by_time_out_period , v1.dispute_conclusion_by_time_out_period); + assert_eq!(v0.no_show_slots , v1.no_show_slots); + assert_eq!(v0.n_delay_tranches , v1.n_delay_tranches); + assert_eq!(v0.zeroth_delay_tranche_width , v1.zeroth_delay_tranche_width); + assert_eq!(v0.needed_approvals , v1.needed_approvals); + assert_eq!(v0.relay_vrf_modulo_samples , v1.relay_vrf_modulo_samples); + + assert_eq!(v1.ump_max_individual_weight, 10_000_000_000); + }; // ; makes this a statement. `rustfmt::skip` cannot be put on an expression. + }); + } +} From 35deb5cdb7ff3ef893a9c5ff5dd0c2a9bf3d2a37 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 5 Aug 2021 12:07:50 +0000 Subject: [PATCH 05/24] Integrate ExecuteOverweightOrigin to runtimes --- runtime/kusama/src/lib.rs | 1 + runtime/rococo/src/lib.rs | 1 + runtime/test-runtime/src/lib.rs | 1 + runtime/westend/src/lib.rs | 1 + 4 files changed, 4 insertions(+) diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index 23a45a675cd5..80aadabf91dd 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -1117,6 +1117,7 @@ impl parachains_ump::Config for Runtime { type Event = Event; type UmpSink = crate::parachains_ump::XcmSink, Runtime>; type FirstMessageFactorPercent = FirstMessageFactorPercent; + type ExecuteOverweightOrigin = EnsureRoot; } impl parachains_dmp::Config for Runtime {} diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index de9e65eb0584..278e2ece0a3e 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -715,6 +715,7 @@ impl parachains_ump::Config for Runtime { type Event = Event; type UmpSink = crate::parachains_ump::XcmSink, Runtime>; type FirstMessageFactorPercent = FirstMessageFactorPercent; + type ExecuteOverweightOrigin = EnsureRoot; } impl parachains_dmp::Config for Runtime {} diff --git a/runtime/test-runtime/src/lib.rs b/runtime/test-runtime/src/lib.rs index a82836deefaa..c2d80196c3c8 100644 --- a/runtime/test-runtime/src/lib.rs +++ b/runtime/test-runtime/src/lib.rs @@ -493,6 +493,7 @@ impl parachains_ump::Config for Runtime { type Event = Event; type UmpSink = (); type FirstMessageFactorPercent = FirstMessageFactorPercent; + type ExecuteOverweightOrigin = EnsureRoot; } parameter_types! { diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index bc494ae9440f..2b4f24a87988 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -786,6 +786,7 @@ impl parachains_ump::Config for Runtime { type Event = Event; type UmpSink = crate::parachains_ump::XcmSink, Runtime>; type FirstMessageFactorPercent = FirstMessageFactorPercent; + type ExecuteOverweightOrigin = EnsureRoot; } impl parachains_dmp::Config for Runtime {} From be55e53b0c546624bb384795d91b4c9b39a7b6ed Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 5 Aug 2021 12:30:52 +0000 Subject: [PATCH 06/24] Fix more stuff --- runtime/test-runtime/src/lib.rs | 2 +- xcm/xcm-simulator/example/src/relay_chain.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/test-runtime/src/lib.rs b/runtime/test-runtime/src/lib.rs index c2d80196c3c8..e268c7e1fffc 100644 --- a/runtime/test-runtime/src/lib.rs +++ b/runtime/test-runtime/src/lib.rs @@ -493,7 +493,7 @@ impl parachains_ump::Config for Runtime { type Event = Event; type UmpSink = (); type FirstMessageFactorPercent = FirstMessageFactorPercent; - type ExecuteOverweightOrigin = EnsureRoot; + type ExecuteOverweightOrigin = frame_system::EnsureRoot; } parameter_types! { diff --git a/xcm/xcm-simulator/example/src/relay_chain.rs b/xcm/xcm-simulator/example/src/relay_chain.rs index 3b27d800a510..a6f6f1989174 100644 --- a/xcm/xcm-simulator/example/src/relay_chain.rs +++ b/xcm/xcm-simulator/example/src/relay_chain.rs @@ -166,6 +166,7 @@ impl ump::Config for Runtime { type Event = Event; type UmpSink = ump::XcmSink, Runtime>; type FirstMessageFactorPercent = FirstMessageFactorPercent; + type ExecuteOverweightOrigin = frame_system::EnsureRoot; } impl origin::Config for Runtime {} From 5a4de33829e2882607a38cb8a3b6336794d80674 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 5 Aug 2021 12:59:16 +0000 Subject: [PATCH 07/24] Add `yeet` into dictionary --- scripts/gitlab/lingua.dic | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/gitlab/lingua.dic b/scripts/gitlab/lingua.dic index 0dda104ca7ab..7d2a0b8e297d 100644 --- a/scripts/gitlab/lingua.dic +++ b/scripts/gitlab/lingua.dic @@ -292,3 +292,4 @@ WND/S Wococo XCM/S XCMP/M +yeet From 52f65dacf0f162abdeb4d8795d55023ae4f27a29 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Wed, 1 Sep 2021 11:41:46 +0000 Subject: [PATCH 08/24] Use suggested `Error` variant names --- runtime/parachains/src/ump.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index 0b58c031018f..0e9f20999fa8 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -226,9 +226,9 @@ pub mod pallet { #[pallet::error] pub enum Error { /// The message index given is unknown. - Unknown, + UnknownMessageIndex, /// The amount of weight given is possibly not enough for executing the message. - OverLimit, + WeightOverLimit, } /// The messages waiting to be handled by the relay-chain originating from a certain parachain. @@ -295,8 +295,8 @@ pub mod pallet { /// - `weight_limit`: The amount of weight that message execution may take. /// /// Errors: - /// - `Unknown`: Message of `index` is unknown. - /// - `OverLimit`: Message execution may use greater than `weight_limit`. + /// - `UnknownMessageIndex`: Message of `index` is unknown. + /// - `WeightOverLimit`: Message execution may use greater than `weight_limit`. /// /// Events: /// - `OverweightServiced`: On success. @@ -308,9 +308,10 @@ pub mod pallet { ) -> DispatchResultWithPostInfo { T::ExecuteOverweightOrigin::ensure_origin(origin)?; - let (sender, data) = Overweight::::get(index).ok_or(Error::::Unknown)?; + let (sender, data) = + Overweight::::get(index).ok_or(Error::::UnknownMessageIndex)?; let used = T::UmpSink::process_upward_message(sender, &data[..], weight_limit) - .map_err(|_| Error::::OverLimit)?; + .map_err(|_| Error::::WeightOverLimit)?; Overweight::::remove(index); Self::deposit_event(Event::OverweightServiced(index, used)); Ok(Some(used.saturating_add(1_000_000)).into()) @@ -973,7 +974,10 @@ pub(crate) mod tests { // This test just makes sure that 0 is not a valid index and we can use it not worrying in // the next test. new_test_ext(GenesisConfigBuilder::default().build()).execute_with(|| { - assert_noop!(Ump::service_overweight(Origin::root(), 0, 1000), Error::::Unknown); + assert_noop!( + Ump::service_overweight(Origin::root(), 0, 1000), + Error::::UnknownMessageIndex + ); }); } @@ -1018,7 +1022,7 @@ pub(crate) mod tests { // weight it will fail. assert_noop!( Ump::service_overweight(Origin::root(), 0, 499), - Error::::OverLimit + Error::::WeightOverLimit ); // ... and if we try to service it with just enough weight it will succeed as well. @@ -1029,7 +1033,7 @@ pub(crate) mod tests { // out. assert_noop!( Ump::service_overweight(Origin::root(), 1, 1000), - Error::::Unknown + Error::::UnknownMessageIndex ); }); } From bb1721dc9693f71cdb53e38de1dbe314d8fb5aa2 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Wed, 1 Sep 2021 11:42:39 +0000 Subject: [PATCH 09/24] typo --- runtime/parachains/src/configuration/migration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/parachains/src/configuration/migration.rs b/runtime/parachains/src/configuration/migration.rs index b43cf6025e42..928b4bf055a6 100644 --- a/runtime/parachains/src/configuration/migration.rs +++ b/runtime/parachains/src/configuration/migration.rs @@ -211,7 +211,7 @@ mod tests { fn test_migrate_to_v1() { // Host configuration has lots of fields. However, in this migration we only add a single // field. The most important part to check are a couple of the last fields. We also pick - // extra fields to check arbitrary, e.g. depending on their position (i.e. the middle) and + // extra fields to check arbitrarily, e.g. depending on their position (i.e. the middle) and // also their type. // // We specify only the picked fields and the rest should be provided by the `Default` From 88f458f0959159b43700ee1011a1c2dfd44532df Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Wed, 1 Sep 2021 11:44:23 +0000 Subject: [PATCH 10/24] Use 20ms as the maximum individual message weight --- runtime/parachains/src/configuration.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/runtime/parachains/src/configuration.rs b/runtime/parachains/src/configuration.rs index c3cbf22f28c4..f6c1a3749dc2 100644 --- a/runtime/parachains/src/configuration.rs +++ b/runtime/parachains/src/configuration.rs @@ -220,11 +220,7 @@ impl> Default for HostConfiguration Date: Wed, 1 Sep 2021 12:07:07 +0000 Subject: [PATCH 11/24] Update the test value --- runtime/parachains/src/configuration/migration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/parachains/src/configuration/migration.rs b/runtime/parachains/src/configuration/migration.rs index 928b4bf055a6..9eb5705cf84d 100644 --- a/runtime/parachains/src/configuration/migration.rs +++ b/runtime/parachains/src/configuration/migration.rs @@ -281,7 +281,7 @@ mod tests { assert_eq!(v0.needed_approvals , v1.needed_approvals); assert_eq!(v0.relay_vrf_modulo_samples , v1.relay_vrf_modulo_samples); - assert_eq!(v1.ump_max_individual_weight, 10_000_000_000); + assert_eq!(v1.ump_max_individual_weight, 20_000_000_000); }; // ; makes this a statement. `rustfmt::skip` cannot be put on an expression. }); } From 14bf5bab21a78d1d80f57b26c1402e94475e749c Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 9 Sep 2021 11:18:14 +0000 Subject: [PATCH 12/24] rustfmt --- runtime/parachains/src/ump.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index 0e9f20999fa8..a442e13f335d 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -22,7 +22,7 @@ use frame_support::{pallet_prelude::*, traits::EnsureOrigin}; use frame_system::pallet_prelude::*; use primitives::v1::{Id as ParaId, UpwardMessage}; use sp_std::{ - collections::btree_map::BTreeMap, convert::TryFrom, fmt, marker::PhantomData, prelude::*, mem, + collections::btree_map::BTreeMap, convert::TryFrom, fmt, marker::PhantomData, mem, prelude::*, }; use xcm::latest::Outcome; @@ -605,10 +605,7 @@ impl QueueCache { end_of_queue: cache_entry.consumed_count >= cache_entry.queue.len(), } } else { - ConsumeFrontResult { - upward_message: None, - end_of_queue: true, - } + ConsumeFrontResult { upward_message: None, end_of_queue: true } } } @@ -709,7 +706,10 @@ impl NeedsDispatchCursor { #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::mock::{new_test_ext, take_processed, assert_last_event, Configuration, System, MockGenesisConfig, Ump, Test, Origin}; + use crate::mock::{ + assert_last_event, new_test_ext, take_processed, Configuration, MockGenesisConfig, Origin, + System, Test, Ump, + }; use frame_support::{assert_noop, assert_ok, weights::Weight}; use std::collections::HashSet; @@ -890,7 +890,12 @@ pub(crate) mod tests { let a_msg_2 = (300u32, "a_msg_2").encode(); new_test_ext( - GenesisConfigBuilder { ump_service_total_weight: 500, ump_max_individual_weight: 300, ..Default::default() }.build(), + GenesisConfigBuilder { + ump_service_total_weight: 500, + ump_max_individual_weight: 300, + ..Default::default() + } + .build(), ) .execute_with(|| { queue_upward_msg(a, a_msg_1.clone()); @@ -1002,7 +1007,6 @@ pub(crate) mod tests { // emitted during the genesis block they will be implicitly wiped. System::set_block_number(1); - // This one is overweight. However, the weight is plenty and we can afford to execute // this message, thus expect it. queue_upward_msg(para_a, a_msg_1.clone()); @@ -1014,8 +1018,7 @@ pub(crate) mod tests { queue_upward_msg(para_a, a_msg_3.clone()); Ump::process_pending_upward_messages(); assert_last_event( - Event::OverweightEnqueued(para_a, upward_message_id(&a_msg_3[..]), 0, 500) - .into(), + Event::OverweightEnqueued(para_a, upward_message_id(&a_msg_3[..]), 0, 500).into(), ); // Now verify that if we wanted to service this overweight message with less than enough From 5346161e1f7f8560f57d8aeeef7691137a284284 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 9 Sep 2021 11:36:37 +0000 Subject: [PATCH 13/24] Clean up --- runtime/parachains/src/ump.rs | 61 ++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index a442e13f335d..fc1c8fe8bc76 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -479,23 +479,25 @@ impl Pallet { // attempt to process the next message from the queue of the dispatchee; if not beyond // our remaining weight limit, then consume it. let maybe_next = queue_cache.peek_front::(dispatchee); - let became_empty = if let Some(upward_message) = maybe_next { + if let Some(upward_message) = maybe_next { match T::UmpSink::process_upward_message(dispatchee, upward_message, max_weight) { Ok(used) => { weight_used += used; - queue_cache.consume_front::(dispatchee).end_of_queue + let _ = queue_cache.consume_front::(dispatchee); }, Err((id, required)) => { if required > config.ump_max_individual_weight { // overweight - add to overweight queue and continue with message // execution consuming the message. - let consume_result = queue_cache.consume_front::(dispatchee); - let index = Self::stash_overweight(dispatchee, consume_result.upward_message - .expect("`consume_front` should return the same msg as `peek_front`; if we get into this branch then `peek_front` returned `Some`; thus `upward_message` cannot be `None`; qed")); + let upward_message = queue_cache.consume_front::(dispatchee).expect( + "`consume_front` should return the same msg as `peek_front`;\ + if we get into this branch then `peek_front` returned `Some`;\ + thus `upward_message` cannot be `None`; qed", + ); + let index = Self::stash_overweight(dispatchee, upward_message); Self::deposit_event(Event::OverweightEnqueued( dispatchee, id, index, required, )); - consume_result.end_of_queue } else { // we process messages in order and don't drop them if we run out of weight, // so need to break here without calling `consume_front`. @@ -504,13 +506,9 @@ impl Pallet { } }, } - } else { - // this should never happen, since the cursor should never point to an empty queue. - // it is resolved harmlessly here anyway. - true - }; + } - if became_empty { + if queue_cache.is_empty::(dispatchee) { // the queue is empty now - this para doesn't need attention anymore. cursor.remove(); } else { @@ -565,11 +563,6 @@ struct QueueCacheEntry { consumed_size: usize, } -struct ConsumeFrontResult { - end_of_queue: bool, - upward_message: Option, -} - impl QueueCache { fn new() -> Self { Self(BTreeMap::new()) @@ -583,6 +576,9 @@ impl QueueCache { }) } + /// Returns the message at the front of `para`'s queue, or `None` if the queue is empty. + /// + /// Does not mutate the queue. fn peek_front(&mut self, para: ParaId) -> Option<&UpwardMessage> { let entry = self.ensure_cached::(para); entry.queue.get(entry.consumed_count) @@ -590,25 +586,30 @@ impl QueueCache { /// Attempts to remove one message from the front of `para`'s queue. If the queue is empty, then /// does nothing. - /// - /// Returns `Some` if the queue is not empty. - fn consume_front(&mut self, para: ParaId) -> ConsumeFrontResult { + fn consume_front(&mut self, para: ParaId) -> Option { let cache_entry = self.ensure_cached::(para); - let upward_message = cache_entry.queue.get_mut(cache_entry.consumed_count); - if let Some(msg) = upward_message { - cache_entry.consumed_count += 1; - cache_entry.consumed_size += msg.len(); + match cache_entry.queue.get_mut(cache_entry.consumed_count) { + Some(msg) => { + cache_entry.consumed_count += 1; + cache_entry.consumed_size += msg.len(); - ConsumeFrontResult { - upward_message: Some(mem::take(msg)), - end_of_queue: cache_entry.consumed_count >= cache_entry.queue.len(), - } - } else { - ConsumeFrontResult { upward_message: None, end_of_queue: true } + Some(mem::take(msg)) + }, + None => None, } } + /// Returns if the queue for the given para is empty. + /// + /// That is, if returned `true` then next call to [`peek_front`] will return `None`. + /// + /// Does not mutate the queue. + fn is_empty(&mut self, para: ParaId) -> bool { + let cache_entry = self.ensure_cached::(para); + cache_entry.consumed_count >= cache_entry.queue.len() + } + /// Flushes the updated queues into the storage. fn flush(self) { // NOTE we use an explicit method here instead of Drop impl because it has unwanted semantics From 5b77e2fd7714d5e9368f278c311dc0650551853d Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Thu, 9 Sep 2021 12:14:49 +0000 Subject: [PATCH 14/24] Remove deprecated field from host config --- runtime/parachains/src/configuration.rs | 6 ------ runtime/parachains/src/configuration/migration.rs | 4 ---- 2 files changed, 10 deletions(-) diff --git a/runtime/parachains/src/configuration.rs b/runtime/parachains/src/configuration.rs index d21288c01388..d749c2d00aaf 100644 --- a/runtime/parachains/src/configuration.rs +++ b/runtime/parachains/src/configuration.rs @@ -95,10 +95,6 @@ pub struct HostConfiguration { pub hrmp_max_parachain_outbound_channels: u32, /// The maximum number of outbound HRMP channels a parathread is allowed to open. pub hrmp_max_parathread_outbound_channels: u32, - /// NOTE: this field is deprecated. Channel open requests became non-expiring. Changing this value - /// doesn't have any effect. This field doesn't have a `deprecated` attribute because that would - /// trigger warnings coming from macros. - pub _hrmp_open_request_ttl: u32, /// The deposit that the sender should provide for opening an HRMP channel. pub hrmp_sender_deposit: Balance, /// The deposit that the recipient should provide for accepting opening an HRMP channel. @@ -211,7 +207,6 @@ impl> Default for HostConfiguration Date: Thu, 9 Sep 2021 15:59:45 +0000 Subject: [PATCH 15/24] Remove missed _hrmp_open_request_ttl --- node/service/src/chain_spec.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/node/service/src/chain_spec.rs b/node/service/src/chain_spec.rs index e2ed37334aaa..42f1592af07f 100644 --- a/node/service/src/chain_spec.rs +++ b/node/service/src/chain_spec.rs @@ -174,7 +174,6 @@ fn default_parachains_host_configuration( ump_service_total_weight: 4 * 1_000_000_000, max_upward_message_size: 1024 * 1024, max_upward_message_num_per_candidate: 5, - _hrmp_open_request_ttl: 5, hrmp_sender_deposit: 0, hrmp_recipient_deposit: 0, hrmp_channel_max_capacity: 8, From f75e7a87e3ed2b58414386a4510f74a48a0dca10 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Mon, 13 Sep 2021 14:18:31 +0200 Subject: [PATCH 16/24] Apply typo fix suggestion Co-authored-by: Alexander Popiak --- runtime/parachains/src/configuration/migration.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/parachains/src/configuration/migration.rs b/runtime/parachains/src/configuration/migration.rs index 0d0ff659752e..0368ffd77976 100644 --- a/runtime/parachains/src/configuration/migration.rs +++ b/runtime/parachains/src/configuration/migration.rs @@ -186,9 +186,9 @@ ump_max_individual_weight: >> if let Err(_) = as Store>::ActiveConfig::translate(|pre| pre.map(translate)) { // `Err` is returned when the pre-migration type cannot be deserialized. This - // cannot happen if the migration run correctly, i.e. against the expected version. + // cannot happen if the migration runs correctly, i.e. against the expected version. // - // This happening almost sure will lead to a panic somewhere else. Corruption seems + // This happening almost surely will lead to a panic somewhere else. Corruption seems // to be unlikely to be caused by this. So we just log. Maybe it'll work out still? log::error!( target: configuration::LOG_TARGET, From 56f9a04a5dd7bc42233a2db49966be14dc86ef8c Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Mon, 13 Sep 2021 12:17:10 +0000 Subject: [PATCH 17/24] Rename `migration::migrate_to_latest` --- runtime/parachains/src/configuration.rs | 2 +- runtime/parachains/src/configuration/migration.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/parachains/src/configuration.rs b/runtime/parachains/src/configuration.rs index d749c2d00aaf..23fc1ea6ea35 100644 --- a/runtime/parachains/src/configuration.rs +++ b/runtime/parachains/src/configuration.rs @@ -783,7 +783,7 @@ pub mod pallet { #[pallet::hooks] impl Hooks> for Pallet { fn on_runtime_upgrade() -> Weight { - migration::on_runtime_upgrade::() + migration::migrate_to_latest::() } fn integrity_test() { diff --git a/runtime/parachains/src/configuration/migration.rs b/runtime/parachains/src/configuration/migration.rs index 0368ffd77976..6cdf05fa38c3 100644 --- a/runtime/parachains/src/configuration/migration.rs +++ b/runtime/parachains/src/configuration/migration.rs @@ -24,7 +24,7 @@ use frame_system::pallet_prelude::BlockNumberFor; pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); /// Call this during an next runtime upgrade for this module. -pub fn on_runtime_upgrade() -> Weight { +pub fn migrate_to_latest() -> Weight { let mut weight = 0; if StorageVersion::get::>() == 0 { From 7bc31f0d683333b58f0136e96cb30eedf3d00aae Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Mon, 13 Sep 2021 12:23:55 +0000 Subject: [PATCH 18/24] Restore `_hrmp_open_request_ttl` in `v0::HostConfiguration` --- runtime/parachains/src/configuration/migration.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/parachains/src/configuration/migration.rs b/runtime/parachains/src/configuration/migration.rs index 6cdf05fa38c3..8bd7d7faf3b5 100644 --- a/runtime/parachains/src/configuration/migration.rs +++ b/runtime/parachains/src/configuration/migration.rs @@ -55,6 +55,7 @@ mod v0 { pub ump_service_total_weight: Weight, pub hrmp_max_parachain_outbound_channels: u32, pub hrmp_max_parathread_outbound_channels: u32, + pub _hrmp_open_request_ttl: u32, pub hrmp_sender_deposit: Balance, pub hrmp_recipient_deposit: Balance, pub hrmp_channel_max_capacity: u32, @@ -114,6 +115,7 @@ mod v0 { ump_service_total_weight: Default::default(), max_upward_message_size: Default::default(), max_upward_message_num_per_candidate: Default::default(), + _hrmp_open_request_ttl: Default::default(), hrmp_sender_deposit: Default::default(), hrmp_recipient_deposit: Default::default(), hrmp_channel_max_capacity: Default::default(), From 7236e5e27a81cfaa8c1dcabdab661487f095f9aa Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Mon, 13 Sep 2021 12:24:43 +0000 Subject: [PATCH 19/24] Apply suggestion for a rustdoc --- runtime/parachains/src/configuration/migration.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/runtime/parachains/src/configuration/migration.rs b/runtime/parachains/src/configuration/migration.rs index 8bd7d7faf3b5..d02c767aade8 100644 --- a/runtime/parachains/src/configuration/migration.rs +++ b/runtime/parachains/src/configuration/migration.rs @@ -131,6 +131,11 @@ mod v0 { } } +/// Migrates the `HostConfiguration` from v0 (with deprecated `hrmp_open_request_ttl` and without +/// `ump_max_individual_weight`) to v1 (without hrmp ttl and with max individual weight). +/// Uses the `Default` implementation of `HostConfiguration` to choose a value for `ump_max_individual_weight`. +/// +/// NOTE: Only use this function if you know what you are doing. Default to using `migrate_to_latest`. fn migrate_to_v1() -> Weight { // Unusual formatting is justified: // - make it easier to verify that fields assign what they supposed to assign. From 27a6a116efbc53de50b005892a0cfe96de674476 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Mon, 13 Sep 2021 12:26:09 +0000 Subject: [PATCH 20/24] Apply the suggestion --- runtime/parachains/src/configuration/migration.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/parachains/src/configuration/migration.rs b/runtime/parachains/src/configuration/migration.rs index d02c767aade8..b891632bc0fc 100644 --- a/runtime/parachains/src/configuration/migration.rs +++ b/runtime/parachains/src/configuration/migration.rs @@ -23,7 +23,7 @@ use frame_system::pallet_prelude::BlockNumberFor; /// The current storage version. pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); -/// Call this during an next runtime upgrade for this module. +/// Migrates the pallet storage to the most recent version, checking and setting the `StorageVersion`. pub fn migrate_to_latest() -> Weight { let mut weight = 0; From 45295caf84ed343d47b92e7b798249d7228190e5 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Mon, 13 Sep 2021 12:53:22 +0000 Subject: [PATCH 21/24] Test v0 config with the raw production data fetched from Kusama --- .../parachains/src/configuration/migration.rs | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/runtime/parachains/src/configuration/migration.rs b/runtime/parachains/src/configuration/migration.rs index b891632bc0fc..151621c827f4 100644 --- a/runtime/parachains/src/configuration/migration.rs +++ b/runtime/parachains/src/configuration/migration.rs @@ -211,9 +211,32 @@ mod tests { use super::*; use crate::mock::{new_test_ext, Test}; + #[test] + fn v0_deserialized_from_actual_data() { + // Fetched at Kusama 9,207,703 (0xbfe5227324c08b3ab67e0473a360acbce43efbd7b42041d0033adaf9ff2c5330) + // + // This exceeds the maximal line width length, but that's fine, since this is not code and + // doesn't need to be read and also leaving it as one line allows to easily copy it. + let raw_config = hex_literal::hex!["0000a000005000000a00000000c8000000c800000a0000000a00000040380000580200000000500000c8000000e87648170000000a0000000000000048000000c09e5d9a2f3d00000000000000000000c09e5d9a2f3d00000000000000000000e8030000009001000a00000000000000009001008070000000000000000000000a0000000a0000000a00000001000000010500000001c8000000060000005802000002000000580200000200000059000000000000001e00000028000000"]; + + let v0 = v0::HostConfiguration::::decode(&mut &raw_config[..]) + .unwrap(); + + // We check only a sample of the values here. If we missed any fields or messed up data types + // that would skew all the fields coming after. + assert_eq!(v0.max_code_size, 10_485_760); + assert_eq!(v0.validation_upgrade_frequency, 14_400); + assert_eq!(v0.max_pov_size, 5_242_880); + assert_eq!(v0._hrmp_open_request_ttl, 72); + assert_eq!(v0.hrmp_channel_max_message_size, 102_400); + assert_eq!(v0.dispute_max_spam_slots, 2); + assert_eq!(v0.n_delay_tranches, 89); + assert_eq!(v0.relay_vrf_modulo_samples, 40); + } + #[test] fn test_migrate_to_v1() { - // Host configuration has lots of fields. However, in this migration we only add a single + // Host configuration has lots of fields. However, in this migration we add one and remove one // field. The most important part to check are a couple of the last fields. We also pick // extra fields to check arbitrarily, e.g. depending on their position (i.e. the middle) and // also their type. From ec2a02d42c3efc8614695860849e131507f99f29 Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Mon, 13 Sep 2021 14:55:46 +0200 Subject: [PATCH 22/24] Update runtime/parachains/src/ump.rs Co-authored-by: Alexander Popiak --- runtime/parachains/src/ump.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs index fc1c8fe8bc76..a4f046024802 100644 --- a/runtime/parachains/src/ump.rs +++ b/runtime/parachains/src/ump.rs @@ -602,7 +602,7 @@ impl QueueCache { /// Returns if the queue for the given para is empty. /// - /// That is, if returned `true` then next call to [`peek_front`] will return `None`. + /// That is, if this returns `true` then the next call to [`peek_front`] will return `None`. /// /// Does not mutate the queue. fn is_empty(&mut self, para: ParaId) -> bool { From f94354661629473c4f7d15bb24e7d1a6baf679bf Mon Sep 17 00:00:00 2001 From: Sergei Shulepov Date: Mon, 13 Sep 2021 15:29:19 +0000 Subject: [PATCH 23/24] Expose migration functions --- runtime/parachains/src/configuration.rs | 2 +- runtime/parachains/src/configuration/migration.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/parachains/src/configuration.rs b/runtime/parachains/src/configuration.rs index 23fc1ea6ea35..f2de0db6aa93 100644 --- a/runtime/parachains/src/configuration.rs +++ b/runtime/parachains/src/configuration.rs @@ -28,7 +28,7 @@ use sp_std::prelude::*; pub use pallet::*; -mod migration; +pub mod migration; const LOG_TARGET: &str = "runtime::configuration"; diff --git a/runtime/parachains/src/configuration/migration.rs b/runtime/parachains/src/configuration/migration.rs index 151621c827f4..8db99af92099 100644 --- a/runtime/parachains/src/configuration/migration.rs +++ b/runtime/parachains/src/configuration/migration.rs @@ -136,7 +136,7 @@ mod v0 { /// Uses the `Default` implementation of `HostConfiguration` to choose a value for `ump_max_individual_weight`. /// /// NOTE: Only use this function if you know what you are doing. Default to using `migrate_to_latest`. -fn migrate_to_v1() -> Weight { +pub fn migrate_to_v1() -> Weight { // Unusual formatting is justified: // - make it easier to verify that fields assign what they supposed to assign. // - this code is transient and will be removed after all migrations are done. From dff100fa79bc0804e4fd34cf441e7047e5f535f7 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Wed, 15 Sep 2021 01:20:40 -0700 Subject: [PATCH 24/24] Fix spellcheck --- runtime/parachains/src/configuration/migration.rs | 2 +- scripts/gitlab/lingua.dic | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/runtime/parachains/src/configuration/migration.rs b/runtime/parachains/src/configuration/migration.rs index 8db99af92099..6909eecc15a9 100644 --- a/runtime/parachains/src/configuration/migration.rs +++ b/runtime/parachains/src/configuration/migration.rs @@ -132,7 +132,7 @@ mod v0 { } /// Migrates the `HostConfiguration` from v0 (with deprecated `hrmp_open_request_ttl` and without -/// `ump_max_individual_weight`) to v1 (without hrmp ttl and with max individual weight). +/// `ump_max_individual_weight`) to v1 (without HRMP TTL and with max individual weight). /// Uses the `Default` implementation of `HostConfiguration` to choose a value for `ump_max_individual_weight`. /// /// NOTE: Only use this function if you know what you are doing. Default to using `migrate_to_latest`. diff --git a/scripts/gitlab/lingua.dic b/scripts/gitlab/lingua.dic index 77606e63f1f7..592dee567f72 100644 --- a/scripts/gitlab/lingua.dic +++ b/scripts/gitlab/lingua.dic @@ -249,6 +249,7 @@ timestamp/MS transitionary trie/MS trustless/Y +TTL tuple/SM typesystem ubuntu/M