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

WIP safe mode and tx pause {continued} #12371

Merged
merged 28 commits into from
Oct 12, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
d076c92
progress on true call UI types
nuke-web3 Sep 27, 2022
1f2a727
mid rework progress on tx pause
nuke-web3 Sep 27, 2022
bf9c803
stck on overflow evaluating the requirement `pallet::Call<mock::Test>…
nuke-web3 Sep 27, 2022
427d48b
tests pass, kitchen sink needs proper impl for origins
nuke-web3 Sep 28, 2022
a8f06db
fmt
nuke-web3 Sep 28, 2022
04a4711
UnfilterableCalls uniform naming
nuke-web3 Sep 28, 2022
55b38bb
Fix safe-mode benchmarks
ggwpez Sep 28, 2022
7aad890
Fix safe-mode benchmarks
ggwpez Sep 28, 2022
354a251
fix build errors, except origin issue
nuke-web3 Sep 29, 2022
80ede09
update to use named parameter syntax for Events
nuke-web3 Sep 29, 2022
cd50d92
building
nuke-web3 Sep 30, 2022
ed6c25f
building except wasm runtime
nuke-web3 Sep 30, 2022
36ee207
benchmarking::bench_force_activate' has overflowed its stack
nuke-web3 Oct 3, 2022
1b6b2b8
??? enum shit
nuke-web3 Oct 3, 2022
d7c7130
benchmark tests passing
nuke-web3 Oct 3, 2022
ac9020d
named reserve impl, tests pass
nuke-web3 Oct 3, 2022
5d78e1d
test coverage safe mode
nuke-web3 Oct 3, 2022
f2f9435
weights.rs for safe mode and tx pause dummy files configured
nuke-web3 Oct 3, 2022
917961b
Fix benchmarks overflow
ggwpez Oct 4, 2022
f1daf3c
names, more comments safe-mode
nuke-web3 Oct 7, 2022
6bfff58
move back to stringy function inputs, with check on validity
nuke-web3 Oct 8, 2022
cc490ae
safe-mode fmt
nuke-web3 Oct 10, 2022
73225ce
broken?
nuke-web3 Oct 10, 2022
b95b286
tests passing, use FullNameOf to check tx-pause unfilterables
nuke-web3 Oct 11, 2022
bbe4ee5
add proxy and utility pallets to mock tx pause
nuke-web3 Oct 11, 2022
163ea73
safe-mode and utility and proxy in mock and tests
nuke-web3 Oct 11, 2022
adb3ab8
tests for proxy and utility for safe mode
nuke-web3 Oct 11, 2022
0538ecd
tests for proxy and utility for tx-pause, fmt
nuke-web3 Oct 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
progress on true call UI types
  • Loading branch information
nuke-web3 committed Sep 27, 2022
commit d076c92256d30e7d2f2389fa4b6f00e5c136bf29
23 changes: 18 additions & 5 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ parameter_types! {

const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct());

pub struct UnpausablePallets;
impl Contains<pallet_tx_pause::PalletNameOf<Runtime>> for UnpausablePallets {
pub struct UnpausableCalls; // TODO move to calls, use (..) to match on pallets like ProxyType
impl Contains<pallet_tx_pause::PalletNameOf<Runtime>> for UnpausableCalls {
fn contains(pallet: &pallet_tx_pause::PalletNameOf<Runtime>) -> bool {
pallet.as_ref() ==
<pallet_safe_mode::Pallet<Runtime> as PalletInfoAccess>::name()
Expand All @@ -211,9 +211,17 @@ impl Contains<pallet_tx_pause::PalletNameOf<Runtime>> for UnpausablePallets {
}
}

impl Contains<RuntimeCall> for MockUnpausableCalls {
fn contains(call: &RuntimeCall) -> bool {
matches!(call,
RuntimeCall::TxPause(..) |
RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive {..})
)
}
}

impl pallet_tx_pause::Config for Runtime {
type Event = Event;
type UnpausablePallets = UnpausablePallets;
type PauseOrigin = EnsureRoot<AccountId>;
type UnpauseOrigin = EnsureRoot<AccountId>;
type MaxNameLen = ConstU32<256>;
Expand All @@ -238,7 +246,7 @@ parameter_types! {
impl pallet_safe_mode::Config for Runtime {
type Event = Event;
type Currency = Balances;
type SafeModeFilter = Nothing; // TODO add TxPause pallet
type UnstoppableCalls = Nothing; // TODO add TxPause pallet
type ActivateDuration = ConstU32<{ 2 * DAYS }>;
type ExtendDuration = ConstU32<{ 1 * DAYS }>;
type EnableOrigin = EnsureRootWithSuccess<AccountId, BlockHeight>;
Expand All @@ -251,7 +259,7 @@ impl pallet_safe_mode::Config for Runtime {
}

impl frame_system::Config for Runtime {
type BaseCallFilter = InsideBoth<SafeMode, TxPause>;
type BaseCallFilter = TheseExcept<InsideBoth<SafeMode, TxPause>, UnpausableCalls>; // TODO consider Exclude or NotInside... so no config for UnpausableCalls unneeded ( see TheseExcept )
type BlockWeights = RuntimeBlockWeights;
type BlockLength = RuntimeBlockLength;
type DbWeight = RocksDbWeight;
Expand Down Expand Up @@ -326,6 +334,11 @@ parameter_types! {
MaxEncodedLen,
scale_info::TypeInfo,
)]

pub enum PausePresets {
...,

}
pub enum ProxyType {
Any,
NonTransfer,
Expand Down
8 changes: 4 additions & 4 deletions frame/safe-mode/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ pub mod pallet {

/// Contains all calls that can be dispatched even when the safe-mode is activated.
///
/// The `SafeMode` pallet is always included and does not need to be added here.
type SafeModeFilter: Contains<Self::RuntimeCall>;
/// The `SafeMode` pallet cannot disable it's own calls, and does not need to be explicitly added here.
type UnstoppableCalls: Contains<Self::RuntimeCall>;

/// How long the safe-mode will stay active when activated with [`Pallet::activate`].
#[pallet::constant]
Expand Down Expand Up @@ -317,7 +317,7 @@ pub mod pallet {

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
/// Automatically inactivates the safe-mode when the period ran out.
/// Automatically inactivates the safe-mode when the period runs out.
///
/// Bypasses any call filters to avoid getting rejected by them.
fn on_initialize(current: T::BlockNumber) -> Weight {
Expand Down Expand Up @@ -424,7 +424,7 @@ impl<T: Config> Pallet<T> {
}

if Self::is_activated() {
T::SafeModeFilter::contains(call)
T::UnstoppableCalls::contains(call)
} else {
true
}
Expand Down
6 changes: 3 additions & 3 deletions frame/safe-mode/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ impl pallet_balances::Config for Test {
}

/// Filter to block balance pallet calls
pub struct MockSafeModeFilter;
impl Contains<RuntimeCall> for MockSafeModeFilter {
pub struct MockUnstoppableCalls;
impl Contains<RuntimeCall> for MockUnstoppableCalls {
fn contains(call: &RuntimeCall) -> bool {
match call {
RuntimeCall::System(_) | RuntimeCall::SafeMode(_) => true,
Expand Down Expand Up @@ -216,7 +216,7 @@ impl SortedMembers<u64> for RepayOrigin {
impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type SafeModeFilter = MockSafeModeFilter;
type UnstoppableCalls = MockUnstoppableCalls;
type ActivateDuration = ActivateDuration;
type ExtendDuration = ExtendDuration;
type ActivateStakeAmount = ActivateStakeAmount;
Expand Down
60 changes: 43 additions & 17 deletions frame/tx-pause/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ pub mod weights;

use frame_support::{
pallet_prelude::*,
traits::{CallMetadata, Contains, GetCallMetadata},
traits::{CallMetadata, Contains, GetCallMetadata, IsSubType, IsType},
dispatch::GetDispatchInfo,
};
use frame_system::pallet_prelude::*;
use sp_std::{convert::TryInto, prelude::*};
use sp_runtime::{
traits::Dispatchable,
DispatchResult
};

pub use pallet::*;
pub use weights::*;
Expand All @@ -51,6 +56,14 @@ pub mod pallet {
/// The overarching event type.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

/// The overarching call type.
type RuntimeCall: Parameter
+ Dispatchable<Origin = Self::Origin>
+ GetDispatchInfo
+ From<frame_system::Call<Self>>
+ IsSubType<Call<Self>>
+ IsType<<Self as frame_system::Config>::RuntimeCall>;

/// The only origin that can pause calls.
type PauseOrigin: EnsureOrigin<Self::Origin>;

Expand All @@ -60,7 +73,7 @@ pub mod pallet {
/// Pallets that are safe and can never be paused.
///
/// The tx-pause pallet is always assumed to be safe itself.
type UnpausablePallets: Contains<PalletNameOf<Self>>;
type UnpausableCalls: Contains<<Self as Config>::RuntimeCall>;

/// Maximum length for pallet- and function-names.
///
Expand Down Expand Up @@ -144,33 +157,45 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::pause_call())]
pub fn pause_call(
origin: OriginFor<T>,
pallet: PalletNameOf<T>,
call: CallNameOf<T>,
call: Box<<T as Config>::RuntimeCall>,
) -> DispatchResult {
T::PauseOrigin::ensure_origin(origin)?;

Self::ensure_can_pause(&pallet, &call)?;
PausedCalls::<T>::insert((&pallet, &call), ());
Self::deposit_event(Event::CallPaused(pallet, call));
let CallMetadata { pallet_name, function_name } = call.get_call_metadata();

Self::ensure_can_pause(&pallet_name, &function_name)?;
PausedCalls::<T>::insert((&pallet_name, &function_name), ());
Self::deposit_event(Event::CallPaused(pallet_name, function_name));

Ok(())
}

// TODO add preset pause functionality (set of calls) See proxy and ProyType in node runtime
// pub fn pause_preset(
// origin: OriginFor<T>,
// preset: PausePresets,
// ) {
// loop
// do_pause_call() // run over a pre-config vec of calls for each type of PausePreset
// // we can use the same storage, a vec of all paused calls.
// }

/// Un-pause a call.
///
/// Can only be called by [`Config::UnpauseOrigin`].
/// Emits an [`Event::CallUnpaused`] event on success.
#[pallet::weight(T::WeightInfo::unpause_call())]
pub fn unpause_call(
origin: OriginFor<T>,
pallet: PalletNameOf<T>,
call: CallNameOf<T>,
call: Box<<T as Config>::RuntimeCall>,
) -> DispatchResult {
T::UnpauseOrigin::ensure_origin(origin)?;

Self::ensure_can_unpause(&pallet, &call)?;
PausedCalls::<T>::remove((&pallet, &call));
Self::deposit_event(Event::CallUnpaused(pallet, call));
let CallMetadata { pallet_name, function_name } = call.get_call_metadata();

Self::ensure_can_unpause(&pallet_name, &function_name)?;
PausedCalls::<T>::remove((&pallet_name, &function_name));
Self::deposit_event(Event::CallUnpaused(pallet_name, function_name));

Ok(())
}
Expand Down Expand Up @@ -203,9 +228,10 @@ impl<T: Config> Pallet<T> {
if pallet.as_ref() == <Self as PalletInfoAccess>::name().as_bytes().to_vec() {
return Err(Error::<T>::IsUnpausable)
}
if T::UnpausablePallets::contains(&pallet) {
return Err(Error::<T>::IsUnpausable)
}
// TODO need a way to see if any RuntimeCall matches the stringy pallet & call names here
// if T::UnpausableCalls::contains(&pallet, &call) {
// return Err(Error::<T>::IsUnpausable)
// }
if Self::is_paused(pallet, call) {
return Err(Error::<T>::IsPaused)
}
Expand Down Expand Up @@ -233,6 +259,6 @@ where
/// Return whether the call is allowed to be dispatched.
fn contains(call: &T::RuntimeCall) -> bool {
let CallMetadata { pallet_name, function_name } = call.get_call_metadata();
!Pallet::<T>::is_paused_unbound(pallet_name.into(), function_name.into())
!Pallet::<T>::is_paused_unbound(pallet_name.into(), function_name.into())
}
}
}
19 changes: 10 additions & 9 deletions frame/tx-pause/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,17 @@ parameter_types! {
pub const PauseTooLongNames: bool = false;
}

pub struct MockUnpausablePallets;

impl Contains<PalletNameOf<Test>> for MockUnpausablePallets {
fn contains(pallet: &PalletNameOf<Test>) -> bool {
let unpausables: Vec<PalletNameOf<Test>> =
vec![b"UnpausablePallet".to_vec().try_into().unwrap()];

unpausables.iter().any(|i| i == pallet)
pub struct MockUnpausableCalls;

impl Contains<RuntimeCall> for MockUnpausableCalls {
fn contains(call: &RuntimeCall) -> bool {
matches!(call,
RuntimeCall::TxPause(..) |
RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive {..})
)
}
}

// Required impl to use some <Configured Origin>::get() in tests
impl SortedMembers<u64> for PauseOrigin {
fn sorted_members() -> Vec<u64> {
Expand All @@ -114,7 +115,7 @@ impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type PauseOrigin = EnsureSignedBy<PauseOrigin, Self::AccountId>;
type UnpauseOrigin = EnsureSignedBy<UnpauseOrigin, Self::AccountId>;
type UnpausablePallets = MockUnpausablePallets;
type UnpausableCalls = MockUnpausableCalls;
type MaxNameLen = MaxNameLen;
type PauseTooLongNames = PauseTooLongNames;
type WeightInfo = ();
Expand Down