Crate pallet_tx_pause
source ·Expand description
§Transaction Pause
Allows dynamic, chain-state-based pausing and unpausing of specific extrinsics via call filters.
§Pallet API
See the pallet
module for more information about the interfaces this pallet exposes,
including its configuration trait, dispatchables, storage items, events, and errors.
§Overview
A dynamic call filter that can be controlled with extrinsics.
Pausing an extrinsic means that the extrinsic CANNOT be called again until it is unpaused.
The exception is calls that use dispatch_bypass_filter
, typically only with the root origin.
§Primary Features
- Calls that should never be paused can be added to a whitelist.
- Separate origins are configurable for pausing and pausing.
- Pausing is triggered using the string representation of the call.
- Pauses can target a single extrinsic or an entire pallet.
- Pauses can target future extrinsics or pallets.
§Example
Configuration of call filters:
impl frame_system::Config for Runtime {
// …
type BaseCallFilter = InsideBoth<DefaultFilter, TxPause>;
// …
}
Pause specific all:
#[test]
fn can_pause_specific_call() {
new_test_ext().execute_with(|| {
assert_ok!(call_transfer(1, 1).dispatch(RuntimeOrigin::signed(0)));
assert_ok!(TxPause::pause(
RuntimeOrigin::signed(mock::PauseOrigin::get()),
full_name::<Test>(b"Balances", b"transfer_allow_death")
));
assert_err!(
call_transfer(2, 1).dispatch(RuntimeOrigin::signed(2)),
frame_system::Error::<Test>::CallFiltered
);
assert_ok!(call_transfer_keep_alive(3, 1).dispatch(RuntimeOrigin::signed(3)));
});
}
Unpause specific all:
#[test]
fn can_unpause_specific_call() {
new_test_ext().execute_with(|| {
assert_ok!(TxPause::pause(
RuntimeOrigin::signed(mock::PauseOrigin::get()),
full_name::<Test>(b"Balances", b"transfer_allow_death"),
));
assert_err!(
call_transfer(2, 1).dispatch(RuntimeOrigin::signed(2)),
frame_system::Error::<Test>::CallFiltered
);
assert_ok!(TxPause::unpause(
RuntimeOrigin::signed(mock::UnpauseOrigin::get()),
full_name::<Test>(b"Balances", b"transfer_allow_death"),
));
assert_ok!(call_transfer(4, 1).dispatch(RuntimeOrigin::signed(0)));
});
}
Pause all calls in a pallet:
#[test]
fn can_pause_all_calls_in_pallet_except_on_whitelist() {
new_test_ext().execute_with(|| {
assert_ok!(call_transfer(1, 1).dispatch(RuntimeOrigin::signed(0)));
let batch_call =
RuntimeCall::Utility(pallet_utility::Call::batch { calls: vec![call_transfer(1, 1)] });
assert_ok!(batch_call.clone().dispatch(RuntimeOrigin::signed(0)));
assert_ok!(TxPause::pause(
RuntimeOrigin::signed(mock::PauseOrigin::get()),
full_name::<Test>(b"Utility", b"batch")
),);
assert_err!(
batch_call.clone().dispatch(RuntimeOrigin::signed(0)),
frame_system::Error::<Test>::CallFiltered
);
});
}
§Low Level / Implementation Details
§Use Cost
A storage map (PausedCalls
) is used to store currently paused calls.
Using the call filter will require a db read of that storage on each extrinsic.
Re-exports§
Modules§
- The
pallet
module in each FRAME pallet hosts the most important items needed to construct this pallet. - Autogenerated weights for
pallet_tx_pause
Type Aliases§
- The stringy name of a call (within a pallet) from [
GetCallMetadata
] forConfig::RuntimeCall
variants. - The stringy name of a pallet from [
GetCallMetadata
] forConfig::RuntimeCall
variants. - A fully specified pallet (
PalletNameOf
) and optional call (PalletCallNameOf
) to partially or fully specify an item a variant of aConfig::RuntimeCall
.