This repository has been archived by the owner on May 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* lockdown-pallet backport * Add lockdown mode activation to lockdown-mode pallet's `GenesisConfig` (#176) * add activating lockdown mode to GenesisConfig * add activating lockdown mode to test ext * add tests for activating lockdown mode in GenesisConfig * cargo fmt -p pallet-lockdown-mode * fix linting * add activated to benchmark * removing, as this is already in another test * setting initial state to true, therefore no longer need to manually change state * rename activated in genesisConfig to initial_status --------- Co-authored-by: Valentin Fernandez <valentin@parity.io> Co-authored-by: Bruno Galvao <brunopgalvao@gmail.com>
- Loading branch information
1 parent
7ee2415
commit a6f4f90
Showing
14 changed files
with
723 additions
and
11 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
[package] | ||
name = "pallet-lockdown-mode" | ||
version = "0.1.0" | ||
description = "Trappist pallet for setting lockdown mode." | ||
edition = "2021" | ||
license = "Apache-2.0" | ||
repository = "https://github.com/paritytech/trappist" | ||
|
||
[package.metadata.docs.rs] | ||
targets = ["x86_64-unknown-linux-gnu"] | ||
|
||
[dependencies] | ||
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive",] } | ||
scale-info = { version = "2.3.1", default-features = false, features = ["derive"] } | ||
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.40" } | ||
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.40" } | ||
frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" } | ||
frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" } | ||
frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" } | ||
cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40", default-features = false } | ||
pallet-assets = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" } | ||
pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" } | ||
log = "0.4.17" | ||
xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.40" } | ||
|
||
xcm-primitives = { path = "../../primitives/xcm", default-features = false } | ||
|
||
[dev-dependencies] | ||
sp-core = { version = "7.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" } | ||
sp-io = { version = "7.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" } | ||
sp-runtime = { version = "7.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" } | ||
pallet-remark = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.40" } | ||
|
||
|
||
xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.40" } | ||
xcm-simulator = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.40" } | ||
xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.40" } | ||
xcm-builder = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.40" } | ||
pallet-xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.40" } | ||
polkadot-core-primitives = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.40" } | ||
polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.40" } | ||
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.40" } | ||
|
||
parachain-info = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40", default-features = false } | ||
parachains-common = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40", default-features = false } | ||
cumulus-pallet-dmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40", default-features = false } | ||
cumulus-pallet-xcmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40", default-features = false } | ||
cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.40", default-features = false } | ||
|
||
[features] | ||
default = ["std"] | ||
std = [ | ||
"codec/std", | ||
"sp-runtime/std", | ||
"sp-std/std", | ||
"pallet-assets/std", | ||
"pallet-balances/std", | ||
"frame-benchmarking/std", | ||
"frame-support/std", | ||
"frame-system/std", | ||
"scale-info/std", | ||
"xcm-primitives/std", | ||
"xcm/std", | ||
"xcm-executor/std", | ||
"xcm-builder/std", | ||
"pallet-xcm/std", | ||
"polkadot-core-primitives/std", | ||
"polkadot-runtime-parachains/std", | ||
"polkadot-parachain/std", | ||
"parachain-info/std", | ||
"parachains-common/std", | ||
"cumulus-pallet-dmp-queue/std", | ||
"cumulus-pallet-xcmp-queue/std", | ||
"cumulus-primitives-core/std", | ||
] | ||
runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] | ||
try-runtime = ["frame-support/try-runtime"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Lockdown Mode Pallet | ||
|
||
The Lockdown Mode Pallet is a Substrate module that provides functionality to lock down the runtime execution in a Substrate-based blockchain system. When the lockdown mode is activated, it filters out incoming calls and messages to ensure that only authorized actions are allowed. | ||
|
||
## Overview | ||
|
||
This pallet the governance of the chain to activate or deactivate a lockdown mode. When the lockdown mode is activated, incoming runtime calls and downward messages are filtered based on a preconfigured filter. Additionally, it suspends the execution of XCM (Cross-Consensus Message) messages in the `on_idle` hook. | ||
|
||
The lockdown mode status is stored in the `LockdownModeStatus` storage item. When the lockdown mode is deactivated, the system resumes normal operations, including the execution of XCM messages in the `on_idle` hook. | ||
|
||
## Configuration | ||
|
||
This pallet supports configurable traits that allow customization according to specific needs. | ||
|
||
### Types | ||
|
||
- `RuntimeEvent`: Specifies the runtime event type. | ||
- `LockdownModeOrigin`: Specifies the origin that is allowed to activate and deactivate the lockdown mode. | ||
- `BlackListedCalls`: Specifies the filter used to filter incoming runtime calls in lockdown mode. | ||
- `LockdownDmpHandler`: Specifies the handler for downward messages in lockdown mode. | ||
- `XcmExecutorManager`: Interface to control the execution of XCMP Queue messages. | ||
|
||
|
||
## Extrinsics | ||
|
||
The pallet provides the following extrinsics: | ||
|
||
- `activate_lockdown_mode`: Activates the lockdown mode. Only the specified `LockdownModeOrigin` can call this extrinsic. It updates the `LockdownModeStatus` storage item to `ACTIVATED` (true) and attempts to suspend the execution of XCM messages in the `on_idle` hook. | ||
- `deactivate_lockdown_mode`: Deactivates the lockdown mode. Only the specified `LockdownModeOrigin` can call this extrinsic. It updates the `LockdownModeStatus` storage item to `DEACTIVATED` (false) and attempts to resume the execution of XCM messages in the `on_idle` hook. | ||
|
||
|
||
#### Errors | ||
|
||
Possible errors returned by the dispatchable calls are: | ||
|
||
- `LockdownModeAlreadyActivated`: The lockdown mode is already activated. | ||
- `LockdownModeAlreadyDeactivated`: The lockdown mode is already deactivated. | ||
|
||
Please note that any failure to suspend or resume XCM execution in the `on_idle` hook is not treated as a fatal error that stops the function execution. Instead, it is recorded as an event `FailedToSuspendIdleXcmExecution` or `FailedToResumeIdleXcmExecution`, respectively, and the function continues its execution. | ||
|
||
The lockdown mode can serve as a crucial tool in system maintenance or in case of emergency, when it's necessary to restrict system operation and ensure the system's security and stability. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
use super::*; | ||
|
||
#[allow(unused)] | ||
use crate::Pallet as LockdownMode; | ||
use crate::{ACTIVATED, DEACTIVATED}; | ||
use frame_benchmarking::benchmarks; | ||
use frame_system::RawOrigin; | ||
|
||
benchmarks! { | ||
activate_lockdown_mode { | ||
LockdownModeStatus::<T>::put(DEACTIVATED); | ||
}: activate_lockdown_mode(RawOrigin::Root) | ||
verify { | ||
assert_eq!(LockdownModeStatus::<T>::get(), ACTIVATED); | ||
} | ||
|
||
deactivate_lockdown_mode { | ||
LockdownModeStatus::<T>::put(ACTIVATED); | ||
}: deactivate_lockdown_mode(RawOrigin::Root) | ||
verify { | ||
assert_eq!(LockdownModeStatus::<T>::get(), DEACTIVATED); | ||
} | ||
|
||
impl_benchmark_test_suite!(LockdownMode, crate::mock::new_test_ext(true), crate::mock::Test); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
#![cfg_attr(not(feature = "std"), no_std)] | ||
|
||
/// Edit this file to define custom logic or remove it if it is not needed. | ||
/// Learn more about FRAME and the core library of Substrate FRAME pallets: | ||
/// <https://docs.substrate.io/reference/frame-pallets/> | ||
pub use pallet::*; | ||
|
||
#[cfg(test)] | ||
mod mock; | ||
#[cfg(test)] | ||
mod tests; | ||
|
||
#[cfg(feature = "runtime-benchmarks")] | ||
mod benchmarking; | ||
pub mod weights; | ||
pub use weights::*; | ||
|
||
pub const ACTIVATED: bool = true; | ||
pub const DEACTIVATED: bool = false; | ||
|
||
#[frame_support::pallet] | ||
pub mod pallet { | ||
use super::*; | ||
use cumulus_primitives_core::{ | ||
relay_chain::BlockNumber as RelayBlockNumber, DmpMessageHandler, | ||
}; | ||
use frame_support::{ | ||
pallet_prelude::{ValueQuery, *}, | ||
traits::Contains, | ||
}; | ||
use frame_system::pallet_prelude::*; | ||
use sp_std::vec::Vec; | ||
use xcm_primitives::PauseXcmExecution; | ||
#[pallet::pallet] | ||
pub struct Pallet<T>(_); | ||
|
||
#[pallet::genesis_config] | ||
pub struct GenesisConfig { | ||
pub initial_status: bool, | ||
} | ||
|
||
#[cfg(feature = "std")] | ||
impl Default for GenesisConfig { | ||
fn default() -> Self { | ||
Self { initial_status: ACTIVATED } | ||
} | ||
} | ||
|
||
#[pallet::genesis_build] | ||
impl<T: Config> GenesisBuild<T> for GenesisConfig { | ||
fn build(&self) { | ||
LockdownModeStatus::<T>::put(&self.initial_status); | ||
} | ||
} | ||
|
||
#[pallet::config] | ||
pub trait Config: frame_system::Config { | ||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>; | ||
type LockdownModeOrigin: EnsureOrigin<Self::RuntimeOrigin>; | ||
type BlackListedCalls: Contains<Self::RuntimeCall>; | ||
type LockdownDmpHandler: DmpMessageHandler; | ||
type XcmExecutorManager: PauseXcmExecution; | ||
type WeightInfo: WeightInfo; | ||
} | ||
|
||
#[pallet::storage] | ||
pub type LockdownModeStatus<T: Config> = StorageValue<_, bool, ValueQuery>; | ||
|
||
#[pallet::event] | ||
#[pallet::generate_deposit(pub(super) fn deposit_event)] | ||
pub enum Event<T: Config> { | ||
LockdownModeActivated, | ||
LockdownModeDeactivated, | ||
/// The call to suspend on_idle XCM execution failed with inner error | ||
FailedToSuspendIdleXcmExecution { | ||
error: DispatchError, | ||
}, | ||
/// The call to resume on_idle XCM execution failed with inner error | ||
FailedToResumeIdleXcmExecution { | ||
error: DispatchError, | ||
}, | ||
} | ||
|
||
#[pallet::error] | ||
pub enum Error<T> { | ||
/// Lockdown mode was already activated | ||
LockdownModeAlreadyActivated, | ||
/// Lockdown mode was already deactivated | ||
LockdownModeAlreadyDeactivated, | ||
} | ||
|
||
#[pallet::call] | ||
impl<T: Config> Pallet<T> { | ||
#[pallet::call_index(0)] | ||
#[pallet::weight(<T as pallet::Config>::WeightInfo::activate_lockdown_mode())] | ||
pub fn activate_lockdown_mode(origin: OriginFor<T>) -> DispatchResult { | ||
T::LockdownModeOrigin::ensure_origin(origin)?; | ||
|
||
ensure!(!LockdownModeStatus::<T>::get(), Error::<T>::LockdownModeAlreadyActivated); | ||
|
||
LockdownModeStatus::<T>::put(ACTIVATED); | ||
|
||
if let Err(error) = T::XcmExecutorManager::suspend_xcm_execution() { | ||
log::error!("Failed to suspend idle XCM execution {:?}", error); | ||
Self::deposit_event(Event::FailedToSuspendIdleXcmExecution { error }); | ||
} | ||
|
||
Self::deposit_event(Event::LockdownModeActivated); | ||
|
||
Ok(()) | ||
} | ||
|
||
#[pallet::call_index(1)] | ||
#[pallet::weight(<T as pallet::Config>::WeightInfo::deactivate_lockdown_mode())] | ||
pub fn deactivate_lockdown_mode(origin: OriginFor<T>) -> DispatchResult { | ||
T::LockdownModeOrigin::ensure_origin(origin)?; | ||
ensure!(LockdownModeStatus::<T>::get(), Error::<T>::LockdownModeAlreadyDeactivated); | ||
|
||
LockdownModeStatus::<T>::put(DEACTIVATED); | ||
|
||
if let Err(error) = T::XcmExecutorManager::resume_xcm_execution() { | ||
log::error!("Failed to resume idle XCM execution {:?}", error); | ||
Self::deposit_event(Event::FailedToResumeIdleXcmExecution { error }); | ||
} | ||
|
||
Self::deposit_event(Event::LockdownModeDeactivated); | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
impl<T: Config> Contains<T::RuntimeCall> for Pallet<T> { | ||
fn contains(call: &T::RuntimeCall) -> bool { | ||
if LockdownModeStatus::<T>::get() { | ||
T::BlackListedCalls::contains(call) | ||
} else { | ||
return true | ||
} | ||
} | ||
} | ||
|
||
impl<T: Config> DmpMessageHandler for Pallet<T> { | ||
fn handle_dmp_messages( | ||
iter: impl Iterator<Item = (RelayBlockNumber, Vec<u8>)>, | ||
limit: Weight, | ||
) -> Weight { | ||
if LockdownModeStatus::<T>::get() { | ||
T::LockdownDmpHandler::handle_dmp_messages(iter, Weight::zero()) | ||
} else { | ||
// Normal path, everything should pass through | ||
T::LockdownDmpHandler::handle_dmp_messages(iter, limit) | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.