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 all commits
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
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions bin/node/cli/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,6 @@ pub fn testnet_genesis(
min_join_bond: 1 * DOLLARS,
..Default::default()
},
safe_mode: Default::default(),
tx_pause: Default::default(),
}
}

Expand Down
204 changes: 170 additions & 34 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ use frame_support::{
parameter_types,
traits::{
AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, ConstU32, Contains, Currency,
EitherOfDiverse, EqualPrivilegeOnly, Imbalance, InsideBoth, InstanceFilter,
KeyOwnerProofSystem, LockIdentifier, Nothing, OnUnbalanced, PalletInfoAccess,
U128CurrencyToVote,
EitherOfDiverse, EnsureOrigin, EqualPrivilegeOnly, Imbalance, InsideBoth, InstanceFilter,
KeyOwnerProofSystem, LockIdentifier, Nothing, OnUnbalanced, U128CurrencyToVote,
},
weights::{
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
Expand All @@ -45,7 +44,7 @@ use frame_support::{
};
use frame_system::{
limits::{BlockLength, BlockWeights},
EnsureRoot, EnsureRootWithSuccess, EnsureSigned,
EnsureRoot, EnsureRootWithSuccess, EnsureSigned, RawOrigin,
};
pub use node_primitives::{AccountId, Signature};
use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment};
Expand Down Expand Up @@ -201,57 +200,189 @@ 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 {
fn contains(pallet: &pallet_tx_pause::PalletNameOf<Runtime>) -> bool {
pallet.as_ref() ==
<pallet_safe_mode::Pallet<Runtime> as PalletInfoAccess>::name()
.as_bytes()
.to_vec()
/// Filter to block balance pallet calls
/// Used for both SafeMode and TxPause pallets
/// Therefor we include both so they cannot affect each other
pub struct UnfilterableCalls;
impl Contains<RuntimeCall> for UnfilterableCalls {
fn contains(call: &RuntimeCall) -> bool {
match call {
RuntimeCall::System(_) | RuntimeCall::SafeMode(_) | RuntimeCall::TxPause(_) => true,
RuntimeCall::Balances(_) => false,
_ => false,
}
}
}

use pallet_tx_pause::FullNameOf;
pub struct UnfilterableCallNames;
/// Make Balances::transfer_keep_alive unfilterable, accept all others.
impl Contains<FullNameOf<Runtime>> for UnfilterableCallNames {
fn contains(full_name: &FullNameOf<Runtime>) -> bool {
let unpausables: Vec<FullNameOf<Runtime>> = vec![(
b"Balances".to_vec().try_into().unwrap(),
Some(b"transfer_keep_alive".to_vec().try_into().unwrap()),
)];

for unpausable_call in unpausables {
let (pallet_name, maybe_call_name) = full_name;
if pallet_name == &unpausable_call.0 {
if unpausable_call.1.is_none() {
return true
}
return maybe_call_name == &unpausable_call.1
}
}

false
}
}

impl pallet_tx_pause::Config for Runtime {
type Event = Event;
type UnpausablePallets = UnpausablePallets;
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type PauseOrigin = EnsureRoot<AccountId>;
type UnpauseOrigin = EnsureRoot<AccountId>;
type UnfilterableCallNames = UnfilterableCallNames;
type MaxNameLen = ConstU32<256>;
type PauseTooLongNames = ConstBool<true>;
type WeightInfo = pallet_tx_pause::weights::SubstrateWeight<Runtime>;
}

parameter_types! {
// signed config
pub const ActivateStakeAmount: Balance = 1 * DOLLARS; //TODO This needs to be something sensible for the implications of enablement!
pub const ExtendStakeAmount: Balance = 1 * DOLLARS; //TODO This needs to be something sensible for the implications of enablement!
pub BlockHeight: BlockNumber = System::block_number(); // TODO ensure this plus config below is correct
/// An origin that can enable the safe-mode by force.
pub enum ForceActivateOrigin {
Weak,
Medium,
Strong,
}

/// An origin that can extend the safe-mode by force.
pub enum ForceExtendOrigin {
Weak,
Medium,
Strong,
}

impl ForceActivateOrigin {
/// The duration of how long the safe-mode will be activated.
pub fn duration(&self) -> u32 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will prefer to make it

/// An origin that can enable the safe-mode by force.
 pub enum ForceActivateOrigin {
 	Weak = 5,
 	Medium = 7,
 	Strong = 11,
 }

so that frontend doesn't need to hardcod those number once more

Copy link
Contributor Author

@nuke-web3 nuke-web3 Oct 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool - TIL https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-fieldless-enumerations is a thing

So this example diff works to yield an integer castable item, so BlockNumber works fine.

But you cannot assign the same value for any origin this way as it would conflict:

enum SharedDiscriminantError {
    SharedA = 1,
    SharedB = 1
}

I think this restriction would be OK, but hope there is a better method to get there... Open to ideas.

match self {
Self::Weak => 5,
Self::Medium => 7,
Self::Strong => 11,
}
}

/// Account id of the origin.
pub fn acc(&self) -> AccountId {
match self {
Self::Weak => sp_core::ed25519::Public::from_raw([0; 32]).into(),
Self::Medium => sp_core::ed25519::Public::from_raw([1; 32]).into(),
Self::Strong => sp_core::ed25519::Public::from_raw([2; 32]).into(),
}
}

/// Signed origin.
pub fn signed(&self) -> <Runtime as frame_system::Config>::Origin {
RawOrigin::Signed(self.acc()).into()
}
}

impl ForceExtendOrigin {
/// The duration of how long the safe-mode will be extended.
pub fn duration(&self) -> u32 {
match self {
Self::Weak => 13,
Self::Medium => 17,
Self::Strong => 19,
}
}

/// Account id of the origin.
pub fn acc(&self) -> AccountId {
match self {
Self::Weak => sp_core::ed25519::Public::from_raw([0; 32]).into(),
Self::Medium => sp_core::ed25519::Public::from_raw([1; 32]).into(),
Self::Strong => sp_core::ed25519::Public::from_raw([2; 32]).into(),
}
}

/// Signed origin.
pub fn signed(&self) -> <Runtime as frame_system::Config>::Origin {
RawOrigin::Signed(self.acc()).into()
}
}

impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>> EnsureOrigin<O>
for ForceActivateOrigin
{
type Success = u32;

fn try_origin(o: O) -> Result<Self::Success, O> {
o.into().and_then(|o| match o {
RawOrigin::Signed(acc) if acc == ForceActivateOrigin::Weak.acc() =>
Ok(ForceActivateOrigin::Weak.duration()),
RawOrigin::Signed(acc) if acc == ForceActivateOrigin::Medium.acc() =>
Ok(ForceActivateOrigin::Medium.duration()),
RawOrigin::Signed(acc) if acc == ForceActivateOrigin::Strong.acc() =>
Ok(ForceActivateOrigin::Strong.duration()),
r => Err(O::from(r)),
})
}

#[cfg(feature = "runtime-benchmarks")]
fn successful_origin() -> O {
O::from(RawOrigin::Signed(ForceActivateOrigin::Strong.acc()))
}
}

impl<O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>> EnsureOrigin<O>
for ForceExtendOrigin
{
type Success = u32;

fn try_origin(o: O) -> Result<Self::Success, O> {
o.into().and_then(|o| match o {
RawOrigin::Signed(acc) if acc == ForceExtendOrigin::Weak.acc() =>
Ok(ForceExtendOrigin::Weak.duration()),
RawOrigin::Signed(acc) if acc == ForceExtendOrigin::Medium.acc() =>
Ok(ForceExtendOrigin::Medium.duration()),
RawOrigin::Signed(acc) if acc == ForceExtendOrigin::Strong.acc() =>
Ok(ForceExtendOrigin::Strong.duration()),
r => Err(O::from(r)),
})
}

#[cfg(feature = "runtime-benchmarks")]
fn successful_origin() -> O {
O::from(RawOrigin::Signed(ForceActivateOrigin::Strong.acc()))
}
}

parameter_types! {
// signed config
pub const ActivateStakeAmount: Balance = 1 * DOLLARS; //TODO This needs to be something sensible for the implications of enablement!
pub const ExtendStakeAmount: Balance = 1 * DOLLARS; //TODO This needs to be something sensible for the implications of enablement!
pub BlockHeight: BlockNumber = System::block_number(); // TODO ensure this plus config below is correct
pub const SignedActivationDuration: u32 = 3;
pub const SignedExtendDuration: u32 = 30;
pub const ActivateReservationAmount: Balance = 10 * DOLLARS; //TODO This needs to be something sensible for the implications of enablement!
pub const ExtendReservationAmount: Balance = 10 * DOLLARS; //TODO This needs to be something sensible for the implications of enablement!
}

impl pallet_safe_mode::Config for Runtime {
type Event = Event;
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type SafeModeFilter = Nothing; // TODO add TxPause pallet
type ActivateDuration = ConstU32<{ 2 * DAYS }>;
type ExtendDuration = ConstU32<{ 1 * DAYS }>;
type EnableOrigin = EnsureRootWithSuccess<AccountId, BlockHeight>;
type ExtendOrigin = EnsureRootWithSuccess<AccountId, BlockHeight>;
type DeactivateOrigin = EnsureRoot<AccountId>;
type RepayOrigin = EnsureRoot<AccountId>;
type ActivateStakeAmount = ActivateStakeAmount;
type ExtendStakeAmount = ExtendStakeAmount;
type UnfilterableCalls = UnfilterableCalls;
type SignedActivationDuration = ConstU32<{ 2 * DAYS }>;
type ActivateReservationAmount = ActivateReservationAmount;
type SignedExtendDuration = ConstU32<{ 1 * DAYS }>;
type ExtendReservationAmount = ExtendReservationAmount;
type ForceActivateOrigin = ForceActivateOrigin;
type ForceExtendOrigin = ForceExtendOrigin;
type ForceDeactivateOrigin = EnsureRoot<Self::AccountId>;
type RepayOrigin = EnsureRoot<Self::AccountId>;
type WeightInfo = pallet_safe_mode::weights::SubstrateWeight<Runtime>;
}

impl frame_system::Config for Runtime {
type BaseCallFilter = InsideBoth<SafeMode, TxPause>;
type BaseCallFilter = InsideBoth<SafeMode, TxPause>; // TODO consider Exclude or NotInside for UnfilterableCalls -> see TheseExcept )
type BlockWeights = RuntimeBlockWeights;
type BlockLength = RuntimeBlockLength;
type DbWeight = RocksDbWeight;
Expand Down Expand Up @@ -312,6 +443,11 @@ parameter_types! {
pub const AnnouncementDepositFactor: Balance = deposit(0, 66);
}

// pub enum PausePresets {
// ..., // todo

// }

/// The type used to represent the kinds of proxying allowed.
#[derive(
Copy,
Expand Down Expand Up @@ -482,7 +618,7 @@ parameter_types! {
impl pallet_balances::Config for Runtime {
type MaxLocks = MaxLocks;
type MaxReserves = MaxReserves;
type ReserveIdentifier = [u8; 8];
type ReserveIdentifier = Self::BlockNumber;
type Balance = Balance;
type DustRemoval = ();
type RuntimeEvent = RuntimeEvent;
Expand Down
13 changes: 12 additions & 1 deletion frame/safe-mode/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,39 @@ frame-system = { version = "4.0.0-dev", default-features = false, path = "../sys
scale-info = { version = "2.0.1", default-features = false, features = ["derive"] }
sp-runtime = { version = "6.0.0", default-features = false, path = "../../primitives/runtime" }
sp-std = { version = "4.0.0", default-features = false, path = "../../primitives/std" }
pallet-balances = { version = "4.0.0-dev", path = "../balances", default-features = false, optional = true }
pallet-utility = { version = "4.0.0-dev", path = "../utility", default-features = false, optional = true }
pallet-proxy = { version = "4.0.0-dev", path = "../proxy", default-features = false, optional = true }

[dev-dependencies]
sp-core = { version = "6.0.0", path = "../../primitives/core" }
sp-std = { version = "4.0.0", path = "../../primitives/std" }
sp-io = { version = "6.0.0", path = "../../primitives/io" }
pallet-balances = { version = "4.0.0-dev", path = "../balances" }
pallet-utility = { version = "4.0.0-dev", path = "../utility" }
pallet-proxy = { version = "4.0.0-dev", path = "../proxy" }

[features]
default = ["std"]
std = [
"codec/std",
"scale-info/std",
"frame-benchmarking/std",
"frame-support/std",
"frame-system/std",
"frame-support/std",
"pallet-balances?/std",
"pallet-utility?/std",
"pallet-proxy?/std",
"sp-runtime/std",
"sp-std/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-utility/runtime-benchmarks",
"pallet-proxy/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
Expand Down
Loading