diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs index 4f5af16ccf..7be232eeb5 100644 --- a/polkadot/runtime/common/src/integration_tests.rs +++ b/polkadot/runtime/common/src/integration_tests.rs @@ -65,7 +65,7 @@ frame_support::construct_runtime!( // Parachains Runtime Configuration: configuration::{Pallet, Call, Storage, Config}, - Paras: paras::{Pallet, Origin, Call, Storage, Config}, + Paras: paras::{Pallet, Origin, Call, Storage, Event, Config}, // Para Onboarding Pallets Registrar: paras_registrar::{Pallet, Call, Storage, Event}, @@ -161,6 +161,7 @@ impl shared::Config for Test { } impl paras::Config for Test { type Origin = Origin; + type Event = Event; } parameter_types! { diff --git a/polkadot/runtime/common/src/paras_registrar.rs b/polkadot/runtime/common/src/paras_registrar.rs index 9e49ce8ec5..6ce22cd4ba 100644 --- a/polkadot/runtime/common/src/paras_registrar.rs +++ b/polkadot/runtime/common/src/paras_registrar.rs @@ -429,7 +429,7 @@ mod tests { { System: frame_system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Parachains: paras::{Pallet, Origin, Call, Storage, Config}, + Parachains: paras::{Pallet, Origin, Call, Storage, Config, Event}, Registrar: paras_registrar::{Pallet, Call, Storage, Event}, } ); @@ -486,6 +486,7 @@ mod tests { impl paras::Config for Test { type Origin = Origin; + type Event = Event; } impl configuration::Config for Test { } diff --git a/polkadot/runtime/parachains/src/mock.rs b/polkadot/runtime/parachains/src/mock.rs index bd69a9b015..33e4f99713 100644 --- a/polkadot/runtime/parachains/src/mock.rs +++ b/polkadot/runtime/parachains/src/mock.rs @@ -42,7 +42,7 @@ frame_support::construct_runtime!( { System: frame_system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Paras: paras::{Pallet, Origin, Call, Storage, Config}, + Paras: paras::{Pallet, Origin, Call, Storage, Event, Config}, Configuration: configuration::{Pallet, Call, Storage, Config}, Shared: shared::{Pallet, Call, Storage}, Inclusion: inclusion::{Pallet, Call, Storage, Event}, @@ -111,6 +111,7 @@ impl crate::shared::Config for Test { } impl crate::paras::Config for Test { type Origin = Origin; + type Event = Event; } impl crate::dmp::Config for Test { } diff --git a/polkadot/runtime/parachains/src/paras.rs b/polkadot/runtime/parachains/src/paras.rs index 8ec2261b03..e74755d502 100644 --- a/polkadot/runtime/parachains/src/paras.rs +++ b/polkadot/runtime/parachains/src/paras.rs @@ -31,8 +31,9 @@ use primitives::v1::{ Id as ParaId, ValidationCode, HeadData, SessionIndex, }; use sp_runtime::{traits::One, DispatchResult}; +use frame_system::ensure_root; use frame_support::{ - decl_storage, decl_module, decl_error, ensure, + decl_storage, decl_module, decl_error, decl_event, ensure, traits::Get, weights::Weight, }; @@ -54,6 +55,8 @@ pub trait Config: type Origin: From + From<::Origin> + Into::Origin>>; + + type Event: From + Into<::Event>; } // the two key times necessary to track for every code replacement. @@ -332,10 +335,79 @@ decl_error! { } } +decl_event! { + pub enum Event { + /// Current code has been updated for a Para. \[para_id\] + CurrentCodeUpdated(ParaId), + /// Current head has been updated for a Para. \[para_id\] + CurrentHeadUpdated(ParaId), + /// A code upgrade has been scheduled for a Para. \[para_id\] + CodeUpgradeScheduled(ParaId), + /// A new head has been noted for a Para. \[para_id\] + NewHeadNoted(ParaId), + /// A para has been queued to execute pending actions. \[para_id\] + ActionQueued(ParaId, SessionIndex), + } +} + decl_module! { /// The parachains configuration module. pub struct Module for enum Call where origin: ::Origin { type Error = Error; + + fn deposit_event() = default; + + /// Set the storage for the parachain validation code immediately. + #[weight = 0] + fn force_set_current_code(origin, para: ParaId, new_code: ValidationCode) { + ensure_root(origin)?; + let prior_code = ::CurrentCode::get(¶).unwrap_or_default(); + ::CurrentCode::insert(¶, new_code); + + let now = frame_system::Pallet::::block_number(); + Self::note_past_code(para, now, now, prior_code); + Self::deposit_event(Event::CurrentCodeUpdated(para)); + } + + /// Set the storage for the current parachain head data immediately. + #[weight = 0] + fn force_set_current_head(origin, para: ParaId, new_head: HeadData) { + ensure_root(origin)?; + ::Heads::insert(¶, new_head); + Self::deposit_event(Event::CurrentHeadUpdated(para)); + } + + /// Schedule a code upgrade for block `expected_at`. + #[weight = 0] + fn force_schedule_code_upgrade(origin, para: ParaId, new_code: ValidationCode, expected_at: T::BlockNumber) { + ensure_root(origin)?; + Self::schedule_code_upgrade(para, new_code, expected_at); + Self::deposit_event(Event::CodeUpgradeScheduled(para)); + } + + /// Note a new block head for para within the context of the current block. + #[weight = 0] + fn force_note_new_head(origin, para: ParaId, new_head: HeadData) { + ensure_root(origin)?; + let now = frame_system::Pallet::::block_number(); + Self::note_new_head(para, new_head, now); + Self::deposit_event(Event::NewHeadNoted(para)); + } + + /// Put a parachain directly into the next session's action queue. + /// We can't queue it any sooner than this without going into the + /// initializer... + #[weight = 0] + fn force_queue_action(origin, para: ParaId) { + ensure_root(origin)?; + let next_session = shared::Module::::session_index().saturating_add(One::one()); + ActionsQueue::mutate(next_session, |v| { + if let Err(i) = v.binary_search(¶) { + v.insert(i, para); + } + }); + Self::deposit_event(Event::ActionQueued(para, next_session)); + } } } diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index a664293248..9d0296678d 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -201,7 +201,7 @@ construct_runtime! { Inclusion: parachains_inclusion::{Pallet, Call, Storage, Event}, InclusionInherent: parachains_inclusion_inherent::{Pallet, Call, Storage, Inherent}, Scheduler: parachains_scheduler::{Pallet, Call, Storage}, - Paras: parachains_paras::{Pallet, Call, Storage}, + Paras: parachains_paras::{Pallet, Call, Storage, Event}, Initializer: parachains_initializer::{Pallet, Call, Storage}, Dmp: parachains_dmp::{Pallet, Call, Storage}, Ump: parachains_ump::{Pallet, Call, Storage}, @@ -526,6 +526,7 @@ impl parachains_inclusion::Config for Runtime { impl parachains_paras::Config for Runtime { type Origin = Origin; + type Event = Event; } parameter_types! { diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index 81117580ea..685c5918c5 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -466,6 +466,7 @@ impl parachains_session_info::Config for Runtime {} impl parachains_paras::Config for Runtime { type Origin = Origin; + type Event = Event; } impl parachains_dmp::Config for Runtime {} @@ -522,7 +523,7 @@ construct_runtime! { Inclusion: parachains_inclusion::{Pallet, Call, Storage, Event}, InclusionInherent: parachains_inclusion_inherent::{Pallet, Call, Storage, Inherent}, Initializer: parachains_initializer::{Pallet, Call, Storage}, - Paras: parachains_paras::{Pallet, Call, Storage, Origin}, + Paras: parachains_paras::{Pallet, Call, Storage, Origin, Event}, Scheduler: parachains_scheduler::{Pallet, Call, Storage}, ParasSudoWrapper: paras_sudo_wrapper::{Pallet, Call}, SessionInfo: parachains_session_info::{Pallet, Call, Storage},