diff --git a/bridges/modules/grandpa/src/benchmarking.rs b/bridges/modules/grandpa/src/benchmarking.rs index f12894bb5cbd2..655cd6eae74e5 100644 --- a/bridges/modules/grandpa/src/benchmarking.rs +++ b/bridges/modules/grandpa/src/benchmarking.rs @@ -41,6 +41,7 @@ use crate::*; +use bp_runtime::BasicOperatingMode; use bp_test_utils::{ accounts, make_justification_for_header, JustificationGeneratorParams, TEST_GRANDPA_ROUND, TEST_GRANDPA_SET_ID, @@ -84,7 +85,7 @@ fn prepare_benchmark_data, I: 'static>( header: Box::new(bp_test_utils::test_header(Zero::zero())), authority_list, set_id: TEST_GRANDPA_SET_ID, - is_halted: false, + operating_mode: BasicOperatingMode::Normal, }; bootstrap_bridge::(init_data); diff --git a/bridges/modules/grandpa/src/lib.rs b/bridges/modules/grandpa/src/lib.rs index 726de9c507ed4..056aee406d8c0 100644 --- a/bridges/modules/grandpa/src/lib.rs +++ b/bridges/modules/grandpa/src/lib.rs @@ -71,6 +71,7 @@ pub type BridgedHeader = HeaderOf<>::BridgedChain>; #[frame_support::pallet] pub mod pallet { use super::*; + use bp_runtime::BasicOperatingMode; use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; @@ -119,14 +120,9 @@ pub mod pallet { impl, I: 'static> OwnedBridgeModule for Pallet { const LOG_TARGET: &'static str = "runtime::bridge-grandpa"; - const OPERATING_MODE_KEY: &'static str = "IsHalted"; type OwnerStorage = PalletOwner; - type OperatingMode = bool; - type OperatingModeStorage = IsHalted; - - fn is_halted() -> bool { - Self::OperatingModeStorage::get() - } + type OperatingMode = BasicOperatingMode; + type OperatingModeStorage = PalletOperatingMode; } #[pallet::call] @@ -237,8 +233,11 @@ pub mod pallet { /// /// May only be called either by root, or by `PalletOwner`. #[pallet::weight((T::DbWeight::get().reads_writes(1, 1), DispatchClass::Operational))] - pub fn set_operational(origin: OriginFor, operational: bool) -> DispatchResult { - Self::set_operating_mode(origin, !operational) + pub fn set_operating_mode( + origin: OriginFor, + operating_mode: BasicOperatingMode, + ) -> DispatchResult { + >::set_operating_mode(origin, operating_mode) } } @@ -293,9 +292,12 @@ pub mod pallet { pub type PalletOwner, I: 'static = ()> = StorageValue<_, T::AccountId, OptionQuery>; - /// If true, all pallet transactions are failed immediately. + /// The current operating mode of the pallet. + /// + /// Depending on the mode either all, or no transactions will be allowed. #[pallet::storage] - pub type IsHalted, I: 'static = ()> = StorageValue<_, bool, ValueQuery>; + pub type PalletOperatingMode, I: 'static = ()> = + StorageValue<_, BasicOperatingMode, ValueQuery>; #[pallet::genesis_config] pub struct GenesisConfig, I: 'static = ()> { @@ -324,7 +326,7 @@ pub mod pallet { } else { // Since the bridge hasn't been initialized we shouldn't allow anyone to perform // transactions. - >::put(true); + >::put(BasicOperatingMode::Halted); } } } @@ -463,7 +465,8 @@ pub mod pallet { pub(crate) fn initialize_bridge, I: 'static>( init_params: super::InitializationData>, ) { - let super::InitializationData { header, authority_list, set_id, is_halted } = init_params; + let super::InitializationData { header, authority_list, set_id, operating_mode } = + init_params; let initial_hash = header.hash(); >::put(initial_hash); @@ -473,7 +476,7 @@ pub mod pallet { let authority_set = bp_header_chain::AuthoritySet::new(authority_list, set_id); >::put(authority_set); - >::put(is_halted); + >::put(operating_mode); } #[cfg(feature = "runtime-benchmarks")] @@ -576,7 +579,7 @@ pub fn initialize_for_benchmarks, I: 'static>(header: BridgedHeader authority_list: sp_std::vec::Vec::new(), /* we don't verify any proofs in external * benchmarks */ set_id: 0, - is_halted: false, + operating_mode: bp_runtime::BasicOperatingMode::Normal, }); } @@ -584,6 +587,7 @@ pub fn initialize_for_benchmarks, I: 'static>(header: BridgedHeader mod tests { use super::*; use crate::mock::{run_test, test_header, Origin, TestHeader, TestNumber, TestRuntime}; + use bp_runtime::BasicOperatingMode; use bp_test_utils::{ authority_list, make_default_justification, make_justification_for_header, JustificationGeneratorParams, ALICE, BOB, @@ -611,7 +615,7 @@ mod tests { header: Box::new(genesis), authority_list: authority_list(), set_id: 1, - is_halted: false, + operating_mode: BasicOperatingMode::Normal, }; Pallet::::initialize(origin, init_data.clone()).map(|_| init_data) @@ -685,7 +689,7 @@ mod tests { CurrentAuthoritySet::::get().authorities, init_data.authority_list ); - assert!(!IsHalted::::get()); + assert_eq!(PalletOperatingMode::::get(), BasicOperatingMode::Normal); }) } @@ -707,29 +711,50 @@ mod tests { assert_ok!(Pallet::::set_owner(Origin::root(), Some(1))); assert_noop!( - Pallet::::set_operational(Origin::signed(2), false), + Pallet::::set_operating_mode( + Origin::signed(2), + BasicOperatingMode::Halted + ), DispatchError::BadOrigin, ); - assert_ok!(Pallet::::set_operational(Origin::root(), false)); + assert_ok!(Pallet::::set_operating_mode( + Origin::root(), + BasicOperatingMode::Halted + )); assert_ok!(Pallet::::set_owner(Origin::signed(1), None)); assert_noop!( - Pallet::::set_operational(Origin::signed(1), true), + Pallet::::set_operating_mode( + Origin::signed(1), + BasicOperatingMode::Normal + ), DispatchError::BadOrigin, ); assert_noop!( - Pallet::::set_operational(Origin::signed(2), true), + Pallet::::set_operating_mode( + Origin::signed(2), + BasicOperatingMode::Normal + ), DispatchError::BadOrigin, ); - assert_ok!(Pallet::::set_operational(Origin::root(), true)); + assert_ok!(Pallet::::set_operating_mode( + Origin::root(), + BasicOperatingMode::Normal + )); }); } #[test] fn pallet_may_be_halted_by_root() { run_test(|| { - assert_ok!(Pallet::::set_operational(Origin::root(), false)); - assert_ok!(Pallet::::set_operational(Origin::root(), true)); + assert_ok!(Pallet::::set_operating_mode( + Origin::root(), + BasicOperatingMode::Halted + )); + assert_ok!(Pallet::::set_operating_mode( + Origin::root(), + BasicOperatingMode::Normal + )); }); } @@ -738,21 +763,39 @@ mod tests { run_test(|| { PalletOwner::::put(2); - assert_ok!(Pallet::::set_operational(Origin::signed(2), false)); - assert_ok!(Pallet::::set_operational(Origin::signed(2), true)); + assert_ok!(Pallet::::set_operating_mode( + Origin::signed(2), + BasicOperatingMode::Halted + )); + assert_ok!(Pallet::::set_operating_mode( + Origin::signed(2), + BasicOperatingMode::Normal + )); assert_noop!( - Pallet::::set_operational(Origin::signed(1), false), + Pallet::::set_operating_mode( + Origin::signed(1), + BasicOperatingMode::Halted + ), DispatchError::BadOrigin, ); assert_noop!( - Pallet::::set_operational(Origin::signed(1), true), + Pallet::::set_operating_mode( + Origin::signed(1), + BasicOperatingMode::Normal + ), DispatchError::BadOrigin, ); - assert_ok!(Pallet::::set_operational(Origin::signed(2), false)); + assert_ok!(Pallet::::set_operating_mode( + Origin::signed(2), + BasicOperatingMode::Halted + )); assert_noop!( - Pallet::::set_operational(Origin::signed(1), true), + Pallet::::set_operating_mode( + Origin::signed(1), + BasicOperatingMode::Normal + ), DispatchError::BadOrigin, ); }); @@ -763,13 +806,19 @@ mod tests { run_test(|| { initialize_substrate_bridge(); - assert_ok!(Pallet::::set_operational(Origin::root(), false)); + assert_ok!(Pallet::::set_operating_mode( + Origin::root(), + BasicOperatingMode::Halted + )); assert_noop!( submit_finality_proof(1), Error::::BridgeModule(bp_runtime::OwnedBridgeModuleError::Halted) ); - assert_ok!(Pallet::::set_operational(Origin::root(), true)); + assert_ok!(Pallet::::set_operating_mode( + Origin::root(), + BasicOperatingMode::Normal + )); assert_ok!(submit_finality_proof(1)); }) } @@ -851,7 +900,7 @@ mod tests { header: Box::new(genesis), authority_list: invalid_authority_list, set_id: 1, - is_halted: false, + operating_mode: BasicOperatingMode::Normal, }; assert_ok!(Pallet::::initialize(Origin::root(), init_data)); @@ -1115,8 +1164,8 @@ mod tests { #[test] fn storage_keys_computed_properly() { assert_eq!( - IsHalted::::storage_value_final_key().to_vec(), - bp_header_chain::storage_keys::is_halted_key("Grandpa").0, + PalletOperatingMode::::storage_value_final_key().to_vec(), + bp_header_chain::storage_keys::pallet_operating_mode_key("Grandpa").0, ); assert_eq!( diff --git a/bridges/modules/messages/src/lib.rs b/bridges/modules/messages/src/lib.rs index 78f44e75027b5..eed718477beb3 100644 --- a/bridges/modules/messages/src/lib.rs +++ b/bridges/modules/messages/src/lib.rs @@ -57,11 +57,11 @@ use bp_messages::{ DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain, }, total_unrewarded_messages, DeliveredMessages, InboundLaneData, InboundMessageDetails, LaneId, - MessageData, MessageKey, MessageNonce, MessagePayload, OperatingMode, OutboundLaneData, + MessageData, MessageKey, MessageNonce, MessagePayload, MessagesOperatingMode, OutboundLaneData, OutboundMessageDetails, Parameter as MessagesParameter, UnrewardedRelayer, UnrewardedRelayersState, }; -use bp_runtime::{ChainId, OwnedBridgeModule, Size}; +use bp_runtime::{BasicOperatingMode, ChainId, OwnedBridgeModule, Size}; use codec::{Decode, Encode}; use frame_support::{ fail, @@ -218,14 +218,9 @@ pub mod pallet { impl, I: 'static> OwnedBridgeModule for Pallet { const LOG_TARGET: &'static str = "runtime::bridge-messages"; - const OPERATING_MODE_KEY: &'static str = "PalletOperatingMode"; type OwnerStorage = PalletOwner; - type OperatingMode = OperatingMode; + type OperatingMode = MessagesOperatingMode; type OperatingModeStorage = PalletOperatingMode; - - fn is_halted() -> bool { - Self::OperatingModeStorage::get() == OperatingMode::Halted - } } #[pallet::call] @@ -244,7 +239,7 @@ pub mod pallet { #[pallet::weight((T::DbWeight::get().reads_writes(1, 1), DispatchClass::Operational))] pub fn set_operating_mode( origin: OriginFor, - operating_mode: OperatingMode, + operating_mode: MessagesOperatingMode, ) -> DispatchResult { >::set_operating_mode(origin, operating_mode) } @@ -708,7 +703,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn operating_mode)] pub type PalletOperatingMode, I: 'static = ()> = - StorageValue<_, OperatingMode, ValueQuery>; + StorageValue<_, MessagesOperatingMode, ValueQuery>; /// Map of lane id => inbound lane data. #[pallet::storage] @@ -728,7 +723,7 @@ pub mod pallet { #[pallet::genesis_config] pub struct GenesisConfig, I: 'static = ()> { /// Initial pallet operating mode. - pub operating_mode: OperatingMode, + pub operating_mode: MessagesOperatingMode, /// Initial pallet owner. pub owner: Option, /// Dummy marker. @@ -972,11 +967,13 @@ where /// Ensure that the pallet is in normal operational mode. fn ensure_normal_operating_mode, I: 'static>() -> Result<(), Error> { - if PalletOperatingMode::::get() != OperatingMode::Normal { - Err(Error::::NotOperatingNormally) - } else { - Ok(()) + if PalletOperatingMode::::get() == + MessagesOperatingMode::Basic(BasicOperatingMode::Normal) + { + return Ok(()) } + + Err(Error::::NotOperatingNormally) } /// Creates new inbound lane object, backed by runtime storage. @@ -1234,26 +1231,35 @@ mod tests { assert_ok!(Pallet::::set_owner(Origin::root(), Some(1))); assert_noop!( - Pallet::::set_operating_mode(Origin::signed(2), OperatingMode::Halted), + Pallet::::set_operating_mode( + Origin::signed(2), + MessagesOperatingMode::Basic(BasicOperatingMode::Halted) + ), DispatchError::BadOrigin, ); assert_ok!(Pallet::::set_operating_mode( Origin::root(), - OperatingMode::Halted + MessagesOperatingMode::Basic(BasicOperatingMode::Halted) )); assert_ok!(Pallet::::set_owner(Origin::signed(1), None)); assert_noop!( - Pallet::::set_operating_mode(Origin::signed(1), OperatingMode::Normal), + Pallet::::set_operating_mode( + Origin::signed(1), + MessagesOperatingMode::Basic(BasicOperatingMode::Normal) + ), DispatchError::BadOrigin, ); assert_noop!( - Pallet::::set_operating_mode(Origin::signed(2), OperatingMode::Normal), + Pallet::::set_operating_mode( + Origin::signed(2), + MessagesOperatingMode::Basic(BasicOperatingMode::Normal) + ), DispatchError::BadOrigin, ); assert_ok!(Pallet::::set_operating_mode( Origin::root(), - OperatingMode::Normal + MessagesOperatingMode::Basic(BasicOperatingMode::Normal) )); }); } @@ -1263,11 +1269,11 @@ mod tests { run_test(|| { assert_ok!(Pallet::::set_operating_mode( Origin::root(), - OperatingMode::Halted + MessagesOperatingMode::Basic(BasicOperatingMode::Halted) )); assert_ok!(Pallet::::set_operating_mode( Origin::root(), - OperatingMode::Normal + MessagesOperatingMode::Basic(BasicOperatingMode::Normal) )); }); } @@ -1279,28 +1285,37 @@ mod tests { assert_ok!(Pallet::::set_operating_mode( Origin::signed(2), - OperatingMode::Halted + MessagesOperatingMode::Basic(BasicOperatingMode::Halted) )); assert_ok!(Pallet::::set_operating_mode( Origin::signed(2), - OperatingMode::Normal + MessagesOperatingMode::Basic(BasicOperatingMode::Normal) )); assert_noop!( - Pallet::::set_operating_mode(Origin::signed(1), OperatingMode::Halted), + Pallet::::set_operating_mode( + Origin::signed(1), + MessagesOperatingMode::Basic(BasicOperatingMode::Halted) + ), DispatchError::BadOrigin, ); assert_noop!( - Pallet::::set_operating_mode(Origin::signed(1), OperatingMode::Normal), + Pallet::::set_operating_mode( + Origin::signed(1), + MessagesOperatingMode::Basic(BasicOperatingMode::Normal) + ), DispatchError::BadOrigin, ); assert_ok!(Pallet::::set_operating_mode( Origin::signed(2), - OperatingMode::Halted + MessagesOperatingMode::Basic(BasicOperatingMode::Halted) )); assert_noop!( - Pallet::::set_operating_mode(Origin::signed(1), OperatingMode::Normal), + Pallet::::set_operating_mode( + Origin::signed(1), + MessagesOperatingMode::Basic(BasicOperatingMode::Normal) + ), DispatchError::BadOrigin, ); }); @@ -1408,7 +1423,9 @@ mod tests { // send message first to be able to check that delivery_proof fails later send_regular_message(); - PalletOperatingMode::::put(OperatingMode::Halted); + PalletOperatingMode::::put(MessagesOperatingMode::Basic( + BasicOperatingMode::Halted, + )); assert_noop!( Pallet::::send_message( @@ -1466,7 +1483,9 @@ mod tests { // send message first to be able to check that delivery_proof fails later send_regular_message(); - PalletOperatingMode::::put(OperatingMode::RejectingOutboundMessages); + PalletOperatingMode::::put( + MessagesOperatingMode::RejectingOutboundMessages, + ); assert_noop!( Pallet::::send_message( diff --git a/bridges/modules/parachains/src/lib.rs b/bridges/modules/parachains/src/lib.rs index cf634e5b5ca5c..46be3866db12e 100644 --- a/bridges/modules/parachains/src/lib.rs +++ b/bridges/modules/parachains/src/lib.rs @@ -400,6 +400,7 @@ mod tests { run_test, test_relay_header, Origin, TestRuntime, PARAS_PALLET_NAME, UNTRACKED_PARACHAIN_ID, }; + use bp_runtime::BasicOperatingMode; use bp_test_utils::{authority_list, make_default_justification}; use frame_support::{ assert_noop, assert_ok, @@ -420,7 +421,7 @@ mod tests { header: Box::new(test_relay_header(0, state_root)), authority_list: authority_list(), set_id: 1, - is_halted: false, + operating_mode: BasicOperatingMode::Normal, }, ) .unwrap(); diff --git a/bridges/primitives/header-chain/src/lib.rs b/bridges/primitives/header-chain/src/lib.rs index ff8ee82f41e42..8ac7972621ce6 100644 --- a/bridges/primitives/header-chain/src/lib.rs +++ b/bridges/primitives/header-chain/src/lib.rs @@ -19,6 +19,7 @@ #![cfg_attr(not(feature = "std"), no_std)] +use bp_runtime::BasicOperatingMode; use codec::{Codec, Decode, Encode, EncodeLike}; use core::{clone::Clone, cmp::Eq, default::Default, fmt::Debug}; use scale_info::TypeInfo; @@ -66,8 +67,8 @@ pub struct InitializationData { pub authority_list: AuthorityList, /// The ID of the initial authority set. pub set_id: SetId, - /// Should the pallet block transaction immediately after initialization. - pub is_halted: bool, + /// Pallet operating mode. + pub operating_mode: BasicOperatingMode, } /// base trait for verifying transaction inclusion proofs. diff --git a/bridges/primitives/header-chain/src/storage_keys.rs b/bridges/primitives/header-chain/src/storage_keys.rs index 14c40d69853b9..bb642b1817f75 100644 --- a/bridges/primitives/header-chain/src/storage_keys.rs +++ b/bridges/primitives/header-chain/src/storage_keys.rs @@ -17,18 +17,18 @@ //! Storage keys of bridge GRANDPA pallet. /// Name of the `IsHalted` storage value. -pub const IS_HALTED_VALUE_NAME: &str = "IsHalted"; +pub const PALLET_OPERATING_MODE_VALUE_NAME: &str = "PalletOperatingMode"; /// Name of the `BestFinalized` storage value. pub const BEST_FINALIZED_VALUE_NAME: &str = "BestFinalized"; use sp_core::storage::StorageKey; -/// Storage key of the `IsHalted` flag in the runtime storage. -pub fn is_halted_key(pallet_prefix: &str) -> StorageKey { +/// Storage key of the `PalletOperatingMode` variable in the runtime storage. +pub fn pallet_operating_mode_key(pallet_prefix: &str) -> StorageKey { StorageKey( bp_runtime::storage_value_final_key( pallet_prefix.as_bytes(), - IS_HALTED_VALUE_NAME.as_bytes(), + PALLET_OPERATING_MODE_VALUE_NAME.as_bytes(), ) .to_vec(), ) @@ -51,13 +51,13 @@ mod tests { use hex_literal::hex; #[test] - fn is_halted_key_computed_properly() { + fn pallet_operating_mode_key_computed_properly() { // If this test fails, then something has been changed in module storage that is breaking // compatibility with previous pallet. - let storage_key = is_halted_key("BridgeGrandpa").0; + let storage_key = pallet_operating_mode_key("BridgeGrandpa").0; assert_eq!( storage_key, - hex!("0b06f475eddb98cf933a12262e0388de9611a984bbd04e2fd39f97bbc006115f").to_vec(), + hex!("0b06f475eddb98cf933a12262e0388de0f4cf0917788d791142ff6c1f216e7b3").to_vec(), "Unexpected storage key: {}", hex::encode(&storage_key), ); diff --git a/bridges/primitives/messages/src/lib.rs b/bridges/primitives/messages/src/lib.rs index 8d51a6fa86462..455caad729b70 100644 --- a/bridges/primitives/messages/src/lib.rs +++ b/bridges/primitives/messages/src/lib.rs @@ -32,14 +32,15 @@ pub mod storage_keys; pub mod target_chain; // Weight is reexported to avoid additional frame-support dependencies in related crates. +use bp_runtime::{BasicOperatingMode, OperatingMode}; pub use frame_support::weights::Weight; /// Messages pallet operating mode. #[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)] #[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] -pub enum OperatingMode { - /// Normal mode, when all operations are allowed. - Normal, +pub enum MessagesOperatingMode { + /// Basic operating mode (Normal/Halted) + Basic(BasicOperatingMode), /// The pallet is not accepting outbound messages. Inbound messages and receiving proofs /// are still accepted. /// @@ -48,13 +49,20 @@ pub enum OperatingMode { /// queued messages to the bridged chain. Once upgrade is completed, the mode may be switched /// back to `Normal`. RejectingOutboundMessages, - /// The pallet is halted. All operations (except operating mode change) are prohibited. - Halted, } -impl Default for OperatingMode { +impl Default for MessagesOperatingMode { fn default() -> Self { - OperatingMode::Normal + MessagesOperatingMode::Basic(BasicOperatingMode::Normal) + } +} + +impl OperatingMode for MessagesOperatingMode { + fn is_halted(&self) -> bool { + match self { + Self::Basic(operating_mode) => operating_mode.is_halted(), + _ => false, + } } } diff --git a/bridges/primitives/runtime/Cargo.toml b/bridges/primitives/runtime/Cargo.toml index 691426aaf04a7..94dd12175d9d6 100644 --- a/bridges/primitives/runtime/Cargo.toml +++ b/bridges/primitives/runtime/Cargo.toml @@ -11,6 +11,7 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = hash-db = { version = "0.15.2", default-features = false } num-traits = { version = "0.2", default-features = false } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } +serde = { version = "1.0", optional = true, features = ["derive"] } # Substrate Dependencies @@ -35,6 +36,7 @@ std = [ "hash-db/std", "num-traits/std", "scale-info/std", + "serde", "sp-core/std", "sp-io/std", "sp-runtime/std", diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs index ee5e6b5d24e99..cba89df726679 100644 --- a/bridges/primitives/runtime/src/lib.rs +++ b/bridges/primitives/runtime/src/lib.rs @@ -269,18 +269,47 @@ pub enum OwnedBridgeModuleError { Halted, } +/// Operating mode for a bridge module. +pub trait OperatingMode: Send + Copy + Debug + FullCodec { + // Returns true if the bridge module is halted. + fn is_halted(&self) -> bool; +} + +/// Basic operating modes for a bridges module (Normal/Halted). +#[derive(Encode, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] +pub enum BasicOperatingMode { + /// Normal mode, when all operations are allowed. + Normal, + /// The pallet is halted. All operations (except operating mode change) are prohibited. + Halted, +} + +impl Default for BasicOperatingMode { + fn default() -> Self { + Self::Normal + } +} + +impl OperatingMode for BasicOperatingMode { + fn is_halted(&self) -> bool { + *self == BasicOperatingMode::Halted + } +} + /// Bridge module that has owner and operating mode pub trait OwnedBridgeModule { /// The target that will be used when publishing logs related to this module. const LOG_TARGET: &'static str; - const OPERATING_MODE_KEY: &'static str; type OwnerStorage: StorageValue>; - type OperatingMode: Copy + Debug + FullCodec; - type OperatingModeStorage: StorageValue; + type OperatingMode: OperatingMode; + type OperatingModeStorage: StorageValue; /// Check if the module is halted. - fn is_halted() -> bool; + fn is_halted() -> bool { + Self::OperatingModeStorage::get().is_halted() + } /// Ensure that the origin is either root, or `PalletOwner`. fn ensure_owner_or_root(origin: T::Origin) -> Result<(), BadOrigin> { @@ -325,12 +354,7 @@ pub trait OwnedBridgeModule { ) -> DispatchResult { Self::ensure_owner_or_root(origin)?; Self::OperatingModeStorage::put(operating_mode); - log::info!( - target: Self::LOG_TARGET, - "Setting operating mode ( {} = {:?}).", - Self::OPERATING_MODE_KEY, - operating_mode - ); + log::info!(target: Self::LOG_TARGET, "Setting operating mode to {:?}.", operating_mode); Ok(()) } } diff --git a/bridges/relays/lib-substrate-relay/src/finality/engine.rs b/bridges/relays/lib-substrate-relay/src/finality/engine.rs index 0f2cc87660bfc..b2b72e4f2c39f 100644 --- a/bridges/relays/lib-substrate-relay/src/finality/engine.rs +++ b/bridges/relays/lib-substrate-relay/src/finality/engine.rs @@ -23,6 +23,7 @@ use bp_header_chain::{ justification::{verify_justification, GrandpaJustification}, FinalityProof, }; +use bp_runtime::{BasicOperatingMode, OperatingMode}; use codec::{Decode, Encode}; use finality_grandpa::voter_set::VoterSet; use num_traits::{One, Zero}; @@ -44,10 +45,12 @@ pub trait Engine: Send { type FinalityProof: FinalityProof> + Decode + Encode; /// Type of bridge pallet initialization data. type InitializationData: std::fmt::Debug + Send + Sync + 'static; + /// Type of bridge pallet operating mode. + type OperatingMode: OperatingMode + 'static; - /// Returns storage key at the bridged (target) chain that corresponds to the `bool` value, - /// which is true when the bridge pallet is halted. - fn is_halted_key() -> StorageKey; + /// Returns storage key at the bridged (target) chain that corresponds to the variable + /// that holds the operating mode of the pallet. + fn pallet_operating_mode_key() -> StorageKey; /// Returns storage at the bridged (target) chain that corresponds to some value that is /// missing from the storage until bridge pallet is initialized. /// @@ -74,7 +77,11 @@ pub trait Engine: Send { async fn is_halted( target_client: &Client, ) -> Result { - Ok(target_client.storage_value(Self::is_halted_key(), None).await?.unwrap_or(false)) + Ok(target_client + .storage_value::(Self::pallet_operating_mode_key(), None) + .await? + .map(|operating_mode| operating_mode.is_halted()) + .unwrap_or(false)) } } @@ -112,9 +119,10 @@ impl Engine for Grandpa { const ID: ConsensusEngineId = sp_finality_grandpa::GRANDPA_ENGINE_ID; type FinalityProof = GrandpaJustification>; type InitializationData = bp_header_chain::InitializationData; + type OperatingMode = BasicOperatingMode; - fn is_halted_key() -> StorageKey { - bp_header_chain::storage_keys::is_halted_key(C::WITH_CHAIN_GRANDPA_PALLET_NAME) + fn pallet_operating_mode_key() -> StorageKey { + bp_header_chain::storage_keys::pallet_operating_mode_key(C::WITH_CHAIN_GRANDPA_PALLET_NAME) } fn is_initialized_key() -> StorageKey { @@ -237,7 +245,7 @@ impl Engine for Grandpa { } else { initial_authorities_set_id }, - is_halted: false, + operating_mode: BasicOperatingMode::Normal, }) } } diff --git a/bridges/relays/lib-substrate-relay/src/messages_source.rs b/bridges/relays/lib-substrate-relay/src/messages_source.rs index 0e21ef66eda3b..5a6b6554e4bae 100644 --- a/bridges/relays/lib-substrate-relay/src/messages_source.rs +++ b/bridges/relays/lib-substrate-relay/src/messages_source.rs @@ -31,10 +31,10 @@ use async_std::sync::Arc; use async_trait::async_trait; use bp_messages::{ storage_keys::{operating_mode_key, outbound_lane_data_key}, - InboundMessageDetails, LaneId, MessageData, MessageNonce, OperatingMode, OutboundLaneData, - OutboundMessageDetails, UnrewardedRelayersState, + InboundMessageDetails, LaneId, MessageData, MessageNonce, MessagesOperatingMode, + OutboundLaneData, OutboundMessageDetails, UnrewardedRelayersState, }; -use bp_runtime::messages::DispatchFeePayment; +use bp_runtime::{messages::DispatchFeePayment, BasicOperatingMode}; use bridge_runtime_common::messages::{ source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof, }; @@ -420,7 +420,8 @@ where let operating_mode = client .storage_value(operating_mode_key(WithChain::WITH_CHAIN_MESSAGES_PALLET_NAME), None) .await?; - let is_halted = operating_mode == Some(OperatingMode::Halted); + let is_halted = + operating_mode == Some(MessagesOperatingMode::Basic(BasicOperatingMode::Halted)); if is_halted { Err(SubstrateError::BridgePalletIsHalted) } else {