Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Add the ability to suspend or resume XCM execution on the XCMP queue #896

Merged
merged 9 commits into from
Jan 31, 2022
38 changes: 38 additions & 0 deletions pallets/xcmp-queue/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ pub mod pallet {

/// The origin that is allowed to execute overweight messages.
type ExecuteOverweightOrigin: EnsureOrigin<Self::Origin>;

/// The origin that is allowed to resume or suspend the XCMP queue.
type ControllerOrigin: EnsureOrigin<Self::Origin>;
}

#[pallet::hooks]
Expand Down Expand Up @@ -129,6 +132,32 @@ pub mod pallet {
Self::deposit_event(Event::OverweightServiced(index, used));
Ok(Some(used.saturating_add(1_000_000)).into())
}

/// Suspends all XCM executions for the XCMP queue, regardless of the sender's origin.
///
/// - `origin`: Must pass `ControllerOrigin`.
#[pallet::weight(T::DbWeight::get().writes(1))]
pub fn suspend_xcm_execution(origin: OriginFor<T>) -> DispatchResult {
T::ControllerOrigin::ensure_origin(origin)?;

QueueActive::<T>::put(false);

Ok(())
}

/// Resumes all XCM executions for the XCMP queue.
///
/// Note that this function doesn't change the status of the in/out bound channels.
///
/// - `origin`: Must pass `ControllerOrigin`.
#[pallet::weight(T::DbWeight::get().writes(1))]
pub fn resume_xcm_execution(origin: OriginFor<T>) -> DispatchResult {
T::ControllerOrigin::ensure_origin(origin)?;

QueueActive::<T>::put(true);

Ok(())
}
}

#[pallet::event]
Expand Down Expand Up @@ -220,6 +249,10 @@ pub mod pallet {
/// available free overweight index.
#[pallet::storage]
pub(super) type OverweightCount<T: Config> = StorageValue<_, OverweightIndex, ValueQuery>;

/// Whether or not the XCMP queue is active in executing incoming XCMs or not.
#[pallet::storage]
pub(super) type QueueActive<T: Config> = StorageValue<_, bool, ValueQuery>;
}

#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, RuntimeDebug, TypeInfo)]
Expand Down Expand Up @@ -619,6 +652,11 @@ impl<T: Config> Pallet<T> {
/// for the second &c. though empirical and or practical factors may give rise to adjusting it
/// further.
fn service_xcmp_queue(max_weight: Weight) -> Weight {
let active = QueueActive::<T>::get();
if !active {
return 0
}

let mut status = <InboundXcmpStatus<T>>::get(); // <- sorted.
if status.len() == 0 {
return 0
Expand Down
1 change: 1 addition & 0 deletions pallets/xcmp-queue/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ impl Config for Test {
type ChannelInfo = ParachainSystem;
type VersionWrapper = ();
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
type ControllerOrigin = EnsureRoot<AccountId>;
}

pub fn new_test_ext() -> sp_io::TestExternalities {
Expand Down
18 changes: 18 additions & 0 deletions pallets/xcmp-queue/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,21 @@ fn service_overweight_bad_xcm_format() {
assert_noop!(XcmpQueue::service_overweight(Origin::root(), 0, 1000), Error::<Test>::BadXcm);
});
}

#[test]
fn suspend_xcm_execution_works() {
new_test_ext().execute_with(|| {
QueueActive::<Test>::put(false);

let xcm = Instruction::<()>::ClearOrigin.encode();
let mut message_format = XcmpMessageFormat::ConcatenatedVersionedXcm.encode();
message_format.extend(xcm.clone());
let messages = vec![(Default::default(), 1u32.into(), message_format.as_slice())];

// This shouldn't have executed the incoming XCM
XcmpQueue::handle_xcmp_messages(messages.into_iter(), Weight::max_value());

let queued_xcm = InboundXcmpMessages::<Test>::get(ParaId::default(), 1u32);
assert_eq!(queued_xcm, xcm);
});
}
1 change: 1 addition & 0 deletions parachain-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime {
type ChannelInfo = ParachainSystem;
type VersionWrapper = ();
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
type ControllerOrigin = EnsureRoot<AccountId>;
}

impl cumulus_pallet_dmp_queue::Config for Runtime {
Expand Down
1 change: 1 addition & 0 deletions polkadot-parachains/rococo-parachain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime {
type ChannelInfo = ParachainSystem;
type VersionWrapper = ();
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
type ControllerOrigin = EnsureRoot<AccountId>;
}

impl cumulus_pallet_dmp_queue::Config for Runtime {
Expand Down
1 change: 1 addition & 0 deletions polkadot-parachains/statemint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime {
type ChannelInfo = ParachainSystem;
type VersionWrapper = PolkadotXcm;
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
type ControllerOrigin = EnsureRoot<AccountId>;
}

impl cumulus_pallet_dmp_queue::Config for Runtime {
Expand Down
1 change: 1 addition & 0 deletions polkadot-parachains/westmint/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,7 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime {
type ChannelInfo = ParachainSystem;
type VersionWrapper = PolkadotXcm;
type ExecuteOverweightOrigin = EnsureRoot<AccountId>;
type ControllerOrigin = EnsureRoot<AccountId>;
}

impl cumulus_pallet_dmp_queue::Config for Runtime {
Expand Down