From 2d3f7a2a216842877eeadaec026276e02d276ab7 Mon Sep 17 00:00:00 2001 From: Javier Viola <363911+pepoviola@users.noreply.github.com> Date: Tue, 21 Jan 2025 00:38:39 +0100 Subject: [PATCH] Revert "[Staking] Currency <> Fungible migration (#5501)" This reverts commit f5673cf260ba08fbc04667b1fcd0e635d87e6451. --- Cargo.lock | 24 +- Cargo.toml | 1 + polkadot/runtime/test-runtime/src/lib.rs | 2 - polkadot/runtime/westend/src/lib.rs | 2 - polkadot/runtime/westend/src/tests.rs | 99 +- .../westend/src/weights/pallet_staking.rs | 386 ++++---- prdoc/pr_5501.prdoc | 47 - substrate/bin/node/runtime/src/lib.rs | 33 +- substrate/bin/node/testing/src/genesis.rs | 4 +- substrate/frame/babe/src/mock.rs | 1 - substrate/frame/beefy/src/mock.rs | 1 - substrate/frame/delegated-staking/src/lib.rs | 2 +- substrate/frame/delegated-staking/src/mock.rs | 1 - .../frame/delegated-staking/src/tests.rs | 11 +- .../frame/delegated-staking/src/types.rs | 6 + .../test-staking-e2e/Cargo.toml | 2 - .../test-staking-e2e/src/lib.rs | 32 +- .../test-staking-e2e/src/mock.rs | 39 +- substrate/frame/fast-unstake/src/mock.rs | 6 +- substrate/frame/fast-unstake/src/tests.rs | 16 +- substrate/frame/grandpa/src/mock.rs | 1 - .../benchmarking/src/inner.rs | 75 +- .../nomination-pools/benchmarking/src/mock.rs | 1 - .../frame/nomination-pools/src/adapter.rs | 6 +- substrate/frame/nomination-pools/src/mock.rs | 202 +--- substrate/frame/nomination-pools/src/tests.rs | 326 +++++-- .../test-delegate-stake/src/lib.rs | 22 +- .../test-delegate-stake/src/mock.rs | 4 - .../test-transfer-stake/Cargo.toml | 39 + .../test-transfer-stake/src/lib.rs | 912 ++++++++++++++++++ .../test-transfer-stake/src/mock.rs | 231 +++++ .../frame/offences/benchmarking/src/inner.rs | 10 +- .../frame/offences/benchmarking/src/mock.rs | 1 - substrate/frame/root-offences/src/mock.rs | 9 +- .../frame/session/benchmarking/src/mock.rs | 1 - substrate/frame/staking/Cargo.toml | 1 - substrate/frame/staking/src/asset.rs | 88 +- substrate/frame/staking/src/benchmarking.rs | 23 +- substrate/frame/staking/src/ledger.rs | 10 +- substrate/frame/staking/src/lib.rs | 12 +- substrate/frame/staking/src/mock.rs | 47 +- substrate/frame/staking/src/pallet/impls.rs | 121 +-- substrate/frame/staking/src/pallet/mod.rs | 80 +- substrate/frame/staking/src/testing_utils.rs | 18 - substrate/frame/staking/src/tests.rs | 854 +++++----------- substrate/frame/staking/src/weights.rs | 755 +++++++-------- substrate/primitives/staking/src/lib.rs | 2 +- 47 files changed, 2466 insertions(+), 2100 deletions(-) delete mode 100644 prdoc/pr_5501.prdoc create mode 100644 substrate/frame/nomination-pools/test-transfer-stake/Cargo.toml create mode 100644 substrate/frame/nomination-pools/test-transfer-stake/src/lib.rs create mode 100644 substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs diff --git a/Cargo.lock b/Cargo.lock index 397d0c7fe823..b71c1890ef29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13400,7 +13400,6 @@ dependencies = [ "log", "pallet-bags-list 27.0.0", "pallet-balances 28.0.0", - "pallet-delegated-staking 1.0.0", "pallet-election-provider-multi-phase 27.0.0", "pallet-nomination-pools 25.0.0", "pallet-session 28.0.0", @@ -14485,6 +14484,29 @@ dependencies = [ "sp-tracing 16.0.0", ] +[[package]] +name = "pallet-nomination-pools-test-transfer-stake" +version = "1.0.0" +dependencies = [ + "frame-election-provider-support 28.0.0", + "frame-support 28.0.0", + "frame-system 28.0.0", + "log", + "pallet-bags-list 27.0.0", + "pallet-balances 28.0.0", + "pallet-nomination-pools 25.0.0", + "pallet-staking 28.0.0", + "pallet-staking-reward-curve", + "pallet-timestamp 27.0.0", + "parity-scale-codec", + "scale-info", + "sp-core 28.0.0", + "sp-io 30.0.0", + "sp-runtime 31.0.1", + "sp-staking 26.0.0", + "sp-tracing 16.0.0", +] + [[package]] name = "pallet-offences" version = "27.0.0" diff --git a/Cargo.toml b/Cargo.toml index 18c1dd2c68d2..e57c648120a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -389,6 +389,7 @@ members = [ "substrate/frame/nomination-pools/fuzzer", "substrate/frame/nomination-pools/runtime-api", "substrate/frame/nomination-pools/test-delegate-stake", + "substrate/frame/nomination-pools/test-transfer-stake", "substrate/frame/offences", "substrate/frame/offences/benchmarking", "substrate/frame/paged-list", diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index cdf6fa92da2f..4f9ba8d8508c 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -366,13 +366,11 @@ impl onchain::Config for OnChainSeqPhragmen { const MAX_QUOTA_NOMINATIONS: u32 = 16; impl pallet_staking::Config for Runtime { - type OldCurrency = Balances; type Currency = Balances; type CurrencyBalance = Balance; type UnixTime = Timestamp; type CurrencyToVote = polkadot_runtime_common::CurrencyToVote; type RewardRemainder = (); - type RuntimeHoldReason = RuntimeHoldReason; type RuntimeEvent = RuntimeEvent; type Slash = (); type Reward = (); diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index a9ba0778fe0e..c85fc59c590e 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -728,10 +728,8 @@ parameter_types! { } impl pallet_staking::Config for Runtime { - type OldCurrency = Balances; type Currency = Balances; type CurrencyBalance = Balance; - type RuntimeHoldReason = RuntimeHoldReason; type UnixTime = Timestamp; type CurrencyToVote = CurrencyToVote; type RewardRemainder = (); diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs index 65b81cc00f06..fcdaf7ff2de6 100644 --- a/polkadot/runtime/westend/src/tests.rs +++ b/polkadot/runtime/westend/src/tests.rs @@ -155,27 +155,25 @@ mod remote_tests { let transport: Transport = var("WS").unwrap_or("ws://127.0.0.1:9900".to_string()).into(); let maybe_state_snapshot: Option = var("SNAP").map(|s| s.into()).ok(); - let online_config = OnlineConfig { - transport, - state_snapshot: maybe_state_snapshot.clone(), - child_trie: false, - pallets: vec![ - "Staking".into(), - "System".into(), - "Balances".into(), - "NominationPools".into(), - "DelegatedStaking".into(), - ], - ..Default::default() - }; let mut ext = Builder::::default() .mode(if let Some(state_snapshot) = maybe_state_snapshot { Mode::OfflineOrElseOnline( OfflineConfig { state_snapshot: state_snapshot.clone() }, - online_config, + OnlineConfig { + transport, + state_snapshot: Some(state_snapshot), + pallets: vec![ + "staking".into(), + "system".into(), + "balances".into(), + "nomination-pools".into(), + "delegated-staking".into(), + ], + ..Default::default() + }, ) } else { - Mode::Online(online_config) + Mode::Online(OnlineConfig { transport, ..Default::default() }) }) .build() .await @@ -243,77 +241,6 @@ mod remote_tests { ); }); } - - #[tokio::test] - async fn staking_curr_fun_migrate() { - // Intended to be run only manually. - if var("RUN_MIGRATION_TESTS").is_err() { - return; - } - sp_tracing::try_init_simple(); - - let transport: Transport = var("WS").unwrap_or("ws://127.0.0.1:9944".to_string()).into(); - let maybe_state_snapshot: Option = var("SNAP").map(|s| s.into()).ok(); - let online_config = OnlineConfig { - transport, - state_snapshot: maybe_state_snapshot.clone(), - child_trie: false, - pallets: vec!["Staking".into(), "System".into(), "Balances".into()], - ..Default::default() - }; - let mut ext = Builder::::default() - .mode(if let Some(state_snapshot) = maybe_state_snapshot { - Mode::OfflineOrElseOnline( - OfflineConfig { state_snapshot: state_snapshot.clone() }, - online_config, - ) - } else { - Mode::Online(online_config) - }) - .build() - .await - .unwrap(); - ext.execute_with(|| { - // create an account with some balance - let alice = AccountId::from([1u8; 32]); - use frame_support::traits::Currency; - let _ = Balances::deposit_creating(&alice, 100_000 * UNITS); - - let mut success = 0; - let mut err = 0; - let mut force_withdraw_acc = 0; - // iterate over all pools - pallet_staking::Ledger::::iter().for_each(|(ctrl, ledger)| { - match pallet_staking::Pallet::::migrate_currency( - RuntimeOrigin::signed(alice.clone()).into(), - ledger.stash.clone(), - ) { - Ok(_) => { - let updated_ledger = - pallet_staking::Ledger::::get(&ctrl).expect("ledger exists"); - let force_withdraw = ledger.total - updated_ledger.total; - if force_withdraw > 0 { - force_withdraw_acc += force_withdraw; - log::info!(target: "remote_test", "Force withdraw from stash {:?}: value {:?}", ledger.stash, force_withdraw); - } - success += 1; - }, - Err(e) => { - log::error!(target: "remote_test", "Error migrating {:?}: {:?}", ledger.stash, e); - err += 1; - }, - } - }); - - log::info!( - target: "remote_test", - "Migration stats: success: {}, err: {}, total force withdrawn stake: {}", - success, - err, - force_withdraw_acc - ); - }); - } } #[test] diff --git a/polkadot/runtime/westend/src/weights/pallet_staking.rs b/polkadot/runtime/westend/src/weights/pallet_staking.rs index f1e7f5ba1576..393fa0b37176 100644 --- a/polkadot/runtime/westend/src/weights/pallet_staking.rs +++ b/polkadot/runtime/westend/src/weights/pallet_staking.rs @@ -17,9 +17,9 @@ //! Autogenerated weights for `pallet_staking` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-09-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-03-27, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-obbyq9g6-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-h2rr8wx7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("westend-dev")`, DB CACHE: 1024 // Executed Command: @@ -52,19 +52,19 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn bond() -> Weight { // Proof Size summary in bytes: - // Measured: `1035` - // Estimated: `4556` - // Minimum execution time: 70_147_000 picoseconds. - Weight::from_parts(71_795_000, 0) - .saturating_add(Weight::from_parts(0, 4556)) + // Measured: `1009` + // Estimated: `4764` + // Minimum execution time: 40_585_000 picoseconds. + Weight::from_parts(41_800_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) .saturating_add(T::DbWeight::get().reads(4)) .saturating_add(T::DbWeight::get().writes(4)) } @@ -72,20 +72,20 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn bond_extra() -> Weight { // Proof Size summary in bytes: - // Measured: `1947` + // Measured: `1921` // Estimated: `8877` - // Minimum execution time: 125_203_000 picoseconds. - Weight::from_parts(128_088_000, 0) + // Minimum execution time: 81_809_000 picoseconds. + Weight::from_parts(84_387_000, 0) .saturating_add(Weight::from_parts(0, 8877)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(7)) @@ -100,23 +100,23 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn unbond() -> Weight { // Proof Size summary in bytes: - // Measured: `2051` + // Measured: `2128` // Estimated: `8877` - // Minimum execution time: 101_991_000 picoseconds. - Weight::from_parts(104_567_000, 0) + // Minimum execution time: 89_419_000 picoseconds. + Weight::from_parts(91_237_000, 0) .saturating_add(Weight::from_parts(0, 8877)) .saturating_add(T::DbWeight::get().reads(12)) - .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().writes(7)) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -124,25 +124,23 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) - /// Storage: `DelegatedStaking::Agents` (r:1 w:0) - /// Proof: `DelegatedStaking::Agents` (`max_values`: None, `max_size`: Some(120), added: 2595, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1253` - // Estimated: `4556` - // Minimum execution time: 76_450_000 picoseconds. - Weight::from_parts(78_836_594, 0) - .saturating_add(Weight::from_parts(0, 4556)) - // Standard Error: 1_529 - .saturating_add(Weight::from_parts(66_662, 0).saturating_mul(s.into())) - .saturating_add(T::DbWeight::get().reads(7)) + // Measured: `1223` + // Estimated: `4764` + // Minimum execution time: 45_152_000 picoseconds. + Weight::from_parts(46_460_819, 0) + .saturating_add(Weight::from_parts(0, 4764)) + // Standard Error: 972 + .saturating_add(Weight::from_parts(55_473, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Staking::Ledger` (r:1 w:1) @@ -153,10 +151,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::SlashingSpans` (r:1 w:1) /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Staking::VirtualStakers` (r:1 w:1) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) @@ -176,15 +174,15 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_kill(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2153 + s * (4 ±0)` + // Measured: `2127 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 121_962_000 picoseconds. - Weight::from_parts(131_000_151, 0) + // Minimum execution time: 82_762_000 picoseconds. + Weight::from_parts(91_035_077, 0) .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 3_846 - .saturating_add(Weight::from_parts(1_277_843, 0).saturating_mul(s.into())) + // Standard Error: 3_771 + .saturating_add(Weight::from_parts(1_217_871, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(13)) - .saturating_add(T::DbWeight::get().writes(12)) + .saturating_add(T::DbWeight::get().writes(11)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -212,10 +210,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn validate() -> Weight { // Proof Size summary in bytes: - // Measured: `1334` + // Measured: `1301` // Estimated: `4556` - // Minimum execution time: 66_450_000 picoseconds. - Weight::from_parts(68_302_000, 0) + // Minimum execution time: 50_555_000 picoseconds. + Weight::from_parts(52_052_000, 0) .saturating_add(Weight::from_parts(0, 4556)) .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(5)) @@ -229,13 +227,13 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `k` is `[1, 128]`. fn kick(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1811 + k * (572 ±0)` + // Measured: `1778 + k * (572 ±0)` // Estimated: `4556 + k * (3033 ±0)` - // Minimum execution time: 43_875_000 picoseconds. - Weight::from_parts(47_332_240, 0) + // Minimum execution time: 35_037_000 picoseconds. + Weight::from_parts(35_081_878, 0) .saturating_add(Weight::from_parts(0, 4556)) - // Standard Error: 6_530 - .saturating_add(Weight::from_parts(7_398_001, 0).saturating_mul(k.into())) + // Standard Error: 5_473 + .saturating_add(Weight::from_parts(6_667_924, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -266,13 +264,13 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `n` is `[1, 16]`. fn nominate(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1830 + n * (102 ±0)` + // Measured: `1797 + n * (102 ±0)` // Estimated: `6248 + n * (2520 ±0)` - // Minimum execution time: 80_640_000 picoseconds. - Weight::from_parts(78_801_092, 0) + // Minimum execution time: 62_098_000 picoseconds. + Weight::from_parts(60_154_061, 0) .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 22_249 - .saturating_add(Weight::from_parts(4_996_344, 0).saturating_mul(n.into())) + // Standard Error: 19_257 + .saturating_add(Weight::from_parts(3_839_855, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(6)) @@ -296,10 +294,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill() -> Weight { // Proof Size summary in bytes: - // Measured: `1780` + // Measured: `1747` // Estimated: `6248` - // Minimum execution time: 71_494_000 picoseconds. - Weight::from_parts(73_487_000, 0) + // Minimum execution time: 54_993_000 picoseconds. + Weight::from_parts(56_698_000, 0) .saturating_add(Weight::from_parts(0, 6248)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(6)) @@ -312,10 +310,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn set_payee() -> Weight { // Proof Size summary in bytes: - // Measured: `898` + // Measured: `865` // Estimated: `4556` - // Minimum execution time: 24_310_000 picoseconds. - Weight::from_parts(24_676_000, 0) + // Minimum execution time: 18_100_000 picoseconds. + Weight::from_parts(18_547_000, 0) .saturating_add(Weight::from_parts(0, 4556)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -328,10 +326,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn update_payee() -> Weight { // Proof Size summary in bytes: - // Measured: `965` + // Measured: `932` // Estimated: `4556` - // Minimum execution time: 31_348_000 picoseconds. - Weight::from_parts(32_384_000, 0) + // Minimum execution time: 23_428_000 picoseconds. + Weight::from_parts(24_080_000, 0) .saturating_add(Weight::from_parts(0, 4556)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -342,10 +340,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) fn set_controller() -> Weight { // Proof Size summary in bytes: - // Measured: `898` + // Measured: `865` // Estimated: `8122` - // Minimum execution time: 27_537_000 picoseconds. - Weight::from_parts(28_714_000, 0) + // Minimum execution time: 21_159_000 picoseconds. + Weight::from_parts(21_706_000, 0) .saturating_add(Weight::from_parts(0, 8122)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -356,8 +354,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_362_000 picoseconds. - Weight::from_parts(2_518_000, 0) + // Minimum execution time: 1_910_000 picoseconds. + Weight::from_parts(2_003_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -367,8 +365,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_752_000 picoseconds. - Weight::from_parts(8_105_000, 0) + // Minimum execution time: 7_076_000 picoseconds. + Weight::from_parts(7_349_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -378,8 +376,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_868_000 picoseconds. - Weight::from_parts(8_175_000, 0) + // Minimum execution time: 7_067_000 picoseconds. + Weight::from_parts(7_389_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -389,8 +387,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_945_000 picoseconds. - Weight::from_parts(8_203_000, 0) + // Minimum execution time: 7_148_000 picoseconds. + Weight::from_parts(7_446_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -401,11 +399,11 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_458_000 picoseconds. - Weight::from_parts(2_815_664, 0) + // Minimum execution time: 2_025_000 picoseconds. + Weight::from_parts(2_229_953, 0) .saturating_add(Weight::from_parts(0, 0)) // Standard Error: 67 - .saturating_add(Weight::from_parts(12_287, 0).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(11_785, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Staking::Ledger` (r:1502 w:1502) @@ -417,13 +415,13 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `i` is `[0, 751]`. fn deprecate_controller_batch(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `713 + i * (227 ±0)` + // Measured: `680 + i * (227 ±0)` // Estimated: `990 + i * (7132 ±0)` - // Minimum execution time: 4_976_000 picoseconds. - Weight::from_parts(5_102_000, 0) + // Minimum execution time: 4_321_000 picoseconds. + Weight::from_parts(4_407_000, 0) .saturating_add(Weight::from_parts(0, 990)) - // Standard Error: 36_458 - .saturating_add(Weight::from_parts(25_359_275, 0).saturating_mul(i.into())) + // Standard Error: 37_239 + .saturating_add(Weight::from_parts(21_300_598, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(i.into()))) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 7132).saturating_mul(i.into())) @@ -434,10 +432,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:1) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) @@ -459,15 +457,15 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `s` is `[0, 100]`. fn force_unstake(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2153 + s * (4 ±0)` + // Measured: `2127 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 116_776_000 picoseconds. - Weight::from_parts(125_460_389, 0) + // Minimum execution time: 78_908_000 picoseconds. + Weight::from_parts(84_886_373, 0) .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 3_095 - .saturating_add(Weight::from_parts(1_300_502, 0).saturating_mul(s.into())) + // Standard Error: 3_376 + .saturating_add(Weight::from_parts(1_217_850, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(13)) - .saturating_add(T::DbWeight::get().writes(13)) + .saturating_add(T::DbWeight::get().writes(12)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -476,13 +474,13 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `s` is `[1, 1000]`. fn cancel_deferred_slash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `66672` - // Estimated: `70137` - // Minimum execution time: 135_135_000 picoseconds. - Weight::from_parts(937_565_332, 0) - .saturating_add(Weight::from_parts(0, 70137)) - // Standard Error: 57_675 - .saturating_add(Weight::from_parts(4_828_080, 0).saturating_mul(s.into())) + // Measured: `66639` + // Estimated: `70104` + // Minimum execution time: 136_389_000 picoseconds. + Weight::from_parts(1_207_241_524, 0) + .saturating_add(Weight::from_parts(0, 70104)) + // Standard Error: 77_138 + .saturating_add(Weight::from_parts(6_443_948, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -500,10 +498,12 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::ErasValidatorReward` (r:1 w:0) /// Proof: `Staking::ErasValidatorReward` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:65 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:65 w:65) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:65 w:65) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:65 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:65 w:65) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::ErasStakersPaged` (r:1 w:0) /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::ErasRewardPoints` (r:1 w:0) @@ -512,32 +512,30 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::ErasValidatorPrefs` (`max_values`: None, `max_size`: Some(57), added: 2532, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:65 w:0) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:65 w:65) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 64]`. fn payout_stakers_alive_staked(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `8275 + n * (389 ±0)` - // Estimated: `10805 + n * (3566 ±0)` - // Minimum execution time: 180_144_000 picoseconds. - Weight::from_parts(237_134_733, 0) - .saturating_add(Weight::from_parts(0, 10805)) - // Standard Error: 52_498 - .saturating_add(Weight::from_parts(73_633_326, 0).saturating_mul(n.into())) + // Measured: `8249 + n * (396 ±0)` + // Estimated: `10779 + n * (3774 ±0)` + // Minimum execution time: 130_222_000 picoseconds. + Weight::from_parts(167_236_150, 0) + .saturating_add(Weight::from_parts(0, 10779)) + // Standard Error: 34_051 + .saturating_add(Weight::from_parts(39_899_917, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(14)) .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(4)) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(n.into())) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) @@ -545,26 +543,26 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `l` is `[1, 32]`. fn rebond(l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1845 + l * (5 ±0)` + // Measured: `1922 + l * (5 ±0)` // Estimated: `8877` - // Minimum execution time: 89_307_000 picoseconds. - Weight::from_parts(92_902_634, 0) + // Minimum execution time: 79_136_000 picoseconds. + Weight::from_parts(82_129_497, 0) .saturating_add(Weight::from_parts(0, 8877)) - // Standard Error: 4_446 - .saturating_add(Weight::from_parts(73_546, 0).saturating_mul(l.into())) + // Standard Error: 3_867 + .saturating_add(Weight::from_parts(75_156, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(6)) + .saturating_add(T::DbWeight::get().writes(7)) } - /// Storage: `Staking::VirtualStakers` (r:1 w:1) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:1) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::SlashingSpans` (r:1 w:1) /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) @@ -584,15 +582,15 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `s` is `[1, 100]`. fn reap_stash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2153 + s * (4 ±0)` + // Measured: `2127 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 130_544_000 picoseconds. - Weight::from_parts(133_260_598, 0) + // Minimum execution time: 89_375_000 picoseconds. + Weight::from_parts(91_224_907, 0) .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 3_545 - .saturating_add(Weight::from_parts(1_313_348, 0).saturating_mul(s.into())) + // Standard Error: 3_424 + .saturating_add(Weight::from_parts(1_219_542, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(12)) - .saturating_add(T::DbWeight::get().writes(12)) + .saturating_add(T::DbWeight::get().writes(11)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -635,14 +633,14 @@ impl pallet_staking::WeightInfo for WeightInfo { fn new_era(v: u32, n: u32, ) -> Weight { // Proof Size summary in bytes: // Measured: `0 + n * (716 ±0) + v * (3594 ±0)` - // Estimated: `456136 + n * (3566 ±4) + v * (3566 ±40)` - // Minimum execution time: 654_756_000 picoseconds. - Weight::from_parts(658_861_000, 0) + // Estimated: `456136 + n * (3566 ±4) + v * (3566 ±0)` + // Minimum execution time: 520_905_000 picoseconds. + Weight::from_parts(523_771_000, 0) .saturating_add(Weight::from_parts(0, 456136)) - // Standard Error: 2_078_102 - .saturating_add(Weight::from_parts(67_775_668, 0).saturating_mul(v.into())) - // Standard Error: 207_071 - .saturating_add(Weight::from_parts(22_624_711, 0).saturating_mul(n.into())) + // Standard Error: 2_142_714 + .saturating_add(Weight::from_parts(68_631_588, 0).saturating_mul(v.into())) + // Standard Error: 213_509 + .saturating_add(Weight::from_parts(19_343_025, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(184)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -671,15 +669,15 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `n` is `[500, 1000]`. fn get_npos_voters(v: u32, n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `3141 + n * (907 ±0) + v * (391 ±0)` + // Measured: `3108 + n * (907 ±0) + v * (391 ±0)` // Estimated: `456136 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 42_790_195_000 picoseconds. - Weight::from_parts(42_954_437_000, 0) + // Minimum execution time: 36_848_619_000 picoseconds. + Weight::from_parts(37_362_442_000, 0) .saturating_add(Weight::from_parts(0, 456136)) - // Standard Error: 478_107 - .saturating_add(Weight::from_parts(6_744_044, 0).saturating_mul(v.into())) - // Standard Error: 478_107 - .saturating_add(Weight::from_parts(4_837_739, 0).saturating_mul(n.into())) + // Standard Error: 415_031 + .saturating_add(Weight::from_parts(5_204_987, 0).saturating_mul(v.into())) + // Standard Error: 415_031 + .saturating_add(Weight::from_parts(4_132_636, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(179)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -694,13 +692,13 @@ impl pallet_staking::WeightInfo for WeightInfo { /// The range of component `v` is `[500, 1000]`. fn get_npos_targets(v: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `979 + v * (50 ±0)` + // Measured: `946 + v * (50 ±0)` // Estimated: `3510 + v * (2520 ±0)` - // Minimum execution time: 2_851_801_000 picoseconds. - Weight::from_parts(4_477_533, 0) + // Minimum execution time: 2_512_817_000 picoseconds. + Weight::from_parts(119_401_374, 0) .saturating_add(Weight::from_parts(0, 3510)) - // Standard Error: 8_644 - .saturating_add(Weight::from_parts(5_811_682, 0).saturating_mul(v.into())) + // Standard Error: 8_463 + .saturating_add(Weight::from_parts(4_860_364, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) @@ -723,8 +721,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_250_000 picoseconds. - Weight::from_parts(4_472_000, 0) + // Minimum execution time: 3_686_000 picoseconds. + Weight::from_parts(3_881_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(7)) } @@ -746,8 +744,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_986_000 picoseconds. - Weight::from_parts(4_144_000, 0) + // Minimum execution time: 3_143_000 picoseconds. + Weight::from_parts(3_424_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(7)) } @@ -775,10 +773,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill_other() -> Weight { // Proof Size summary in bytes: - // Measured: `1903` + // Measured: `1870` // Estimated: `6248` - // Minimum execution time: 87_291_000 picoseconds. - Weight::from_parts(89_344_000, 0) + // Minimum execution time: 66_946_000 picoseconds. + Weight::from_parts(69_382_000, 0) .saturating_add(Weight::from_parts(0, 6248)) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(6)) @@ -789,10 +787,10 @@ impl pallet_staking::WeightInfo for WeightInfo { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) fn force_apply_min_commission() -> Weight { // Proof Size summary in bytes: - // Measured: `691` + // Measured: `658` // Estimated: `3510` - // Minimum execution time: 16_113_000 picoseconds. - Weight::from_parts(16_593_000, 0) + // Minimum execution time: 11_278_000 picoseconds. + Weight::from_parts(11_603_000, 0) .saturating_add(Weight::from_parts(0, 3510)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -803,53 +801,29 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_433_000 picoseconds. - Weight::from_parts(2_561_000, 0) + // Minimum execution time: 1_963_000 picoseconds. + Weight::from_parts(2_077_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:0) + /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:1) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - fn restore_ledger() -> Weight { - // Proof Size summary in bytes: - // Measured: `1040` - // Estimated: `4764` - // Minimum execution time: 50_167_000 picoseconds. - Weight::from_parts(51_108_000, 0) - .saturating_add(Weight::from_parts(0, 4764)) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) - } - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:1 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - fn migrate_currency() -> Weight { + fn restore_ledger() -> Weight { // Proof Size summary in bytes: - // Measured: `1209` + // Measured: `1014` // Estimated: `4764` - // Minimum execution time: 91_790_000 picoseconds. - Weight::from_parts(92_991_000, 0) + // Minimum execution time: 40_258_000 picoseconds. + Weight::from_parts(41_210_000, 0) .saturating_add(Weight::from_parts(0, 4764)) - .saturating_add(T::DbWeight::get().reads(6)) - .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) } } diff --git a/prdoc/pr_5501.prdoc b/prdoc/pr_5501.prdoc deleted file mode 100644 index f2a5aa9a4667..000000000000 --- a/prdoc/pr_5501.prdoc +++ /dev/null @@ -1,47 +0,0 @@ -# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 -# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json - -title: Currency to Fungible migration for pallet-staking - -doc: - - audience: Runtime User - description: | - Lazy migration of staking balance from `Currency::locks` to `Fungible::holds`. New extrinsic - `staking::migrate_currency` removes the old lock along with other housekeeping. Additionally, any ledger mutation - creates hold if it does not exist. - - The pallet-staking configuration item `Currency` is updated to use `fungible::hold::Mutate` type while still - requiring `LockableCurrency` type to be passed as `OldCurrency` for migration purposes. - - -crates: - - name: westend-runtime - bump: major - - name: kitchensink-runtime - bump: minor - - name: pallet-delegated-staking - bump: patch - - name: pallet-nomination-pools - bump: minor - - name: pallet-nomination-pools-runtime-api - bump: patch - - name: sp-staking - bump: patch - - name: pallet-beefy - bump: patch - - name: pallet-fast-unstake - bump: patch - - name: pallet-staking - bump: major - - name: pallet-grandpa - bump: patch - - name: pallet-babe - bump: patch - - name: pallet-nomination-pools-benchmarking - bump: patch - - name: pallet-session-benchmarking - bump: patch - - name: pallet-root-offences - bump: patch - - name: pallet-offences-benchmarking - bump: patch diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 26f4dacf9a1e..0d9c2df95a82 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -53,9 +53,7 @@ use frame_support::{ Balanced, Credit, HoldConsideration, ItemOf, NativeFromLeft, NativeOrWithId, UnionOf, }, tokens::{ - imbalance::{ResolveAssetTo, ResolveTo}, - nonfungibles_v2::Inspect, - pay::PayAssetFromAccount, + imbalance::ResolveAssetTo, nonfungibles_v2::Inspect, pay::PayAssetFromAccount, GetSalary, PayFromAccount, }, AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, @@ -721,15 +719,13 @@ impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig { } impl pallet_staking::Config for Runtime { - type OldCurrency = Balances; type Currency = Balances; type CurrencyBalance = Balance; type UnixTime = Timestamp; type CurrencyToVote = sp_staking::currency_to_vote::U128CurrencyToVote; - type RewardRemainder = ResolveTo; + type RewardRemainder = Treasury; type RuntimeEvent = RuntimeEvent; - type RuntimeHoldReason = RuntimeHoldReason; - type Slash = ResolveTo; // send the slashed funds to the treasury. + type Slash = Treasury; // send the slashed funds to the treasury. type Reward = (); // rewards are minted from the void type SessionsPerEra = SessionsPerEra; type BondingDuration = BondingDuration; @@ -752,7 +748,7 @@ impl pallet_staking::Config for Runtime { type MaxUnlockingChunks = ConstU32<32>; type MaxControllersInDeprecationBatch = MaxControllersInDeprecationBatch; type HistoryDepth = HistoryDepth; - type EventListeners = (NominationPools, DelegatedStaking); + type EventListeners = NominationPools; type WeightInfo = pallet_staking::weights::SubstrateWeight; type BenchmarkingConfig = StakingBenchmarkingConfig; type DisablingStrategy = pallet_staking::UpToLimitWithReEnablingDisablingStrategy; @@ -936,21 +932,6 @@ impl pallet_bags_list::Config for Runtime { type WeightInfo = pallet_bags_list::weights::SubstrateWeight; } -parameter_types! { - pub const DelegatedStakingPalletId: PalletId = PalletId(*b"py/dlstk"); - pub const SlashRewardFraction: Perbill = Perbill::from_percent(1); -} - -impl pallet_delegated_staking::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type PalletId = DelegatedStakingPalletId; - type Currency = Balances; - type OnSlash = (); - type SlashRewardFraction = SlashRewardFraction; - type RuntimeHoldReason = RuntimeHoldReason; - type CoreStaking = Staking; -} - parameter_types! { pub const PostUnbondPoolsWindow: u32 = 4; pub const NominationPoolsPalletId: PalletId = PalletId(*b"py/nopls"); @@ -979,8 +960,7 @@ impl pallet_nomination_pools::Config for Runtime { type RewardCounter = FixedU128; type BalanceToU256 = BalanceToU256; type U256ToBalance = U256ToBalance; - type StakeAdapter = - pallet_nomination_pools::adapter::DelegateStake; + type StakeAdapter = pallet_nomination_pools::adapter::TransferStake; type PostUnbondingPoolsWindow = PostUnbondPoolsWindow; type MaxMetadataLen = ConstU32<256>; type MaxUnbonding = ConstU32<8>; @@ -2710,9 +2690,6 @@ mod runtime { #[runtime::pallet_index(81)] pub type VerifySignature = pallet_verify_signature::Pallet; - #[runtime::pallet_index(82)] - pub type DelegatedStaking = pallet_delegated_staking::Pallet; - #[runtime::pallet_index(83)] pub type AssetRewards = pallet_asset_rewards::Pallet; diff --git a/substrate/bin/node/testing/src/genesis.rs b/substrate/bin/node/testing/src/genesis.rs index 0394f6cd7394..7f5364744c66 100644 --- a/substrate/bin/node/testing/src/genesis.rs +++ b/substrate/bin/node/testing/src/genesis.rs @@ -38,9 +38,9 @@ pub fn config_endowed(extra_endowed: Vec) -> RuntimeGenesisConfig { (alice(), 111 * DOLLARS), (bob(), 100 * DOLLARS), (charlie(), 100_000_000 * DOLLARS), - (dave(), 112 * DOLLARS), + (dave(), 111 * DOLLARS), (eve(), 101 * DOLLARS), - (ferdie(), 101 * DOLLARS), + (ferdie(), 100 * DOLLARS), ]; endowed.extend(extra_endowed.into_iter().map(|endowed| (endowed, 100 * DOLLARS))); diff --git a/substrate/frame/babe/src/mock.rs b/substrate/frame/babe/src/mock.rs index 8d00509e800b..23857470adc4 100644 --- a/substrate/frame/babe/src/mock.rs +++ b/substrate/frame/babe/src/mock.rs @@ -157,7 +157,6 @@ impl onchain::Config for OnChainSeqPhragmen { #[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] impl pallet_staking::Config for Test { - type OldCurrency = Balances; type Currency = Balances; type SessionsPerEra = SessionsPerEra; type BondingDuration = BondingDuration; diff --git a/substrate/frame/beefy/src/mock.rs b/substrate/frame/beefy/src/mock.rs index 38e0cc4cfc26..7ae41c609180 100644 --- a/substrate/frame/beefy/src/mock.rs +++ b/substrate/frame/beefy/src/mock.rs @@ -235,7 +235,6 @@ impl onchain::Config for OnChainSeqPhragmen { #[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] impl pallet_staking::Config for Test { type RuntimeEvent = RuntimeEvent; - type OldCurrency = Balances; type Currency = Balances; type AdminOrigin = frame_system::EnsureRoot; type SessionInterface = Self; diff --git a/substrate/frame/delegated-staking/src/lib.rs b/substrate/frame/delegated-staking/src/lib.rs index 0dacfe9c5579..1d181eb29cab 100644 --- a/substrate/frame/delegated-staking/src/lib.rs +++ b/substrate/frame/delegated-staking/src/lib.rs @@ -520,7 +520,7 @@ impl Pallet { let stake = T::CoreStaking::stake(who)?; // release funds from core staking. - T::CoreStaking::migrate_to_virtual_staker(who)?; + T::CoreStaking::migrate_to_virtual_staker(who); // transfer just released staked amount plus any free amount. let amount_to_transfer = diff --git a/substrate/frame/delegated-staking/src/mock.rs b/substrate/frame/delegated-staking/src/mock.rs index 875279864f7a..811d5739f4e9 100644 --- a/substrate/frame/delegated-staking/src/mock.rs +++ b/substrate/frame/delegated-staking/src/mock.rs @@ -102,7 +102,6 @@ impl onchain::Config for OnChainSeqPhragmen { #[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] impl pallet_staking::Config for Runtime { - type OldCurrency = Balances; type Currency = Balances; type UnixTime = pallet_timestamp::Pallet; type AdminOrigin = frame_system::EnsureRoot; diff --git a/substrate/frame/delegated-staking/src/tests.rs b/substrate/frame/delegated-staking/src/tests.rs index c764e2741a2a..b7b82a43771e 100644 --- a/substrate/frame/delegated-staking/src/tests.rs +++ b/substrate/frame/delegated-staking/src/tests.rs @@ -671,14 +671,12 @@ mod staking_integration { )); assert_ok!(Staking::nominate(RuntimeOrigin::signed(agent), vec![GENESIS_VALIDATOR],)); let init_stake = Staking::stake(&agent).unwrap(); - // no extra provider added. - assert_eq!(System::providers(&agent), 1); // scenario: 200 is a pool account, and the stake comes from its 4 delegators (300..304) // in equal parts. lets try to migrate this nominator into delegate based stake. // all balance currently is in 200 - assert_eq!(pallet_staking::asset::total_balance::(&agent), agent_amount); + assert_eq!(pallet_staking::asset::stakeable_balance::(&agent), agent_amount); // to migrate, nominator needs to set an account as a proxy delegator where staked funds // will be moved and delegated back to this old nominator account. This should be funded @@ -687,9 +685,8 @@ mod staking_integration { DelegatedStaking::generate_proxy_delegator(Agent::from(agent)).get(); assert_ok!(DelegatedStaking::migrate_to_agent(RawOrigin::Signed(agent).into(), 201)); - // after migration, no provider left since free balance is 0 and staking pallet released - // all funds. - assert_eq!(System::providers(&agent), 0); + // after migration, funds are moved to proxy delegator, still a provider exists. + assert_eq!(System::providers(&agent), 1); assert_eq!(Balances::free_balance(agent), 0); // proxy delegator has one provider as well with no free balance. assert_eq!(System::providers(&proxy_delegator), 1); @@ -801,6 +798,8 @@ mod staking_integration { RawOrigin::Signed(agent).into(), reward_acc )); + // becoming an agent adds another provider. + assert_eq!(System::providers(&agent), 2); // delegate to this account fund(&delegator, 1000); diff --git a/substrate/frame/delegated-staking/src/types.rs b/substrate/frame/delegated-staking/src/types.rs index 14f49466f0e2..a78aa3f55906 100644 --- a/substrate/frame/delegated-staking/src/types.rs +++ b/substrate/frame/delegated-staking/src/types.rs @@ -131,6 +131,10 @@ impl AgentLedger { /// /// Increments provider count if this is a new agent. pub(crate) fn update(self, key: &T::AccountId) { + if !>::contains_key(key) { + // This is a new agent. Provide for this account. + frame_system::Pallet::::inc_providers(key); + } >::insert(key, self) } @@ -138,6 +142,8 @@ impl AgentLedger { pub(crate) fn remove(key: &T::AccountId) { debug_assert!(>::contains_key(key), "Agent should exist in storage"); >::remove(key); + // Remove provider reference. + let _ = frame_system::Pallet::::dec_providers(key).defensive(); } /// Effective total balance of the `Agent`. diff --git a/substrate/frame/election-provider-multi-phase/test-staking-e2e/Cargo.toml b/substrate/frame/election-provider-multi-phase/test-staking-e2e/Cargo.toml index f11f9c04dbf4..7a48ae868a5a 100644 --- a/substrate/frame/election-provider-multi-phase/test-staking-e2e/Cargo.toml +++ b/substrate/frame/election-provider-multi-phase/test-staking-e2e/Cargo.toml @@ -34,7 +34,6 @@ frame-system = { workspace = true, default-features = true } pallet-bags-list = { workspace = true, default-features = true } pallet-balances = { workspace = true, default-features = true } -pallet-delegated-staking = { workspace = true, default-features = true } pallet-election-provider-multi-phase = { workspace = true, default-features = true } pallet-nomination-pools = { workspace = true, default-features = true } pallet-session = { workspace = true, default-features = true } @@ -48,7 +47,6 @@ try-runtime = [ "frame-system/try-runtime", "pallet-bags-list/try-runtime", "pallet-balances/try-runtime", - "pallet-delegated-staking/try-runtime", "pallet-election-provider-multi-phase/try-runtime", "pallet-nomination-pools/try-runtime", "pallet-session/try-runtime", diff --git a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/lib.rs b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/lib.rs index b1029e89fe85..26a6345e145f 100644 --- a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/lib.rs +++ b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/lib.rs @@ -327,8 +327,8 @@ fn automatic_unbonding_pools() { assert_eq!(::MaxUnbonding::get(), 1); // init state of pool members. - let init_free_balance_2 = Balances::free_balance(2); - let init_free_balance_3 = Balances::free_balance(3); + let init_stakeable_balance_2 = pallet_staking::asset::stakeable_balance::(&2); + let init_stakeable_balance_3 = pallet_staking::asset::stakeable_balance::(&3); let pool_bonded_account = Pools::generate_bonded_account(1); @@ -378,7 +378,7 @@ fn automatic_unbonding_pools() { System::reset_events(); let staked_before_withdraw_pool = staked_amount_for(pool_bonded_account); - assert_eq!(delegated_balance_for(pool_bonded_account), 5 + 10 + 10); + assert_eq!(pallet_staking::asset::stakeable_balance::(&pool_bonded_account), 26); // now unbonding 3 will work, although the pool's ledger still has the unlocking chunks // filled up. @@ -390,13 +390,13 @@ fn automatic_unbonding_pools() { [ // auto-withdraw happened as expected to release 2's unbonding funds, but the funds // were not transferred to 2 and stay in the pool's transferrable balance instead. - pallet_staking::Event::Withdrawn { stash: pool_bonded_account, amount: 10 }, - pallet_staking::Event::Unbonded { stash: pool_bonded_account, amount: 10 } + pallet_staking::Event::Withdrawn { stash: 7939698191839293293, amount: 10 }, + pallet_staking::Event::Unbonded { stash: 7939698191839293293, amount: 10 } ] ); // balance of the pool remains the same, it hasn't withdraw explicitly from the pool yet. - assert_eq!(delegated_balance_for(pool_bonded_account), 25); + assert_eq!(pallet_staking::asset::stakeable_balance::(&pool_bonded_account), 26); // but the locked amount in the pool's account decreases due to the auto-withdraw: assert_eq!(staked_before_withdraw_pool - 10, staked_amount_for(pool_bonded_account)); @@ -405,12 +405,12 @@ fn automatic_unbonding_pools() { // however, note that the withdrawing from the pool still works for 2, the funds are taken // from the pool's non staked balance. - assert_eq!(delegated_balance_for(pool_bonded_account), 25); - assert_eq!(staked_amount_for(pool_bonded_account), 15); + assert_eq!(pallet_staking::asset::stakeable_balance::(&pool_bonded_account), 26); + assert_eq!(pallet_staking::asset::staked::(&pool_bonded_account), 15); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(2), 2, 10)); - assert_eq!(delegated_balance_for(pool_bonded_account), 15); + assert_eq!(pallet_staking::asset::stakeable_balance::(&pool_bonded_account), 16); - assert_eq!(Balances::free_balance(2), 20); + assert_eq!(pallet_staking::asset::stakeable_balance::(&2), 20); assert_eq!(TotalValueLocked::::get(), 15); // 3 cannot withdraw yet. @@ -429,9 +429,15 @@ fn automatic_unbonding_pools() { assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(3), 3, 10)); // final conditions are the expected. - assert_eq!(delegated_balance_for(pool_bonded_account), 5); // 5 init bonded - assert_eq!(Balances::free_balance(2), init_free_balance_2); - assert_eq!(Balances::free_balance(3), init_free_balance_3); + assert_eq!(pallet_staking::asset::stakeable_balance::(&pool_bonded_account), 6); // 5 init bonded + ED + assert_eq!( + pallet_staking::asset::stakeable_balance::(&2), + init_stakeable_balance_2 + ); + assert_eq!( + pallet_staking::asset::stakeable_balance::(&3), + init_stakeable_balance_3 + ); assert_eq!(TotalValueLocked::::get(), init_tvl); }); diff --git a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs index bcb25f8287b3..eaab848c1694 100644 --- a/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs @@ -21,7 +21,6 @@ use frame_support::{ assert_ok, parameter_types, traits, traits::{Hooks, UnfilteredDispatchable, VariantCountOf}, weights::constants, - PalletId, }; use frame_system::EnsureRoot; use sp_core::{ConstU32, Get}; @@ -37,7 +36,7 @@ use sp_runtime::{ }; use sp_staking::{ offence::{OffenceDetails, OnOffenceHandler}, - Agent, DelegationInterface, EraIndex, SessionIndex, StakingInterface, + EraIndex, SessionIndex, }; use std::collections::BTreeMap; @@ -69,7 +68,6 @@ frame_support::construct_runtime!( System: frame_system, ElectionProviderMultiPhase: pallet_election_provider_multi_phase, Staking: pallet_staking, - DelegatedStaking: pallet_delegated_staking, Pools: pallet_nomination_pools, Balances: pallet_balances, BagsList: pallet_bags_list, @@ -79,7 +77,7 @@ frame_support::construct_runtime!( } ); -pub(crate) type AccountId = u128; +pub(crate) type AccountId = u64; pub(crate) type AccountIndex = u32; pub(crate) type BlockNumber = u32; pub(crate) type Balance = u64; @@ -89,10 +87,8 @@ pub(crate) type Moment = u32; #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] impl frame_system::Config for Runtime { - type AccountId = AccountId; type Block = Block; type AccountData = pallet_balances::AccountData; - type Lookup = sp_runtime::traits::IdentityLookup; } const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); @@ -269,8 +265,7 @@ impl pallet_nomination_pools::Config for Runtime { type RewardCounter = sp_runtime::FixedU128; type BalanceToU256 = BalanceToU256; type U256ToBalance = U256ToBalance; - type StakeAdapter = - pallet_nomination_pools::adapter::DelegateStake; + type StakeAdapter = pallet_nomination_pools::adapter::TransferStake; type PostUnbondingPoolsWindow = ConstU32<2>; type PalletId = PoolsPalletId; type MaxMetadataLen = ConstU32<256>; @@ -279,21 +274,6 @@ impl pallet_nomination_pools::Config for Runtime { type AdminOrigin = frame_system::EnsureRoot; } -parameter_types! { - pub const DelegatedStakingPalletId: PalletId = PalletId(*b"py/dlstk"); - pub const SlashRewardFraction: Perbill = Perbill::from_percent(1); -} - -impl pallet_delegated_staking::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type PalletId = DelegatedStakingPalletId; - type Currency = Balances; - type OnSlash = (); - type SlashRewardFraction = SlashRewardFraction; - type RuntimeHoldReason = RuntimeHoldReason; - type CoreStaking = Staking; -} - parameter_types! { pub static MaxUnlockingChunks: u32 = 32; } @@ -305,7 +285,6 @@ pub(crate) const SLASHING_DISABLING_FACTOR: usize = 3; #[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] impl pallet_staking::Config for Runtime { - type OldCurrency = Balances; type Currency = Balances; type CurrencyBalance = Balance; type UnixTime = Timestamp; @@ -323,7 +302,7 @@ impl pallet_staking::Config for Runtime { type NominationsQuota = pallet_staking::FixedNominationsQuota; type TargetList = pallet_staking::UseValidatorsMap; type MaxUnlockingChunks = MaxUnlockingChunks; - type EventListeners = (Pools, DelegatedStaking); + type EventListeners = Pools; type WeightInfo = pallet_staking::weights::SubstrateWeight; type DisablingStrategy = pallet_staking::UpToLimitWithReEnablingDisablingStrategy; @@ -523,7 +502,7 @@ impl Default for BalancesExtBuilder { (100, 100), (200, 100), // stashes - (11, 1100), + (11, 1000), (21, 2000), (31, 3000), (41, 4000), @@ -602,7 +581,7 @@ impl ExtBuilder { // set the keys for the first session. keys: stakers .into_iter() - .map(|(id, ..)| (id, id, SessionKeys { other: (id as AccountId as u64).into() })) + .map(|(id, ..)| (id, id, SessionKeys { other: (id as u64).into() })) .collect(), ..Default::default() } @@ -947,11 +926,7 @@ pub(crate) fn set_minimum_election_score( } pub(crate) fn staked_amount_for(account_id: AccountId) -> Balance { - Staking::total_stake(&account_id).expect("account must be staker") -} - -pub(crate) fn delegated_balance_for(account_id: AccountId) -> Balance { - DelegatedStaking::agent_balance(Agent::from(account_id)).unwrap_or_default() + pallet_staking::asset::staked::(&account_id) } pub(crate) fn staking_events() -> Vec> { diff --git a/substrate/frame/fast-unstake/src/mock.rs b/substrate/frame/fast-unstake/src/mock.rs index cf4f5f49240e..f044fc610187 100644 --- a/substrate/frame/fast-unstake/src/mock.rs +++ b/substrate/frame/fast-unstake/src/mock.rs @@ -105,7 +105,6 @@ impl frame_election_provider_support::ElectionProvider for MockElection { #[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] impl pallet_staking::Config for Runtime { - type OldCurrency = Balances; type Currency = Balances; type UnixTime = pallet_timestamp::Pallet; type AdminOrigin = frame_system::EnsureRoot; @@ -224,9 +223,8 @@ impl ExtBuilder { .clone() .into_iter() .map(|(stash, _, balance)| (stash, balance * 2)) - // give stakers enough balance for stake, ed and fast unstake deposit. - .chain(validators_range.clone().map(|x| (x, 7 + 1 + 100))) - .chain(nominators_range.clone().map(|x| (x, 7 + 1 + 100))) + .chain(validators_range.clone().map(|x| (x, 7 + 100))) + .chain(nominators_range.clone().map(|x| (x, 7 + 100))) .collect::>(), } .assimilate_storage(&mut storage); diff --git a/substrate/frame/fast-unstake/src/tests.rs b/substrate/frame/fast-unstake/src/tests.rs index 0fddb88e02b7..7c11f381ca10 100644 --- a/substrate/frame/fast-unstake/src/tests.rs +++ b/substrate/frame/fast-unstake/src/tests.rs @@ -19,15 +19,7 @@ use super::*; use crate::{mock::*, types::*, Event}; -use frame_support::{ - pallet_prelude::*, - testing_prelude::*, - traits::{ - fungible::Inspect, - tokens::{Fortitude::Polite, Preservation::Expendable}, - Currency, - }, -}; +use frame_support::{pallet_prelude::*, testing_prelude::*, traits::Currency}; use pallet_staking::{CurrentEra, RewardDestination}; use sp_runtime::traits::BadOrigin; @@ -154,7 +146,7 @@ fn deregister_works() { // Controller then changes mind and deregisters. assert_ok!(FastUnstake::deregister(RuntimeOrigin::signed(1))); - assert_eq!(::Currency::reserved_balance(&1), pre_reserved); + assert_eq!(::Currency::reserved_balance(&1) - pre_reserved, 0); // Ensure stash no longer exists in the queue. assert_eq!(Queue::::get(1), None); @@ -305,7 +297,7 @@ mod on_idle { ); assert_eq!(Queue::::count(), 3); - assert_eq!(::Currency::reserved_balance(&1), pre_reserved); + assert_eq!(::Currency::reserved_balance(&1) - pre_reserved, 0); assert_eq!( fast_unstake_events_since_last_call(), @@ -801,8 +793,6 @@ mod on_idle { RuntimeOrigin::signed(VALIDATOR_PREFIX), vec![VALIDATOR_PREFIX] )); - - assert_eq!(Balances::reducible_balance(&VALIDATOR_PREFIX, Expendable, Polite), 7); assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(VALIDATOR_PREFIX))); // but they indeed are exposed! diff --git a/substrate/frame/grandpa/src/mock.rs b/substrate/frame/grandpa/src/mock.rs index 0a85d9ffd2b0..87369c23948c 100644 --- a/substrate/frame/grandpa/src/mock.rs +++ b/substrate/frame/grandpa/src/mock.rs @@ -161,7 +161,6 @@ impl onchain::Config for OnChainSeqPhragmen { #[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] impl pallet_staking::Config for Test { - type OldCurrency = Balances; type Currency = Balances; type CurrencyBalance = ::Balance; type SessionsPerEra = SessionsPerEra; diff --git a/substrate/frame/nomination-pools/benchmarking/src/inner.rs b/substrate/frame/nomination-pools/benchmarking/src/inner.rs index 20c5eafbcfc5..7ddb78cca3f9 100644 --- a/substrate/frame/nomination-pools/benchmarking/src/inner.rs +++ b/substrate/frame/nomination-pools/benchmarking/src/inner.rs @@ -132,10 +132,6 @@ fn migrate_to_transfer_stake(pool_id: PoolId) { .expect("member should have enough balance to transfer"); }); - // Pool needs to have ED balance free to stake so give it some. - // Note: we didn't require ED until pallet-staking migrated from locks to holds. - let _ = CurrencyOf::::mint_into(&pool_acc, CurrencyOf::::minimum_balance()); - pallet_staking::Pallet::::migrate_to_direct_staker(&pool_acc); } @@ -145,6 +141,14 @@ fn vote_to_balance( vote.try_into().map_err(|_| "could not convert u64 to Balance") } +/// `assertion` should strictly be true if the adapter is using `Delegate` strategy and strictly +/// false if the adapter is not using `Delegate` strategy. +fn assert_if_delegate(assertion: bool) { + let legacy_adapter_used = T::StakeAdapter::strategy_type() != StakeStrategyType::Delegate; + // one and only one of the two should be true. + assert!(assertion ^ legacy_adapter_used); +} + #[allow(unused)] struct ListScenario { /// Stash/Controller that is expected to be moved. @@ -977,6 +981,9 @@ mod benchmarks { #[benchmark] fn apply_slash() { + // Note: With older `TransferStake` strategy, slashing is greedy and apply_slash should + // always fail. + // We want to fill member's unbonding pools. So let's bond with big enough amount. let deposit_amount = Pools::::depositor_min_bond() * T::MaxUnbonding::get().into() * 4u32.into(); @@ -986,7 +993,7 @@ mod benchmarks { // verify user balance in the pool. assert_eq!(PoolMembers::::get(&depositor).unwrap().total_balance(), deposit_amount); // verify delegated balance. - assert!( + assert_if_delegate::( T::StakeAdapter::member_delegation_balance(Member::from(depositor.clone())) == Some(deposit_amount), ); @@ -1010,7 +1017,7 @@ mod benchmarks { deposit_amount / 2u32.into() ); // verify delegated balance are not yet slashed. - assert!( + assert_if_delegate::( T::StakeAdapter::member_delegation_balance(Member::from(depositor.clone())) == Some(deposit_amount), ); @@ -1034,11 +1041,13 @@ mod benchmarks { #[block] { - assert!(Pools::::apply_slash( - RuntimeOrigin::Signed(slash_reporter.clone()).into(), - depositor_lookup.clone(), - ) - .is_ok(),); + assert_if_delegate::( + Pools::::apply_slash( + RuntimeOrigin::Signed(slash_reporter.clone()).into(), + depositor_lookup.clone(), + ) + .is_ok(), + ); } // verify balances are correct and slash applied. @@ -1046,7 +1055,7 @@ mod benchmarks { PoolMembers::::get(&depositor).unwrap().total_balance(), deposit_amount / 2u32.into() ); - assert!( + assert_if_delegate::( T::StakeAdapter::member_delegation_balance(Member::from(depositor.clone())) == Some(deposit_amount / 2u32.into()), ); @@ -1117,16 +1126,18 @@ mod benchmarks { let _ = migrate_to_transfer_stake::(1); #[block] { - assert!(Pools::::migrate_pool_to_delegate_stake( - RuntimeOrigin::Signed(depositor.clone()).into(), - 1u32.into(), - ) - .is_ok(),); + assert_if_delegate::( + Pools::::migrate_pool_to_delegate_stake( + RuntimeOrigin::Signed(depositor.clone()).into(), + 1u32.into(), + ) + .is_ok(), + ); } - // this queries agent balance. + // this queries agent balance if `DelegateStake` strategy. assert_eq!( T::StakeAdapter::total_balance(Pool::from(pool_account.clone())), - Some(deposit_amount + CurrencyOf::::minimum_balance()) + Some(deposit_amount) ); } @@ -1141,11 +1152,13 @@ mod benchmarks { let _ = migrate_to_transfer_stake::(1); // Now migrate pool to delegate stake keeping delegators unmigrated. - assert!(Pools::::migrate_pool_to_delegate_stake( - RuntimeOrigin::Signed(depositor.clone()).into(), - 1u32.into(), - ) - .is_ok(),); + assert_if_delegate::( + Pools::::migrate_pool_to_delegate_stake( + RuntimeOrigin::Signed(depositor.clone()).into(), + 1u32.into(), + ) + .is_ok(), + ); // delegation does not exist. assert!( @@ -1158,14 +1171,16 @@ mod benchmarks { #[block] { - assert!(Pools::::migrate_delegation( - RuntimeOrigin::Signed(depositor.clone()).into(), - depositor_lookup.clone(), - ) - .is_ok(),); + assert_if_delegate::( + Pools::::migrate_delegation( + RuntimeOrigin::Signed(depositor.clone()).into(), + depositor_lookup.clone(), + ) + .is_ok(), + ); } // verify balances once more. - assert!( + assert_if_delegate::( T::StakeAdapter::member_delegation_balance(Member::from(depositor.clone())) == Some(deposit_amount), ); diff --git a/substrate/frame/nomination-pools/benchmarking/src/mock.rs b/substrate/frame/nomination-pools/benchmarking/src/mock.rs index 7c09cf22ad51..15d9e2c56031 100644 --- a/substrate/frame/nomination-pools/benchmarking/src/mock.rs +++ b/substrate/frame/nomination-pools/benchmarking/src/mock.rs @@ -78,7 +78,6 @@ parameter_types! { } #[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] impl pallet_staking::Config for Runtime { - type OldCurrency = Balances; type Currency = Balances; type CurrencyBalance = Balance; type UnixTime = pallet_timestamp::Pallet; diff --git a/substrate/frame/nomination-pools/src/adapter.rs b/substrate/frame/nomination-pools/src/adapter.rs index f1c68af4ea6a..f125919dabfa 100644 --- a/substrate/frame/nomination-pools/src/adapter.rs +++ b/substrate/frame/nomination-pools/src/adapter.rs @@ -16,7 +16,6 @@ // limitations under the License. use crate::*; -use frame_support::traits::tokens::{Fortitude::Polite, Preservation::Expendable}; use sp_staking::{Agent, DelegationInterface, DelegationMigrator, Delegator}; /// Types of stake strategies. @@ -246,10 +245,8 @@ pub trait StakeStrategy { /// strategy in an existing runtime, storage migration is required. See /// [`migration::unversioned::DelegationStakeMigration`]. For new runtimes, it is highly recommended /// to use the [`DelegateStake`] strategy. -#[deprecated = "consider migrating to DelegateStake"] pub struct TransferStake(PhantomData<(T, Staking)>); -#[allow(deprecated)] impl, AccountId = T::AccountId>> StakeStrategy for TransferStake { @@ -265,8 +262,7 @@ impl, AccountId = T: pool_account: Pool, _: Member, ) -> BalanceOf { - // free/liquid balance of the pool account. - T::Currency::reducible_balance(&pool_account.get(), Expendable, Polite) + T::Currency::balance(&pool_account.0).saturating_sub(Self::active_stake(pool_account)) } fn total_balance(pool_account: Pool) -> Option> { diff --git a/substrate/frame/nomination-pools/src/mock.rs b/substrate/frame/nomination-pools/src/mock.rs index f4552389a267..f544e79ec481 100644 --- a/substrate/frame/nomination-pools/src/mock.rs +++ b/substrate/frame/nomination-pools/src/mock.rs @@ -23,10 +23,8 @@ use frame_support::{ PalletId, }; use frame_system::{EnsureSignedBy, RawOrigin}; -use sp_runtime::{BuildStorage, DispatchResult, FixedU128}; -use sp_staking::{ - Agent, DelegationInterface, DelegationMigrator, Delegator, OnStakingUpdate, Stake, -}; +use sp_runtime::{BuildStorage, FixedU128}; +use sp_staking::{OnStakingUpdate, Stake}; pub type BlockNumber = u64; pub type AccountId = u128; @@ -78,7 +76,6 @@ impl StakingMock { let bonded = BondedBalanceMap::get(); let pre_total = bonded.get(&acc).unwrap(); Self::set_bonded_balance(acc, pre_total - amount); - DelegateMock::on_slash(acc, amount); Pools::on_slash(&acc, pre_total - amount, &Default::default(), amount); } } @@ -115,8 +112,8 @@ impl sp_staking::StakingInterface for StakingMock { .ok_or(DispatchError::Other("NotStash")) } - fn is_virtual_staker(who: &Self::AccountId) -> bool { - AgentBalanceMap::get().contains_key(who) + fn is_virtual_staker(_who: &Self::AccountId) -> bool { + false } fn bond_extra(who: &Self::AccountId, extra: Self::Balance) -> DispatchResult { @@ -165,9 +162,7 @@ impl sp_staking::StakingInterface for StakingMock { staker_map.retain(|(unlocking_at, _amount)| *unlocking_at > current_era); // if there was a withdrawal, notify the pallet. - let withdraw_amount = unlocking_before.saturating_sub(unlocking(&staker_map)); - Pools::on_withdraw(&who, withdraw_amount); - DelegateMock::on_withdraw(who, withdraw_amount); + Pools::on_withdraw(&who, unlocking_before.saturating_sub(unlocking(&staker_map))); UnbondingBalanceMap::set(&unbonding_map); Ok(UnbondingBalanceMap::get().get(&who).unwrap().is_empty() && @@ -244,176 +239,6 @@ impl sp_staking::StakingInterface for StakingMock { } } -parameter_types! { - // Map of agent to their (delegated balance, unclaimed withdrawal, pending slash). - pub storage AgentBalanceMap: BTreeMap = Default::default(); - pub storage DelegatorBalanceMap: BTreeMap = Default::default(); -} -pub struct DelegateMock; -impl DelegationInterface for DelegateMock { - type Balance = Balance; - type AccountId = AccountId; - fn agent_balance(agent: Agent) -> Option { - AgentBalanceMap::get() - .get(&agent.get()) - .copied() - .map(|(delegated, _, pending)| delegated - pending) - } - - fn agent_transferable_balance(agent: Agent) -> Option { - AgentBalanceMap::get() - .get(&agent.get()) - .copied() - .map(|(_, unclaimed_withdrawals, _)| unclaimed_withdrawals) - } - - fn delegator_balance(delegator: Delegator) -> Option { - DelegatorBalanceMap::get().get(&delegator.get()).copied() - } - - fn register_agent( - agent: Agent, - _reward_account: &Self::AccountId, - ) -> DispatchResult { - let mut agents = AgentBalanceMap::get(); - agents.insert(agent.get(), (0, 0, 0)); - AgentBalanceMap::set(&agents); - Ok(()) - } - - fn remove_agent(agent: Agent) -> DispatchResult { - let mut agents = AgentBalanceMap::get(); - let agent = agent.get(); - assert!(agents.contains_key(&agent)); - agents.remove(&agent); - AgentBalanceMap::set(&agents); - Ok(()) - } - - fn delegate( - delegator: Delegator, - agent: Agent, - amount: Self::Balance, - ) -> DispatchResult { - let delegator = delegator.get(); - let mut delegators = DelegatorBalanceMap::get(); - delegators.entry(delegator).and_modify(|b| *b += amount).or_insert(amount); - DelegatorBalanceMap::set(&delegators); - - let agent = agent.get(); - let mut agents = AgentBalanceMap::get(); - agents - .get_mut(&agent) - .map(|(d, _, _)| *d += amount) - .ok_or(DispatchError::Other("agent not registered"))?; - AgentBalanceMap::set(&agents); - - if BondedBalanceMap::get().contains_key(&agent) { - StakingMock::bond_extra(&agent, amount) - } else { - // reward account does not matter in this context. - StakingMock::bond(&agent, amount, &999) - } - } - - fn withdraw_delegation( - delegator: Delegator, - agent: Agent, - amount: Self::Balance, - _num_slashing_spans: u32, - ) -> DispatchResult { - let mut delegators = DelegatorBalanceMap::get(); - delegators.get_mut(&delegator.get()).map(|b| *b -= amount); - DelegatorBalanceMap::set(&delegators); - - let mut agents = AgentBalanceMap::get(); - agents.get_mut(&agent.get()).map(|(d, u, _)| { - *d -= amount; - *u -= amount; - }); - AgentBalanceMap::set(&agents); - - Ok(()) - } - - fn pending_slash(agent: Agent) -> Option { - AgentBalanceMap::get() - .get(&agent.get()) - .copied() - .map(|(_, _, pending_slash)| pending_slash) - } - - fn delegator_slash( - agent: Agent, - delegator: Delegator, - value: Self::Balance, - _maybe_reporter: Option, - ) -> DispatchResult { - let mut delegators = DelegatorBalanceMap::get(); - delegators.get_mut(&delegator.get()).map(|b| *b -= value); - DelegatorBalanceMap::set(&delegators); - - let mut agents = AgentBalanceMap::get(); - agents.get_mut(&agent.get()).map(|(_, _, p)| { - p.saturating_reduce(value); - }); - AgentBalanceMap::set(&agents); - - Ok(()) - } -} - -impl DelegateMock { - pub fn set_agent_balance(who: AccountId, delegated: Balance) { - let mut agents = AgentBalanceMap::get(); - agents.insert(who, (delegated, 0, 0)); - AgentBalanceMap::set(&agents); - } - - pub fn set_delegator_balance(who: AccountId, amount: Balance) { - let mut delegators = DelegatorBalanceMap::get(); - delegators.insert(who, amount); - DelegatorBalanceMap::set(&delegators); - } - - pub fn on_slash(agent: AccountId, amount: Balance) { - let mut agents = AgentBalanceMap::get(); - agents.get_mut(&agent).map(|(_, _, p)| *p += amount); - AgentBalanceMap::set(&agents); - } - - fn on_withdraw(agent: AccountId, amount: Balance) { - let mut agents = AgentBalanceMap::get(); - // if agent exists, add the amount to unclaimed withdrawals. - agents.get_mut(&agent).map(|(_, u, _)| *u += amount); - AgentBalanceMap::set(&agents); - } -} - -impl DelegationMigrator for DelegateMock { - type Balance = Balance; - type AccountId = AccountId; - fn migrate_nominator_to_agent( - _agent: Agent, - _reward_account: &Self::AccountId, - ) -> DispatchResult { - unimplemented!("not used in current unit tests") - } - - fn migrate_delegation( - _agent: Agent, - _delegator: Delegator, - _value: Self::Balance, - ) -> DispatchResult { - unimplemented!("not used in current unit tests") - } - - #[cfg(feature = "runtime-benchmarks")] - fn force_kill_agent(_agent: Agent) { - unimplemented!("not used in current unit tests") - } -} - #[derive_impl(frame_system::config_preludes::TestDefaultConfig)] impl frame_system::Config for Runtime { type Nonce = u64; @@ -470,7 +295,7 @@ impl pools::Config for Runtime { type RewardCounter = RewardCounter; type BalanceToU256 = BalanceToU256; type U256ToBalance = U256ToBalance; - type StakeAdapter = adapter::DelegateStake; + type StakeAdapter = adapter::TransferStake; type PostUnbondingPoolsWindow = PostUnbondingPoolsWindow; type PalletId = PoolsPalletId; type MaxMetadataLen = MaxMetadataLen; @@ -697,21 +522,6 @@ pub fn reward_imbalance(pool: PoolId) -> RewardImbalance { } } -pub fn set_pool_balance(who: AccountId, amount: Balance) { - StakingMock::set_bonded_balance(who, amount); - DelegateMock::set_agent_balance(who, amount); -} - -pub fn member_delegation(who: AccountId) -> Balance { - ::StakeAdapter::member_delegation_balance(Member::from(who)) - .expect("who must be a pool member") -} - -pub fn pool_balance(id: PoolId) -> Balance { - ::StakeAdapter::total_balance(Pool::from(Pools::generate_bonded_account(id))) - .expect("who must be a bonded pool account") -} - #[cfg(test)] mod test { use super::*; diff --git a/substrate/frame/nomination-pools/src/tests.rs b/substrate/frame/nomination-pools/src/tests.rs index c46638d2f8f7..06261699a5b2 100644 --- a/substrate/frame/nomination-pools/src/tests.rs +++ b/substrate/frame/nomination-pools/src/tests.rs @@ -24,7 +24,6 @@ use sp_runtime::{ traits::{BadOrigin, Dispatchable}, FixedU128, }; -use sp_staking::{Agent, DelegationInterface}; macro_rules! unbonding_pools_with_era { ($($k:expr => $v:expr),* $(,)?) => {{ @@ -128,41 +127,41 @@ mod bonded_pool { }; // 1 points : 1 balance ratio - set_pool_balance(bonded_pool.bonded_account(), 100); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 100); assert_eq!(bonded_pool.balance_to_point(10), 10); assert_eq!(bonded_pool.balance_to_point(0), 0); // 2 points : 1 balance ratio - set_pool_balance(bonded_pool.bonded_account(), 50); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 50); assert_eq!(bonded_pool.balance_to_point(10), 20); // 1 points : 2 balance ratio - set_pool_balance(bonded_pool.bonded_account(), 100); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 100); bonded_pool.points = 50; assert_eq!(bonded_pool.balance_to_point(10), 5); // 100 points : 0 balance ratio - set_pool_balance(bonded_pool.bonded_account(), 0); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 0); bonded_pool.points = 100; assert_eq!(bonded_pool.balance_to_point(10), 100 * 10); // 0 points : 100 balance - set_pool_balance(bonded_pool.bonded_account(), 100); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 100); bonded_pool.points = 0; assert_eq!(bonded_pool.balance_to_point(10), 10); // 10 points : 3 balance ratio - set_pool_balance(bonded_pool.bonded_account(), 30); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 30); bonded_pool.points = 100; assert_eq!(bonded_pool.balance_to_point(10), 33); // 2 points : 3 balance ratio - set_pool_balance(bonded_pool.bonded_account(), 300); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 300); bonded_pool.points = 200; assert_eq!(bonded_pool.balance_to_point(10), 6); // 4 points : 9 balance ratio - set_pool_balance(bonded_pool.bonded_account(), 900); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 900); bonded_pool.points = 400; assert_eq!(bonded_pool.balance_to_point(90), 40); }) @@ -183,7 +182,7 @@ mod bonded_pool { }, }; - set_pool_balance(bonded_pool.bonded_account(), 100); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 100); assert_eq!(bonded_pool.points_to_balance(10), 10); assert_eq!(bonded_pool.points_to_balance(0), 0); @@ -192,27 +191,27 @@ mod bonded_pool { assert_eq!(bonded_pool.points_to_balance(10), 20); // 100 balance : 0 points ratio - set_pool_balance(bonded_pool.bonded_account(), 100); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 100); bonded_pool.points = 0; assert_eq!(bonded_pool.points_to_balance(10), 0); // 0 balance : 100 points ratio - set_pool_balance(bonded_pool.bonded_account(), 0); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 0); bonded_pool.points = 100; assert_eq!(bonded_pool.points_to_balance(10), 0); // 10 balance : 3 points ratio - set_pool_balance(bonded_pool.bonded_account(), 100); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 100); bonded_pool.points = 30; assert_eq!(bonded_pool.points_to_balance(10), 33); // 2 balance : 3 points ratio - set_pool_balance(bonded_pool.bonded_account(), 200); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 200); bonded_pool.points = 300; assert_eq!(bonded_pool.points_to_balance(10), 6); // 4 balance : 9 points ratio - set_pool_balance(bonded_pool.bonded_account(), 400); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), 400); bonded_pool.points = 900; assert_eq!(bonded_pool.points_to_balance(90), 40); }) @@ -270,21 +269,30 @@ mod bonded_pool { <::MaxPointsToBalance as Get>::get().into(); // Simulate a 100% slashed pool - set_pool_balance(pool.bonded_account(), 0); + StakingMock::set_bonded_balance(pool.bonded_account(), 0); assert_noop!(pool.ok_to_join(), Error::::OverflowRisk); // Simulate a slashed pool at `MaxPointsToBalance` + 1 slashed pool - set_pool_balance(pool.bonded_account(), max_points_to_balance.saturating_add(1)); + StakingMock::set_bonded_balance( + pool.bonded_account(), + max_points_to_balance.saturating_add(1), + ); assert_ok!(pool.ok_to_join()); // Simulate a slashed pool at `MaxPointsToBalance` - set_pool_balance(pool.bonded_account(), max_points_to_balance); + StakingMock::set_bonded_balance(pool.bonded_account(), max_points_to_balance); assert_noop!(pool.ok_to_join(), Error::::OverflowRisk); - set_pool_balance(pool.bonded_account(), Balance::MAX / max_points_to_balance); + StakingMock::set_bonded_balance( + pool.bonded_account(), + Balance::MAX / max_points_to_balance, + ); // and a sanity check - set_pool_balance(pool.bonded_account(), Balance::MAX / max_points_to_balance - 1); + StakingMock::set_bonded_balance( + pool.bonded_account(), + Balance::MAX / max_points_to_balance - 1, + ); assert_ok!(pool.ok_to_join()); }); } @@ -302,7 +310,7 @@ mod bonded_pool { state: PoolState::Open, }, }; - set_pool_balance(bonded_pool.bonded_account(), u128::MAX); + StakingMock::set_bonded_balance(bonded_pool.bonded_account(), u128::MAX); // Max out the points and balance of the pool and make sure the conversion works as // expected and does not overflow. @@ -632,6 +640,8 @@ mod sub_pools { } mod join { + use sp_runtime::TokenError; + use super::*; #[test] @@ -718,7 +728,7 @@ mod join { ); // Force the pools bonded balance to 0, simulating a 100% slash - set_pool_balance(Pools::generate_bonded_account(1), 0); + StakingMock::set_bonded_balance(Pools::generate_bonded_account(1), 0); assert_noop!( Pools::join(RuntimeOrigin::signed(11), 420, 1), Error::::OverflowRisk @@ -744,13 +754,29 @@ mod join { let max_points_to_balance: u128 = <::MaxPointsToBalance as Get>::get().into(); - set_pool_balance(Pools::generate_bonded_account(123), max_points_to_balance); + StakingMock::set_bonded_balance( + Pools::generate_bonded_account(123), + max_points_to_balance, + ); assert_noop!( Pools::join(RuntimeOrigin::signed(11), 420, 123), Error::::OverflowRisk ); - set_pool_balance(Pools::generate_bonded_account(1), max_points_to_balance); + StakingMock::set_bonded_balance( + Pools::generate_bonded_account(123), + Balance::MAX / max_points_to_balance, + ); + // Balance needs to be gt Balance::MAX / `MaxPointsToBalance` + assert_noop!( + Pools::join(RuntimeOrigin::signed(11), 5, 123), + TokenError::FundsUnavailable, + ); + + StakingMock::set_bonded_balance( + Pools::generate_bonded_account(1), + max_points_to_balance, + ); // Cannot join a pool that isn't open unsafe_set_state(123, PoolState::Blocked); @@ -781,7 +807,7 @@ mod join { #[cfg_attr(not(debug_assertions), should_panic)] fn join_panics_when_reward_pool_not_found() { ExtBuilder::default().build_and_execute(|| { - set_pool_balance(Pools::generate_bonded_account(123), 100); + StakingMock::set_bonded_balance(Pools::generate_bonded_account(123), 100); BondedPool:: { id: 123, inner: BondedPoolInner { @@ -2295,8 +2321,8 @@ mod claim_payout { fn rewards_are_rounded_down_depositor_collects_them() { ExtBuilder::default().add_members(vec![(20, 20)]).build_and_execute(|| { // initial balance of 10. - let init_balance_10 = Currency::free_balance(&10); - assert_eq!(member_delegation(10), 10); + + assert_eq!(Currency::free_balance(&10), 35); assert_eq!( Currency::free_balance(&default_reward_account()), Currency::minimum_balance() @@ -2347,10 +2373,8 @@ mod claim_payout { ); assert!(!Metadata::::contains_key(1)); - // original ed + ed put into reward account + reward + dust. - assert_eq!(Currency::free_balance(&10), init_balance_10 + 5 + 13 + 1); - // delegation reduced from 10 to 0. - assert_eq!(member_delegation(10), 0); + // original ed + ed put into reward account + reward + bond + dust. + assert_eq!(Currency::free_balance(&10), 35 + 5 + 13 + 10 + 1); }) } @@ -2420,10 +2444,9 @@ mod claim_payout { let claimable_reward = 8 - ExistentialDeposit::get(); // NOTE: easier to read if we use 3, so let's use the number instead of variable. assert_eq!(claimable_reward, 3, "test is correct if rewards are divisible by 3"); - let init_balance = Currency::free_balance(&10); // given - assert_eq!(member_delegation(10), 10); + assert_eq!(Currency::free_balance(&10), 35); // when @@ -2432,10 +2455,7 @@ mod claim_payout { assert_ok!(Pools::claim_payout_other(RuntimeOrigin::signed(80), 10)); // then - // delegated balance does not change. - assert_eq!(member_delegation(10), 10); - // reward of 1 is paid out to 10. - assert_eq!(Currency::free_balance(&10), init_balance + 1); + assert_eq!(Currency::free_balance(&10), 36); assert_eq!(Currency::free_balance(&default_reward_account()), 7); }) } @@ -2798,8 +2818,6 @@ mod unbond { ExtBuilder::default() .add_members(vec![(40, 40), (550, 550)]) .build_and_execute(|| { - let init_balance_40 = Currency::free_balance(&40); - let init_balance_550 = Currency::free_balance(&550); let ed = Currency::minimum_balance(); // Given a slash from 600 -> 500 StakingMock::slash_by(1, 500); @@ -2846,9 +2864,7 @@ mod unbond { PoolMembers::::get(40).unwrap().unbonding_eras, member_unbonding_eras!(3 => 6) ); - assert_eq!(member_delegation(40), 40); - // We claim rewards when unbonding - assert_eq!(Currency::free_balance(&40), init_balance_40 + 40); + assert_eq!(Currency::free_balance(&40), 40 + 40); // We claim rewards when unbonding // When unsafe_set_state(1, PoolState::Destroying); @@ -2877,8 +2893,7 @@ mod unbond { PoolMembers::::get(550).unwrap().unbonding_eras, member_unbonding_eras!(3 => 92) ); - assert_eq!(member_delegation(550), 550); - assert_eq!(Currency::free_balance(&550), init_balance_550 + 550); + assert_eq!(Currency::free_balance(&550), 550 + 550); assert_eq!( pool_events_since_last_call(), vec![ @@ -2919,8 +2934,7 @@ mod unbond { ); assert_eq!(StakingMock::active_stake(&default_bonded_account()).unwrap(), 0); - // 550 is removed from pool. - assert_eq!(member_delegation(550), 0); + assert_eq!(Currency::free_balance(&550), 550 + 550 + 92); assert_eq!( pool_events_since_last_call(), vec![ @@ -3518,7 +3532,7 @@ mod pool_withdraw_unbonded { assert_eq!(StakingMock::active_stake(&default_bonded_account()), Ok(15)); assert_eq!(StakingMock::total_stake(&default_bonded_account()), Ok(20)); - assert_eq!(pool_balance(1), 20); + assert_eq!(Balances::free_balance(&default_bonded_account()), 20); // When CurrentEra::set(StakingMock::current_era() + StakingMock::bonding_duration() + 1); @@ -3527,7 +3541,7 @@ mod pool_withdraw_unbonded { // Then their unbonding balance is no longer locked assert_eq!(StakingMock::active_stake(&default_bonded_account()), Ok(15)); assert_eq!(StakingMock::total_stake(&default_bonded_account()), Ok(15)); - assert_eq!(pool_balance(1), 20); + assert_eq!(Balances::free_balance(&default_bonded_account()), 20); }); } #[test] @@ -3538,7 +3552,7 @@ mod pool_withdraw_unbonded { assert_eq!(StakingMock::active_stake(&default_bonded_account()), Ok(15)); assert_eq!(StakingMock::total_stake(&default_bonded_account()), Ok(20)); - assert_eq!(pool_balance(1), 20); + assert_eq!(Balances::free_balance(&default_bonded_account()), 20); assert_eq!(TotalValueLocked::::get(), 20); // When @@ -3554,14 +3568,14 @@ mod pool_withdraw_unbonded { // Then their unbonding balance is no longer locked assert_eq!(StakingMock::active_stake(&default_bonded_account()), Ok(15)); assert_eq!(StakingMock::total_stake(&default_bonded_account()), Ok(15)); - assert_eq!(pool_balance(1), 20); + assert_eq!(Currency::free_balance(&default_bonded_account()), 20); // The difference between TVL and member_balance is exactly the difference between - // `pool balance` (sum of all balance delegated to pool) and the `staked balance`. - // This is the withdrawn funds from the pool stake that has not yet been claimed by the - // respective members. - let non_locked_balance = - pool_balance(1) - StakingMock::total_stake(&default_bonded_account()).unwrap(); + // `total_stake` and the `free_balance`. + // This relation is not guaranteed in the wild as arbitrary transfers towards + // `free_balance` can be made to the pool that are not accounted for. + let non_locked_balance = Balances::free_balance(&default_bonded_account()) - + StakingMock::total_stake(&default_bonded_account()).unwrap(); assert_eq!(member_balance, TotalValueLocked::::get() + non_locked_balance); }); } @@ -3583,7 +3597,7 @@ mod withdraw_unbonded { assert_eq!(StakingMock::bonding_duration(), 3); assert_ok!(Pools::fully_unbond(RuntimeOrigin::signed(550), 550)); assert_ok!(Pools::fully_unbond(RuntimeOrigin::signed(40), 40)); - assert_eq!(pool_balance(1), 600); + assert_eq!(Currency::free_balance(&default_bonded_account()), 600); let mut current_era = 1; CurrentEra::set(current_era); @@ -3612,7 +3626,10 @@ mod withdraw_unbonded { .1 /= 2; UnbondingBalanceMap::set(&x); - set_pool_balance(1, pool_balance(1) / 2); + Currency::set_balance( + &default_bonded_account(), + Currency::free_balance(&default_bonded_account()) / 2, // 300 + ); assert_eq!(StakingMock::active_stake(&default_bonded_account()).unwrap(), 10); StakingMock::slash_by(1, 5); assert_eq!(StakingMock::active_stake(&default_bonded_account()).unwrap(), 5); @@ -3654,6 +3671,11 @@ mod withdraw_unbonded { Event::PoolSlashed { pool_id: 1, balance: 5 } ] ); + assert_eq!( + balances_events_since_last_call(), + vec![BEvent::Burned { who: default_bonded_account(), amount: 300 }] + ); + // When assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(550), 550, 0)); @@ -3669,9 +3691,10 @@ mod withdraw_unbonded { Event::MemberRemoved { pool_id: 1, member: 550, released_balance: 0 } ] ); - - // member has 40 tokens in delegation, but only 20 can be withdrawan. - assert_eq!(member_delegation(40), 40); + assert_eq!( + balances_events_since_last_call(), + vec![BEvent::Transfer { from: default_bonded_account(), to: 550, amount: 275 }] + ); // When assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(40), 40, 0)); @@ -3685,18 +3708,18 @@ mod withdraw_unbonded { assert_eq!( pool_events_since_last_call(), vec![ - // out of 40, 20 is withdrawn. Event::Withdrawn { member: 40, pool_id: 1, balance: 20, points: 40 }, - // member is removed and the dangling delegation of 20 tokens left in their - // account is released. - Event::MemberRemoved { pool_id: 1, member: 40, released_balance: 20 } + Event::MemberRemoved { pool_id: 1, member: 40, released_balance: 0 } ] ); + assert_eq!( + balances_events_since_last_call(), + vec![BEvent::Transfer { from: default_bonded_account(), to: 40, amount: 20 }] + ); // now, finally, the depositor can take out its share. unsafe_set_state(1, PoolState::Destroying); assert_ok!(fully_unbond_permissioned(10)); - assert_eq!(member_delegation(10), 10); current_era += 3; CurrentEra::set(current_era); @@ -3708,9 +3731,7 @@ mod withdraw_unbonded { vec![ Event::Unbonded { member: 10, pool_id: 1, balance: 5, points: 5, era: 9 }, Event::Withdrawn { member: 10, pool_id: 1, balance: 5, points: 5 }, - // when member is removed, any leftover delegation is released. - Event::MemberRemoved { pool_id: 1, member: 10, released_balance: 5 }, - // when the last member leaves, the pool is destroyed. + Event::MemberRemoved { pool_id: 1, member: 10, released_balance: 0 }, Event::Destroyed { pool_id: 1 } ] ); @@ -3718,6 +3739,7 @@ mod withdraw_unbonded { assert_eq!( balances_events_since_last_call(), vec![ + BEvent::Transfer { from: default_bonded_account(), to: 10, amount: 5 }, BEvent::Thawed { who: default_reward_account(), amount: 5 }, BEvent::Transfer { from: default_reward_account(), to: 10, amount: 5 } ] @@ -3731,9 +3753,11 @@ mod withdraw_unbonded { .add_members(vec![(40, 40), (550, 550)]) .build_and_execute(|| { let _ = balances_events_since_last_call(); + // Given // current bond is 600, we slash it all to 300. StakingMock::slash_by(1, 300); + Currency::set_balance(&default_bonded_account(), 300); assert_eq!(StakingMock::total_stake(&default_bonded_account()), Ok(300)); assert_ok!(fully_unbond_permissioned(40)); @@ -3763,6 +3787,10 @@ mod withdraw_unbonded { } ] ); + assert_eq!( + balances_events_since_last_call(), + vec![BEvent::Burned { who: default_bonded_account(), amount: 300 },] + ); CurrentEra::set(StakingMock::bonding_duration()); @@ -3770,6 +3798,10 @@ mod withdraw_unbonded { assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(40), 40, 0)); // Then + assert_eq!( + balances_events_since_last_call(), + vec![BEvent::Transfer { from: default_bonded_account(), to: 40, amount: 20 },] + ); assert_eq!( pool_events_since_last_call(), vec![ @@ -3787,6 +3819,10 @@ mod withdraw_unbonded { assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(550), 550, 0)); // Then + assert_eq!( + balances_events_since_last_call(), + vec![BEvent::Transfer { from: default_bonded_account(), to: 550, amount: 275 },] + ); assert_eq!( pool_events_since_last_call(), vec![ @@ -3816,11 +3852,9 @@ mod withdraw_unbonded { assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0)); // then - assert_eq!( - DelegateMock::agent_balance(Agent::from(default_bonded_account())), - None - ); - assert_eq!(StakingMock::stake(&default_bonded_account()).unwrap().total, 0); + assert_eq!(Currency::free_balance(&10), 10 + 35); + assert_eq!(Currency::free_balance(&default_bonded_account()), 0); + // in this test 10 also gets a fair share of the slash, because the slash was // applied to the bonded account. assert_eq!( @@ -3836,6 +3870,7 @@ mod withdraw_unbonded { assert_eq!( balances_events_since_last_call(), vec![ + BEvent::Transfer { from: default_bonded_account(), to: 10, amount: 5 }, BEvent::Thawed { who: default_reward_account(), amount: 5 }, BEvent::Transfer { from: default_reward_account(), to: 10, amount: 5 } ] @@ -3843,6 +3878,35 @@ mod withdraw_unbonded { }); } + #[test] + fn withdraw_unbonded_handles_faulty_sub_pool_accounting() { + ExtBuilder::default().build_and_execute(|| { + // Given + assert_eq!(Currency::minimum_balance(), 5); + assert_eq!(Currency::free_balance(&10), 35); + assert_eq!(Currency::free_balance(&default_bonded_account()), 10); + unsafe_set_state(1, PoolState::Destroying); + assert_ok!(Pools::fully_unbond(RuntimeOrigin::signed(10), 10)); + + // Simulate a slash that is not accounted for in the sub pools. + Currency::set_balance(&default_bonded_account(), 5); + assert_eq!( + SubPoolsStorage::::get(1).unwrap().with_era, + //------------------------------balance decrease is not account for + unbonding_pools_with_era! { 3 => UnbondPool { points: 10, balance: 10 } } + ); + + CurrentEra::set(3); + + // When + assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0)); + + // Then + assert_eq!(Currency::free_balance(&10), 10 + 35); + assert_eq!(Currency::free_balance(&default_bonded_account()), 0); + }); + } + #[test] fn withdraw_unbonded_errors_correctly() { ExtBuilder::default().with_check(0).build_and_execute(|| { @@ -3861,10 +3925,6 @@ mod withdraw_unbonded { let mut member = PoolMember { pool_id: 1, points: 10, ..Default::default() }; PoolMembers::::insert(11, member.clone()); - // set agent and delegator balance - DelegateMock::set_agent_balance(Pools::generate_bonded_account(1), 10); - DelegateMock::set_delegator_balance(11, 10); - // Simulate calling `unbond` member.unbonding_eras = member_unbonding_eras!(3 => 10); PoolMembers::::insert(11, member.clone()); @@ -3985,7 +4045,7 @@ mod withdraw_unbonded { } ); CurrentEra::set(StakingMock::bonding_duration()); - assert_eq!(member_delegation(100), 100); + assert_eq!(Currency::free_balance(&100), 100); // Cannot permissionlessly withdraw assert_noop!( @@ -4001,7 +4061,6 @@ mod withdraw_unbonded { assert_eq!(SubPoolsStorage::::get(1).unwrap(), Default::default(),); assert_eq!(Currency::free_balance(&100), 100 + 100); - assert_eq!(member_delegation(100), 0); assert!(!PoolMembers::::contains_key(100)); assert_eq!( pool_events_since_last_call(), @@ -4603,6 +4662,10 @@ mod withdraw_unbonded { // move to era when unbonded funds can be withdrawn. CurrentEra::set(4); + + // increment consumer by 1 reproducing the erroneous consumer bug. + // refer /~https://github.com/paritytech/polkadot-sdk/issues/4440. + assert_ok!(frame_system::Pallet::::inc_consumers(&pool_one)); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0)); assert_eq!( @@ -4649,7 +4712,7 @@ mod create { )); assert_eq!(TotalValueLocked::::get(), 10 + StakingMock::minimum_nominator_bond()); - assert_eq!(member_delegation(11), StakingMock::minimum_nominator_bond()); + assert_eq!(Currency::free_balance(&11), 0); assert_eq!( PoolMembers::::get(11).unwrap(), PoolMember { @@ -4788,7 +4851,7 @@ mod create { 789 )); - assert_eq!(member_delegation(11), StakingMock::minimum_nominator_bond()); + assert_eq!(Currency::free_balance(&11), 0); // delete the initial pool created, then pool_Id `1` will be free assert_noop!( @@ -4951,9 +5014,16 @@ mod set_state { // surpassed. Making this pool destroyable by anyone. StakingMock::slash_by(1, 10); - // pending slash is correct. - assert_eq!(Pools::api_pool_pending_slash(1), 10); - assert_eq!(Pools::api_member_pending_slash(10), 10); + // in mock we are using transfer stake which implies slash is greedy. Extrinsic to + // apply pending slash should fail. + assert_noop!( + Pools::apply_slash(RuntimeOrigin::signed(11), 10), + Error::::NotSupported + ); + + // pending slash api should return zero as well. + assert_eq!(Pools::api_pool_pending_slash(1), 0); + assert_eq!(Pools::api_member_pending_slash(10), 0); // When assert_ok!(Pools::set_state(RuntimeOrigin::signed(11), 1, PoolState::Destroying)); @@ -5105,13 +5175,13 @@ mod bond_extra { // given assert_eq!(PoolMembers::::get(10).unwrap().points, 10); assert_eq!(BondedPools::::get(1).unwrap().points, 10); - assert_eq!(member_delegation(10), 10); + assert_eq!(Currency::free_balance(&10), 100); // when assert_ok!(Pools::bond_extra(RuntimeOrigin::signed(10), BondExtra::FreeBalance(10))); // then - assert_eq!(member_delegation(10), 10 + 10); + assert_eq!(Currency::free_balance(&10), 90); assert_eq!(PoolMembers::::get(10).unwrap().points, 20); assert_eq!(BondedPools::::get(1).unwrap().points, 20); @@ -5128,7 +5198,7 @@ mod bond_extra { assert_ok!(Pools::bond_extra(RuntimeOrigin::signed(10), BondExtra::FreeBalance(20))); // then - assert_eq!(member_delegation(10), 20 + 20); + assert_eq!(Currency::free_balance(&10), 70); assert_eq!(PoolMembers::::get(10).unwrap().points, 40); assert_eq!(BondedPools::::get(1).unwrap().points, 40); @@ -5151,15 +5221,13 @@ mod bond_extra { // given assert_eq!(PoolMembers::::get(10).unwrap().points, 10); assert_eq!(BondedPools::::get(1).unwrap().points, 10); - // 10 has delegated 10 tokens to the pool. - assert_eq!(member_delegation(10), 10); + assert_eq!(Currency::free_balance(&10), 35); // when assert_ok!(Pools::bond_extra(RuntimeOrigin::signed(10), BondExtra::Rewards)); // then - // delegator balance is increased by the claimable reward. - assert_eq!(member_delegation(10), 10 + claimable_reward); + assert_eq!(Currency::free_balance(&10), 35); assert_eq!(PoolMembers::::get(10).unwrap().points, 10 + claimable_reward); assert_eq!(BondedPools::::get(1).unwrap().points, 10 + claimable_reward); @@ -5196,8 +5264,8 @@ mod bond_extra { assert_eq!(PoolMembers::::get(20).unwrap().points, 20); assert_eq!(BondedPools::::get(1).unwrap().points, 30); - assert_eq!(member_delegation(10), 10); - assert_eq!(member_delegation(20), 20); + assert_eq!(Currency::free_balance(&10), 35); + assert_eq!(Currency::free_balance(&20), 20); assert_eq!(TotalValueLocked::::get(), 30); // when @@ -5205,7 +5273,7 @@ mod bond_extra { assert_eq!(Currency::free_balance(&default_reward_account()), 7); // then - assert_eq!(member_delegation(10), 10 + 1); + assert_eq!(Currency::free_balance(&10), 35); assert_eq!(TotalValueLocked::::get(), 31); // 10's share of the reward is 1/3, since they gave 10/30 of the total shares. @@ -5216,11 +5284,11 @@ mod bond_extra { assert_ok!(Pools::bond_extra(RuntimeOrigin::signed(20), BondExtra::Rewards)); // then + assert_eq!(Currency::free_balance(&20), 20); assert_eq!(TotalValueLocked::::get(), 33); // 20's share of the rewards is the other 2/3 of the rewards, since they have 20/30 of // the shares - assert_eq!(member_delegation(20), 20 + 2); assert_eq!(PoolMembers::::get(20).unwrap().points, 20 + 2); assert_eq!(BondedPools::::get(1).unwrap().points, 30 + 3); @@ -5252,8 +5320,8 @@ mod bond_extra { assert_eq!(PoolMembers::::get(10).unwrap().points, 10); assert_eq!(PoolMembers::::get(20).unwrap().points, 20); assert_eq!(BondedPools::::get(1).unwrap().points, 30); - assert_eq!(member_delegation(10), 10); - assert_eq!(member_delegation(20), 20); + assert_eq!(Currency::free_balance(&10), 35); + assert_eq!(Currency::free_balance(&20), 20); // Permissioned by default assert_noop!( @@ -5269,7 +5337,7 @@ mod bond_extra { assert_eq!(Currency::free_balance(&default_reward_account()), 7); // then - assert_eq!(member_delegation(10), 10 + 1); + assert_eq!(Currency::free_balance(&10), 35); assert_eq!(PoolMembers::::get(10).unwrap().points, 10 + 1); assert_eq!(BondedPools::::get(1).unwrap().points, 30 + 1); @@ -5287,7 +5355,7 @@ mod bond_extra { )); // then - assert_eq!(member_delegation(20), 20 + 10); + assert_eq!(Currency::free_balance(&20), 12); assert_eq!(Currency::free_balance(&default_reward_account()), 5); assert_eq!(PoolMembers::::get(20).unwrap().points, 30); assert_eq!(BondedPools::::get(1).unwrap().points, 41); @@ -7419,3 +7487,63 @@ mod chill { }) } } + +// the test mock is using `TransferStake` and so `DelegateStake` is not tested here. Extrinsics +// meant for `DelegateStake` should be gated. +// +// `DelegateStake` tests are in `pallet-nomination-pools-test-delegate-stake`. Since we support both +// strategies currently, we keep these tests as it is but in future we may remove `TransferStake` +// completely. +mod delegate_stake { + use super::*; + #[test] + fn delegation_specific_calls_are_gated() { + ExtBuilder::default().with_check(0).build_and_execute(|| { + // Given + Currency::set_balance(&11, ExistentialDeposit::get() + 2); + assert!(!PoolMembers::::contains_key(11)); + + // When + assert_ok!(Pools::join(RuntimeOrigin::signed(11), 2, 1)); + + // Then + assert_eq!( + pool_events_since_last_call(), + vec![ + Event::Created { depositor: 10, pool_id: 1 }, + Event::Bonded { member: 10, pool_id: 1, bonded: 10, joined: true }, + Event::Bonded { member: 11, pool_id: 1, bonded: 2, joined: true }, + ] + ); + + assert_eq!( + PoolMembers::::get(11).unwrap(), + PoolMember:: { pool_id: 1, points: 2, ..Default::default() } + ); + + // ensure pool 1 cannot be migrated. + assert!(!Pools::api_pool_needs_delegate_migration(1)); + assert_noop!( + Pools::migrate_pool_to_delegate_stake(RuntimeOrigin::signed(10), 1), + Error::::NotSupported + ); + + // members cannot be migrated either. + assert!(!Pools::api_member_needs_delegate_migration(10)); + assert_noop!( + Pools::migrate_delegation(RuntimeOrigin::signed(10), 11), + Error::::NotSupported + ); + + // Given + // The bonded balance is slashed in half + StakingMock::slash_by(1, 6); + + // since slash is greedy with `TransferStake`, `apply_slash` should not work either. + assert_noop!( + Pools::apply_slash(RuntimeOrigin::signed(10), 11), + Error::::NotSupported + ); + }); + } +} diff --git a/substrate/frame/nomination-pools/test-delegate-stake/src/lib.rs b/substrate/frame/nomination-pools/test-delegate-stake/src/lib.rs index 54783332aa3e..cc6335959ab7 100644 --- a/substrate/frame/nomination-pools/test-delegate-stake/src/lib.rs +++ b/substrate/frame/nomination-pools/test-delegate-stake/src/lib.rs @@ -21,10 +21,7 @@ mod mock; use frame_support::{ assert_noop, assert_ok, hypothetically, - traits::{ - fungible::{InspectHold, Mutate}, - Currency, - }, + traits::{fungible::InspectHold, Currency}, }; use mock::*; use pallet_nomination_pools::{ @@ -945,12 +942,8 @@ fn pool_slash_non_proportional_bonded_pool_and_chunks() { fn pool_migration_e2e() { new_test_ext().execute_with(|| { LegacyAdapter::set(true); - assert_eq!(CurrentEra::::get(), None); - - // hack: mint ED to pool so that the deprecated `TransferStake` works correctly with - // staking. assert_eq!(Balances::minimum_balance(), 5); - assert_ok!(Balances::mint_into(&POOL1_BONDED, 5)); + assert_eq!(CurrentEra::::get(), None); // create the pool with TransferStake strategy. assert_ok!(Pools::create(RuntimeOrigin::signed(10), 50, 10, 10, 10)); @@ -1057,11 +1050,10 @@ fn pool_migration_e2e() { assert_eq!( delegated_staking_events_since_last_call(), - // delegated also contains the extra ED that we minted when pool was `TransferStake` . vec![DelegatedStakingEvent::Delegated { agent: POOL1_BONDED, delegator: proxy_delegator_1, - amount: 50 + 10 * 3 + 5 + amount: 50 + 10 * 3 }] ); @@ -1231,11 +1223,6 @@ fn disable_pool_operations_on_non_migrated() { assert_eq!(Balances::minimum_balance(), 5); assert_eq!(CurrentEra::::get(), None); - // hack: mint ED to pool so that the deprecated `TransferStake` works correctly with - // staking. - assert_eq!(Balances::minimum_balance(), 5); - assert_ok!(Balances::mint_into(&POOL1_BONDED, 5)); - // create the pool with TransferStake strategy. assert_ok!(Pools::create(RuntimeOrigin::signed(10), 50, 10, 10, 10)); assert_eq!(LastPoolId::::get(), 1); @@ -1344,12 +1331,11 @@ fn disable_pool_operations_on_non_migrated() { assert_ok!(Pools::migrate_pool_to_delegate_stake(RuntimeOrigin::signed(10), 1)); assert_eq!( delegated_staking_events_since_last_call(), - // delegated also contains the extra ED that we minted when pool was `TransferStake` . vec![DelegatedStakingEvent::Delegated { agent: POOL1_BONDED, delegator: DelegatedStaking::generate_proxy_delegator(Agent::from(POOL1_BONDED)) .get(), - amount: 50 + 10 + 5 + amount: 50 + 10 },] ); diff --git a/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs b/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs index d943ba6f5333..d1bc4ef8ff28 100644 --- a/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs +++ b/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs @@ -15,9 +15,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Disable warnings for `TransferStake` being deprecated. -#![allow(deprecated)] - use frame_election_provider_support::VoteWeight; use frame_support::{ assert_ok, derive_impl, @@ -95,7 +92,6 @@ parameter_types! { #[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] impl pallet_staking::Config for Runtime { - type OldCurrency = Balances; type Currency = Balances; type UnixTime = pallet_timestamp::Pallet; type AdminOrigin = frame_system::EnsureRoot; diff --git a/substrate/frame/nomination-pools/test-transfer-stake/Cargo.toml b/substrate/frame/nomination-pools/test-transfer-stake/Cargo.toml new file mode 100644 index 000000000000..0b21d5f4e8cf --- /dev/null +++ b/substrate/frame/nomination-pools/test-transfer-stake/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "pallet-nomination-pools-test-transfer-stake" +version = "1.0.0" +authors.workspace = true +edition.workspace = true +license = "Apache-2.0" +homepage.workspace = true +repository.workspace = true +description = "FRAME nomination pools pallet tests with the staking pallet" +publish = false + +[lints] +workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dev-dependencies] +codec = { features = ["derive"], workspace = true, default-features = true } +scale-info = { features = ["derive"], workspace = true, default-features = true } + +sp-core = { workspace = true, default-features = true } +sp-io = { workspace = true, default-features = true } +sp-runtime = { workspace = true, default-features = true } +sp-staking = { workspace = true, default-features = true } + +frame-election-provider-support = { workspace = true, default-features = true } +frame-support = { workspace = true, default-features = true } +frame-system = { workspace = true, default-features = true } + +pallet-bags-list = { workspace = true, default-features = true } +pallet-balances = { workspace = true, default-features = true } +pallet-nomination-pools = { workspace = true, default-features = true } +pallet-staking = { workspace = true, default-features = true } +pallet-staking-reward-curve = { workspace = true, default-features = true } +pallet-timestamp = { workspace = true, default-features = true } + +log = { workspace = true, default-features = true } +sp-tracing = { workspace = true, default-features = true } diff --git a/substrate/frame/nomination-pools/test-transfer-stake/src/lib.rs b/substrate/frame/nomination-pools/test-transfer-stake/src/lib.rs new file mode 100644 index 000000000000..cc39cfee91c8 --- /dev/null +++ b/substrate/frame/nomination-pools/test-transfer-stake/src/lib.rs @@ -0,0 +1,912 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg(test)] + +mod mock; + +use frame_support::{assert_noop, assert_ok, traits::Currency}; +use mock::*; +use pallet_nomination_pools::{ + BondExtra, BondedPools, Error as PoolsError, Event as PoolsEvent, LastPoolId, PoolMember, + PoolMembers, PoolState, +}; +use pallet_staking::{ + CurrentEra, Error as StakingError, Event as StakingEvent, Payee, RewardDestination, +}; +use sp_runtime::{bounded_btree_map, traits::Zero}; + +#[test] +fn pool_lifecycle_e2e() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::minimum_balance(), 5); + assert_eq!(CurrentEra::::get(), None); + + // create the pool, we know this has id 1. + assert_ok!(Pools::create(RuntimeOrigin::signed(10), 50, 10, 10, 10)); + assert_eq!(LastPoolId::::get(), 1); + + // have the pool nominate. + assert_ok!(Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3])); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Bonded { stash: POOL1_BONDED, amount: 50 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Created { depositor: 10, pool_id: 1 }, + PoolsEvent::Bonded { member: 10, pool_id: 1, bonded: 50, joined: true }, + ] + ); + + // have two members join + assert_ok!(Pools::join(RuntimeOrigin::signed(20), 10, 1)); + assert_ok!(Pools::join(RuntimeOrigin::signed(21), 10, 1)); + + assert_eq!( + staking_events_since_last_call(), + vec![ + StakingEvent::Bonded { stash: POOL1_BONDED, amount: 10 }, + StakingEvent::Bonded { stash: POOL1_BONDED, amount: 10 }, + ] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Bonded { member: 20, pool_id: 1, bonded: 10, joined: true }, + PoolsEvent::Bonded { member: 21, pool_id: 1, bonded: 10, joined: true }, + ] + ); + + // pool goes into destroying + assert_ok!(Pools::set_state(RuntimeOrigin::signed(10), 1, PoolState::Destroying)); + + // depositor cannot unbond yet. + assert_noop!( + Pools::unbond(RuntimeOrigin::signed(10), 10, 50), + PoolsError::::MinimumBondNotMet, + ); + + // now the members want to unbond. + assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 10)); + assert_ok!(Pools::unbond(RuntimeOrigin::signed(21), 21, 10)); + + assert_eq!(PoolMembers::::get(20).unwrap().unbonding_eras.len(), 1); + assert_eq!(PoolMembers::::get(20).unwrap().points, 0); + assert_eq!(PoolMembers::::get(21).unwrap().unbonding_eras.len(), 1); + assert_eq!(PoolMembers::::get(21).unwrap().points, 0); + + assert_eq!( + staking_events_since_last_call(), + vec![ + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 10 }, + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 10 }, + ] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::StateChanged { pool_id: 1, new_state: PoolState::Destroying }, + PoolsEvent::Unbonded { member: 20, pool_id: 1, points: 10, balance: 10, era: 3 }, + PoolsEvent::Unbonded { member: 21, pool_id: 1, points: 10, balance: 10, era: 3 }, + ] + ); + + // depositor cannot still unbond + assert_noop!( + Pools::unbond(RuntimeOrigin::signed(10), 10, 50), + PoolsError::::MinimumBondNotMet, + ); + + for e in 1..BondingDuration::get() { + CurrentEra::::set(Some(e)); + assert_noop!( + Pools::withdraw_unbonded(RuntimeOrigin::signed(20), 20, 0), + PoolsError::::CannotWithdrawAny + ); + } + + // members are now unlocked. + CurrentEra::::set(Some(BondingDuration::get())); + + // depositor cannot still unbond + assert_noop!( + Pools::unbond(RuntimeOrigin::signed(10), 10, 50), + PoolsError::::MinimumBondNotMet, + ); + + // but members can now withdraw. + assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(20), 20, 0)); + assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(21), 21, 0)); + assert!(PoolMembers::::get(20).is_none()); + assert!(PoolMembers::::get(21).is_none()); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Withdrawn { stash: POOL1_BONDED, amount: 20 },] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Withdrawn { member: 20, pool_id: 1, points: 10, balance: 10 }, + PoolsEvent::MemberRemoved { pool_id: 1, member: 20, released_balance: 0 }, + PoolsEvent::Withdrawn { member: 21, pool_id: 1, points: 10, balance: 10 }, + PoolsEvent::MemberRemoved { pool_id: 1, member: 21, released_balance: 0 }, + ] + ); + + // as soon as all members have left, the depositor can try to unbond, but since the + // min-nominator intention is set, they must chill first. + assert_noop!( + Pools::unbond(RuntimeOrigin::signed(10), 10, 50), + pallet_staking::Error::::InsufficientBond + ); + + assert_ok!(Pools::chill(RuntimeOrigin::signed(10), 1)); + assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 50)); + + assert_eq!( + staking_events_since_last_call(), + vec![ + StakingEvent::Chilled { stash: POOL1_BONDED }, + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 50 }, + ] + ); + assert_eq!( + pool_events_since_last_call(), + vec![PoolsEvent::Unbonded { member: 10, pool_id: 1, points: 50, balance: 50, era: 6 }] + ); + + // waiting another bonding duration: + CurrentEra::::set(Some(BondingDuration::get() * 2)); + assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 1)); + + // pools is fully destroyed now. + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Withdrawn { stash: POOL1_BONDED, amount: 50 },] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Withdrawn { member: 10, pool_id: 1, points: 50, balance: 50 }, + PoolsEvent::MemberRemoved { pool_id: 1, member: 10, released_balance: 0 }, + PoolsEvent::Destroyed { pool_id: 1 } + ] + ); + }) +} + +#[test] +fn destroy_pool_with_erroneous_consumer() { + new_test_ext().execute_with(|| { + // create the pool, we know this has id 1. + assert_ok!(Pools::create(RuntimeOrigin::signed(10), 50, 10, 10, 10)); + assert_eq!(LastPoolId::::get(), 1); + + // expect consumers on pool account to be 2 (staking lock and an explicit inc by staking). + assert_eq!(frame_system::Pallet::::consumers(&POOL1_BONDED), 2); + + // increment consumer by 1 reproducing the erroneous consumer bug. + // refer /~https://github.com/paritytech/polkadot-sdk/issues/4440. + assert_ok!(frame_system::Pallet::::inc_consumers(&POOL1_BONDED)); + assert_eq!(frame_system::Pallet::::consumers(&POOL1_BONDED), 3); + + // have the pool nominate. + assert_ok!(Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3])); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Bonded { stash: POOL1_BONDED, amount: 50 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Created { depositor: 10, pool_id: 1 }, + PoolsEvent::Bonded { member: 10, pool_id: 1, bonded: 50, joined: true }, + ] + ); + + // pool goes into destroying + assert_ok!(Pools::set_state(RuntimeOrigin::signed(10), 1, PoolState::Destroying)); + + assert_eq!( + pool_events_since_last_call(), + vec![PoolsEvent::StateChanged { pool_id: 1, new_state: PoolState::Destroying },] + ); + + // move to era 1 + CurrentEra::::set(Some(1)); + + // depositor need to chill before unbonding + assert_noop!( + Pools::unbond(RuntimeOrigin::signed(10), 10, 50), + pallet_staking::Error::::InsufficientBond + ); + + assert_ok!(Pools::chill(RuntimeOrigin::signed(10), 1)); + assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 50)); + + assert_eq!( + staking_events_since_last_call(), + vec![ + StakingEvent::Chilled { stash: POOL1_BONDED }, + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 50 }, + ] + ); + assert_eq!( + pool_events_since_last_call(), + vec![PoolsEvent::Unbonded { + member: 10, + pool_id: 1, + points: 50, + balance: 50, + era: 1 + 3 + }] + ); + + // waiting bonding duration: + CurrentEra::::set(Some(1 + 3)); + // this should work even with an extra consumer count on pool account. + assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 1)); + + // pools is fully destroyed now. + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Withdrawn { stash: POOL1_BONDED, amount: 50 },] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Withdrawn { member: 10, pool_id: 1, points: 50, balance: 50 }, + PoolsEvent::MemberRemoved { pool_id: 1, member: 10, released_balance: 0 }, + PoolsEvent::Destroyed { pool_id: 1 } + ] + ); + }) +} + +#[test] +fn pool_chill_e2e() { + new_test_ext().execute_with(|| { + assert_eq!(Balances::minimum_balance(), 5); + assert_eq!(CurrentEra::::get(), None); + + // create the pool, we know this has id 1. + assert_ok!(Pools::create(RuntimeOrigin::signed(10), 50, 10, 10, 10)); + assert_eq!(LastPoolId::::get(), 1); + + // have the pool nominate. + assert_ok!(Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3])); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Bonded { stash: POOL1_BONDED, amount: 50 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Created { depositor: 10, pool_id: 1 }, + PoolsEvent::Bonded { member: 10, pool_id: 1, bonded: 50, joined: true }, + ] + ); + + // have two members join + assert_ok!(Pools::join(RuntimeOrigin::signed(20), 10, 1)); + assert_ok!(Pools::join(RuntimeOrigin::signed(21), 10, 1)); + + assert_eq!( + staking_events_since_last_call(), + vec![ + StakingEvent::Bonded { stash: POOL1_BONDED, amount: 10 }, + StakingEvent::Bonded { stash: POOL1_BONDED, amount: 10 }, + ] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Bonded { member: 20, pool_id: 1, bonded: 10, joined: true }, + PoolsEvent::Bonded { member: 21, pool_id: 1, bonded: 10, joined: true }, + ] + ); + + // in case depositor does not have more than `MinNominatorBond` staked, we can end up in + // situation where a member unbonding would cause pool balance to drop below + // `MinNominatorBond` and hence not allowed. This can happen if the `MinNominatorBond` is + // increased after the pool is created. + assert_ok!(Staking::set_staking_configs( + RuntimeOrigin::root(), + pallet_staking::ConfigOp::Set(55), // minimum nominator bond + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + )); + + // members can unbond as long as total stake of the pool is above min nominator bond + assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 10),); + assert_eq!(PoolMembers::::get(20).unwrap().unbonding_eras.len(), 1); + assert_eq!(PoolMembers::::get(20).unwrap().points, 0); + + // this member cannot unbond since it will cause `pool stake < MinNominatorBond` + assert_noop!( + Pools::unbond(RuntimeOrigin::signed(21), 21, 10), + StakingError::::InsufficientBond, + ); + + // members can call `chill` permissionlessly now + assert_ok!(Pools::chill(RuntimeOrigin::signed(20), 1)); + + // now another member can unbond. + assert_ok!(Pools::unbond(RuntimeOrigin::signed(21), 21, 10)); + assert_eq!(PoolMembers::::get(21).unwrap().unbonding_eras.len(), 1); + assert_eq!(PoolMembers::::get(21).unwrap().points, 0); + + // nominator can not resume nomination until depositor have enough stake + assert_noop!( + Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3]), + PoolsError::::MinimumBondNotMet, + ); + + // other members joining pool does not affect the depositor's ability to resume nomination + assert_ok!(Pools::join(RuntimeOrigin::signed(22), 10, 1)); + + assert_noop!( + Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3]), + PoolsError::::MinimumBondNotMet, + ); + + // depositor can bond extra stake + assert_ok!(Pools::bond_extra(RuntimeOrigin::signed(10), BondExtra::FreeBalance(10))); + + // `chill` can not be called permissionlessly anymore + assert_noop!( + Pools::chill(RuntimeOrigin::signed(20), 1), + PoolsError::::NotNominator, + ); + + // now nominator can resume nomination + assert_ok!(Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3])); + + // skip to make the unbonding period end. + CurrentEra::::set(Some(BondingDuration::get())); + + // members can now withdraw. + assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(20), 20, 0)); + assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(21), 21, 0)); + + assert_eq!( + staking_events_since_last_call(), + vec![ + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 10 }, + StakingEvent::Chilled { stash: POOL1_BONDED }, + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 10 }, + StakingEvent::Bonded { stash: POOL1_BONDED, amount: 10 }, // other member bonding + StakingEvent::Bonded { stash: POOL1_BONDED, amount: 10 }, // depositor bond extra + StakingEvent::Withdrawn { stash: POOL1_BONDED, amount: 20 }, + ] + ); + }) +} + +#[test] +fn pool_slash_e2e() { + new_test_ext().execute_with(|| { + ExistentialDeposit::set(1); + assert_eq!(Balances::minimum_balance(), 1); + assert_eq!(CurrentEra::::get(), None); + + // create the pool, we know this has id 1. + assert_ok!(Pools::create(RuntimeOrigin::signed(10), 40, 10, 10, 10)); + assert_eq!(LastPoolId::::get(), 1); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Bonded { stash: POOL1_BONDED, amount: 40 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Created { depositor: 10, pool_id: 1 }, + PoolsEvent::Bonded { member: 10, pool_id: 1, bonded: 40, joined: true }, + ] + ); + + assert_eq!( + Payee::::get(POOL1_BONDED), + Some(RewardDestination::Account(POOL1_REWARD)) + ); + + // have two members join + assert_ok!(Pools::join(RuntimeOrigin::signed(20), 20, 1)); + assert_ok!(Pools::join(RuntimeOrigin::signed(21), 20, 1)); + + assert_eq!( + staking_events_since_last_call(), + vec![ + StakingEvent::Bonded { stash: POOL1_BONDED, amount: 20 }, + StakingEvent::Bonded { stash: POOL1_BONDED, amount: 20 } + ] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Bonded { member: 20, pool_id: 1, bonded: 20, joined: true }, + PoolsEvent::Bonded { member: 21, pool_id: 1, bonded: 20, joined: true }, + ] + ); + + // now let's progress a bit. + CurrentEra::::set(Some(1)); + + // 20 / 80 of the total funds are unlocked, and safe from any further slash. + assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 10)); + assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 10)); + + assert_eq!( + staking_events_since_last_call(), + vec![ + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 10 }, + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 10 } + ] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Unbonded { member: 10, pool_id: 1, balance: 10, points: 10, era: 4 }, + PoolsEvent::Unbonded { member: 20, pool_id: 1, balance: 10, points: 10, era: 4 } + ] + ); + + CurrentEra::::set(Some(2)); + + // note: depositor cannot fully unbond at this point. + // these funds will still get slashed. + assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 10)); + assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 10)); + assert_ok!(Pools::unbond(RuntimeOrigin::signed(21), 21, 10)); + + assert_eq!( + staking_events_since_last_call(), + vec![ + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 10 }, + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 10 }, + StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 10 }, + ] + ); + + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Unbonded { member: 10, pool_id: 1, balance: 10, points: 10, era: 5 }, + PoolsEvent::Unbonded { member: 20, pool_id: 1, balance: 10, points: 10, era: 5 }, + PoolsEvent::Unbonded { member: 21, pool_id: 1, balance: 10, points: 10, era: 5 }, + ] + ); + + // At this point, 20 are safe from slash, 30 are unlocking but vulnerable to slash, and + // another 30 are active and vulnerable to slash. Let's slash half of them. + pallet_staking::slashing::do_slash::( + &POOL1_BONDED, + 30, + &mut Default::default(), + &mut Default::default(), + 2, // slash era 2, affects chunks at era 5 onwards. + ); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Slashed { staker: POOL1_BONDED, amount: 30 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + // 30 has been slashed to 15 (15 slash) + PoolsEvent::UnbondingPoolSlashed { pool_id: 1, era: 5, balance: 15 }, + // 30 has been slashed to 15 (15 slash) + PoolsEvent::PoolSlashed { pool_id: 1, balance: 15 } + ] + ); + + CurrentEra::::set(Some(3)); + assert_ok!(Pools::unbond(RuntimeOrigin::signed(21), 21, 10)); + + assert_eq!( + PoolMembers::::get(21).unwrap(), + PoolMember { + pool_id: 1, + points: 0, + last_recorded_reward_counter: Zero::zero(), + // the 10 points unlocked just now correspond to 5 points in the unbond pool. + unbonding_eras: bounded_btree_map!(5 => 10, 6 => 5) + } + ); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 5 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![PoolsEvent::Unbonded { member: 21, pool_id: 1, balance: 5, points: 5, era: 6 }] + ); + + // now we start withdrawing. we do it all at once, at era 6 where 20 and 21 are fully free. + CurrentEra::::set(Some(6)); + assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(20), 20, 0)); + assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(21), 21, 0)); + + assert_eq!( + pool_events_since_last_call(), + vec![ + // 20 had unbonded 10 safely, and 10 got slashed by half. + PoolsEvent::Withdrawn { member: 20, pool_id: 1, balance: 10 + 5, points: 20 }, + PoolsEvent::MemberRemoved { pool_id: 1, member: 20, released_balance: 0 }, + // 21 unbonded all of it after the slash + PoolsEvent::Withdrawn { member: 21, pool_id: 1, balance: 5 + 5, points: 15 }, + PoolsEvent::MemberRemoved { pool_id: 1, member: 21, released_balance: 0 } + ] + ); + assert_eq!( + staking_events_since_last_call(), + // a 10 (un-slashed) + 10/2 (slashed) balance from 10 has also been unlocked + vec![StakingEvent::Withdrawn { stash: POOL1_BONDED, amount: 15 + 10 + 15 }] + ); + + // now, finally, we can unbond the depositor further than their current limit. + assert_ok!(Pools::set_state(RuntimeOrigin::signed(10), 1, PoolState::Destroying)); + assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 20)); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Unbonded { stash: POOL1_BONDED, amount: 10 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::StateChanged { pool_id: 1, new_state: PoolState::Destroying }, + PoolsEvent::Unbonded { member: 10, pool_id: 1, points: 10, balance: 10, era: 9 } + ] + ); + + CurrentEra::::set(Some(9)); + assert_eq!( + PoolMembers::::get(10).unwrap(), + PoolMember { + pool_id: 1, + points: 0, + last_recorded_reward_counter: Zero::zero(), + unbonding_eras: bounded_btree_map!(4 => 10, 5 => 10, 9 => 10) + } + ); + // withdraw the depositor, they should lose 12 balance in total due to slash. + assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0)); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Withdrawn { stash: POOL1_BONDED, amount: 10 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Withdrawn { member: 10, pool_id: 1, balance: 10 + 15, points: 30 }, + PoolsEvent::MemberRemoved { pool_id: 1, member: 10, released_balance: 0 }, + PoolsEvent::Destroyed { pool_id: 1 } + ] + ); + }); +} + +#[test] +fn pool_slash_proportional() { + // a typical example where 3 pool members unbond in era 99, 100, and 101, and a slash that + // happened in era 100 should only affect the latter two. + new_test_ext().execute_with(|| { + ExistentialDeposit::set(1); + BondingDuration::set(28); + assert_eq!(Balances::minimum_balance(), 1); + assert_eq!(CurrentEra::::get(), None); + + // create the pool, we know this has id 1. + assert_ok!(Pools::create(RuntimeOrigin::signed(10), 40, 10, 10, 10)); + assert_eq!(LastPoolId::::get(), 1); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Bonded { stash: POOL1_BONDED, amount: 40 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Created { depositor: 10, pool_id: 1 }, + PoolsEvent::Bonded { member: 10, pool_id: 1, bonded: 40, joined: true }, + ] + ); + + // have two members join + let bond = 20; + assert_ok!(Pools::join(RuntimeOrigin::signed(20), bond, 1)); + assert_ok!(Pools::join(RuntimeOrigin::signed(21), bond, 1)); + assert_ok!(Pools::join(RuntimeOrigin::signed(22), bond, 1)); + + assert_eq!( + staking_events_since_last_call(), + vec![ + StakingEvent::Bonded { stash: POOL1_BONDED, amount: bond }, + StakingEvent::Bonded { stash: POOL1_BONDED, amount: bond }, + StakingEvent::Bonded { stash: POOL1_BONDED, amount: bond }, + ] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Bonded { member: 20, pool_id: 1, bonded: bond, joined: true }, + PoolsEvent::Bonded { member: 21, pool_id: 1, bonded: bond, joined: true }, + PoolsEvent::Bonded { member: 22, pool_id: 1, bonded: bond, joined: true }, + ] + ); + + // now let's progress a lot. + CurrentEra::::set(Some(99)); + + // and unbond + assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, bond)); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Unbonded { stash: POOL1_BONDED, amount: bond },] + ); + assert_eq!( + pool_events_since_last_call(), + vec![PoolsEvent::Unbonded { + member: 20, + pool_id: 1, + balance: bond, + points: bond, + era: 127 + }] + ); + + CurrentEra::::set(Some(100)); + assert_ok!(Pools::unbond(RuntimeOrigin::signed(21), 21, bond)); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Unbonded { stash: POOL1_BONDED, amount: bond },] + ); + assert_eq!( + pool_events_since_last_call(), + vec![PoolsEvent::Unbonded { + member: 21, + pool_id: 1, + balance: bond, + points: bond, + era: 128 + }] + ); + + CurrentEra::::set(Some(101)); + assert_ok!(Pools::unbond(RuntimeOrigin::signed(22), 22, bond)); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Unbonded { stash: POOL1_BONDED, amount: bond },] + ); + assert_eq!( + pool_events_since_last_call(), + vec![PoolsEvent::Unbonded { + member: 22, + pool_id: 1, + balance: bond, + points: bond, + era: 129 + }] + ); + + // Apply a slash that happened in era 100. This is typically applied with a delay. + // Of the total 100, 50 is slashed. + assert_eq!(BondedPools::::get(1).unwrap().points, 40); + pallet_staking::slashing::do_slash::( + &POOL1_BONDED, + 50, + &mut Default::default(), + &mut Default::default(), + 100, + ); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Slashed { staker: POOL1_BONDED, amount: 50 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + // This era got slashed 12.5, which rounded up to 13. + PoolsEvent::UnbondingPoolSlashed { pool_id: 1, era: 128, balance: 7 }, + // This era got slashed 12 instead of 12.5 because an earlier chunk got 0.5 more + // slashed, and 12 is all the remaining slash + PoolsEvent::UnbondingPoolSlashed { pool_id: 1, era: 129, balance: 8 }, + // Bonded pool got slashed for 25, remaining 15 in it. + PoolsEvent::PoolSlashed { pool_id: 1, balance: 15 } + ] + ); + }); +} + +#[test] +fn pool_slash_non_proportional_only_bonded_pool() { + // A typical example where a pool member unbonds in era 99, and they can get away with a slash + // that happened in era 100, as long as the pool has enough active bond to cover the slash. If + // everything else in the slashing/staking system works, this should always be the case. + // Nonetheless, `ledger.slash` has been written such that it will slash greedily from any chunk + // if it runs out of chunks that it thinks should be affected by the slash. + new_test_ext().execute_with(|| { + ExistentialDeposit::set(1); + BondingDuration::set(28); + assert_eq!(Balances::minimum_balance(), 1); + assert_eq!(CurrentEra::::get(), None); + + // create the pool, we know this has id 1. + assert_ok!(Pools::create(RuntimeOrigin::signed(10), 40, 10, 10, 10)); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Bonded { stash: POOL1_BONDED, amount: 40 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Created { depositor: 10, pool_id: 1 }, + PoolsEvent::Bonded { member: 10, pool_id: 1, bonded: 40, joined: true }, + ] + ); + + // have two members join + let bond = 20; + assert_ok!(Pools::join(RuntimeOrigin::signed(20), bond, 1)); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Bonded { stash: POOL1_BONDED, amount: bond }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![PoolsEvent::Bonded { member: 20, pool_id: 1, bonded: bond, joined: true }] + ); + + // progress and unbond. + CurrentEra::::set(Some(99)); + assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, bond)); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Unbonded { stash: POOL1_BONDED, amount: bond }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![PoolsEvent::Unbonded { + member: 20, + pool_id: 1, + balance: bond, + points: bond, + era: 127 + }] + ); + + // slash for 30. This will be deducted only from the bonded pool. + CurrentEra::::set(Some(100)); + assert_eq!(BondedPools::::get(1).unwrap().points, 40); + pallet_staking::slashing::do_slash::( + &POOL1_BONDED, + 30, + &mut Default::default(), + &mut Default::default(), + 100, + ); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Slashed { staker: POOL1_BONDED, amount: 30 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![PoolsEvent::PoolSlashed { pool_id: 1, balance: 10 }] + ); + }); +} + +#[test] +fn pool_slash_non_proportional_bonded_pool_and_chunks() { + // An uncommon example where even though some funds are unlocked such that they should not be + // affected by a slash, we still slash out of them. This should not happen at all. If a + // nomination has unbonded, from the next era onwards, their exposure will drop, so if an era + // happens in that era, then their share of that slash should naturally be less, such that only + // their active ledger stake is enough to compensate it. + new_test_ext().execute_with(|| { + ExistentialDeposit::set(1); + BondingDuration::set(28); + assert_eq!(Balances::minimum_balance(), 1); + assert_eq!(CurrentEra::::get(), None); + + // create the pool, we know this has id 1. + assert_ok!(Pools::create(RuntimeOrigin::signed(10), 40, 10, 10, 10)); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Bonded { stash: POOL1_BONDED, amount: 40 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + PoolsEvent::Created { depositor: 10, pool_id: 1 }, + PoolsEvent::Bonded { member: 10, pool_id: 1, bonded: 40, joined: true }, + ] + ); + + // have two members join + let bond = 20; + assert_ok!(Pools::join(RuntimeOrigin::signed(20), bond, 1)); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Bonded { stash: POOL1_BONDED, amount: bond }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![PoolsEvent::Bonded { member: 20, pool_id: 1, bonded: bond, joined: true }] + ); + + // progress and unbond. + CurrentEra::::set(Some(99)); + assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, bond)); + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Unbonded { stash: POOL1_BONDED, amount: bond }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![PoolsEvent::Unbonded { + member: 20, + pool_id: 1, + balance: bond, + points: bond, + era: 127 + }] + ); + + // slash 50. This will be deducted only from the bonded pool and one of the unbonding pools. + CurrentEra::::set(Some(100)); + assert_eq!(BondedPools::::get(1).unwrap().points, 40); + pallet_staking::slashing::do_slash::( + &POOL1_BONDED, + 50, + &mut Default::default(), + &mut Default::default(), + 100, + ); + + assert_eq!( + staking_events_since_last_call(), + vec![StakingEvent::Slashed { staker: POOL1_BONDED, amount: 50 }] + ); + assert_eq!( + pool_events_since_last_call(), + vec![ + // out of 20, 10 was taken. + PoolsEvent::UnbondingPoolSlashed { pool_id: 1, era: 127, balance: 10 }, + // out of 40, all was taken. + PoolsEvent::PoolSlashed { pool_id: 1, balance: 0 } + ] + ); + }); +} diff --git a/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs b/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs new file mode 100644 index 000000000000..d913c5fe6948 --- /dev/null +++ b/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs @@ -0,0 +1,231 @@ +// This file is part of Substrate. + +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use frame_election_provider_support::VoteWeight; +use frame_support::{ + assert_ok, derive_impl, + pallet_prelude::*, + parameter_types, + traits::{ConstU64, ConstU8, VariantCountOf}, + PalletId, +}; +use sp_runtime::{ + traits::{Convert, IdentityLookup}, + BuildStorage, FixedU128, Perbill, +}; + +type AccountId = u128; +type BlockNumber = u64; +type Balance = u128; + +pub(crate) type T = Runtime; + +pub(crate) const POOL1_BONDED: AccountId = 20318131474730217858575332831085u128; +pub(crate) const POOL1_REWARD: AccountId = 20397359637244482196168876781421u128; + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] +impl frame_system::Config for Runtime { + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Block = Block; + type AccountData = pallet_balances::AccountData; +} + +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = ConstU64<5>; + type WeightInfo = (); +} + +parameter_types! { + pub static ExistentialDeposit: Balance = 5; +} + +#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] +impl pallet_balances::Config for Runtime { + type Balance = Balance; + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type FreezeIdentifier = RuntimeFreezeReason; + type MaxFreezes = VariantCountOf; + type RuntimeFreezeReason = RuntimeFreezeReason; +} + +pallet_staking_reward_curve::build! { + const I_NPOS: sp_runtime::curve::PiecewiseLinear<'static> = curve!( + min_inflation: 0_025_000, + max_inflation: 0_100_000, + ideal_stake: 0_500_000, + falloff: 0_050_000, + max_piece_count: 40, + test_precision: 0_005_000, + ); +} + +parameter_types! { + pub const RewardCurve: &'static sp_runtime::curve::PiecewiseLinear<'static> = &I_NPOS; + pub static BondingDuration: u32 = 3; +} + +#[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] +impl pallet_staking::Config for Runtime { + type Currency = Balances; + type UnixTime = pallet_timestamp::Pallet; + type AdminOrigin = frame_system::EnsureRoot; + type BondingDuration = BondingDuration; + type EraPayout = pallet_staking::ConvertCurve; + type ElectionProvider = + frame_election_provider_support::NoElection<(AccountId, BlockNumber, Staking, ())>; + type GenesisElectionProvider = Self::ElectionProvider; + type VoterList = VoterList; + type TargetList = pallet_staking::UseValidatorsMap; + type EventListeners = Pools; + type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig; +} + +parameter_types! { + pub static BagThresholds: &'static [VoteWeight] = &[10, 20, 30, 40, 50, 60, 1_000, 2_000, 10_000]; +} + +type VoterBagsListInstance = pallet_bags_list::Instance1; +impl pallet_bags_list::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type BagThresholds = BagThresholds; + type ScoreProvider = Staking; + type Score = VoteWeight; +} + +pub struct BalanceToU256; +impl Convert for BalanceToU256 { + fn convert(n: Balance) -> sp_core::U256 { + n.into() + } +} + +pub struct U256ToBalance; +impl Convert for U256ToBalance { + fn convert(n: sp_core::U256) -> Balance { + n.try_into().unwrap() + } +} + +parameter_types! { + pub const PostUnbondingPoolsWindow: u32 = 10; + pub const PoolsPalletId: PalletId = PalletId(*b"py/nopls"); +} + +impl pallet_nomination_pools::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type Currency = Balances; + type RuntimeFreezeReason = RuntimeFreezeReason; + type RewardCounter = FixedU128; + type BalanceToU256 = BalanceToU256; + type U256ToBalance = U256ToBalance; + type StakeAdapter = pallet_nomination_pools::adapter::TransferStake; + type PostUnbondingPoolsWindow = PostUnbondingPoolsWindow; + type MaxMetadataLen = ConstU32<256>; + type MaxUnbonding = ConstU32<8>; + type MaxPointsToBalance = ConstU8<10>; + type PalletId = PoolsPalletId; + type AdminOrigin = frame_system::EnsureRoot; +} + +type Block = frame_system::mocking::MockBlock; + +frame_support::construct_runtime!( + pub enum Runtime { + System: frame_system, + Timestamp: pallet_timestamp, + Balances: pallet_balances, + Staking: pallet_staking, + VoterList: pallet_bags_list::, + Pools: pallet_nomination_pools, + } +); + +pub fn new_test_ext() -> sp_io::TestExternalities { + sp_tracing::try_init_simple(); + let mut storage = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let _ = pallet_nomination_pools::GenesisConfig:: { + min_join_bond: 2, + min_create_bond: 2, + max_pools: Some(3), + max_members_per_pool: Some(5), + max_members: Some(3 * 5), + global_max_commission: Some(Perbill::from_percent(90)), + } + .assimilate_storage(&mut storage) + .unwrap(); + + let _ = pallet_balances::GenesisConfig:: { + balances: vec![(10, 100), (20, 100), (21, 100), (22, 100)], + } + .assimilate_storage(&mut storage) + .unwrap(); + + let mut ext = sp_io::TestExternalities::from(storage); + + ext.execute_with(|| { + // for events to be deposited. + frame_system::Pallet::::set_block_number(1); + + // set some limit for nominations. + assert_ok!(Staking::set_staking_configs( + RuntimeOrigin::root(), + pallet_staking::ConfigOp::Set(10), // minimum nominator bond + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + pallet_staking::ConfigOp::Noop, + )); + }); + + ext +} + +parameter_types! { + static ObservedEventsPools: usize = 0; + static ObservedEventsStaking: usize = 0; + static ObservedEventsBalances: usize = 0; +} + +pub(crate) fn pool_events_since_last_call() -> Vec> { + let events = System::events() + .into_iter() + .map(|r| r.event) + .filter_map(|e| if let RuntimeEvent::Pools(inner) = e { Some(inner) } else { None }) + .collect::>(); + let already_seen = ObservedEventsPools::get(); + ObservedEventsPools::set(events.len()); + events.into_iter().skip(already_seen).collect() +} + +pub(crate) fn staking_events_since_last_call() -> Vec> { + let events = System::events() + .into_iter() + .map(|r| r.event) + .filter_map(|e| if let RuntimeEvent::Staking(inner) = e { Some(inner) } else { None }) + .collect::>(); + let already_seen = ObservedEventsStaking::get(); + ObservedEventsStaking::set(events.len()); + events.into_iter().skip(already_seen).collect() +} diff --git a/substrate/frame/offences/benchmarking/src/inner.rs b/substrate/frame/offences/benchmarking/src/inner.rs index 3d3cd470bc24..75f3e9931e34 100644 --- a/substrate/frame/offences/benchmarking/src/inner.rs +++ b/substrate/frame/offences/benchmarking/src/inner.rs @@ -180,12 +180,16 @@ where ::RuntimeEvent: TryInto>, { // make sure that all slashes have been applied - // deposit to reporter + reporter account endowed. - assert_eq!(System::::read_events_for_pallet::>().len(), 2); + // (n nominators + one validator) * (slashed + unlocked) + deposit to reporter + + // reporter account endowed + some funds rescinded from issuance. + assert_eq!( + System::::read_events_for_pallet::>().len(), + 2 * (offender_count + 1) + 3 + ); // (n nominators + one validator) * slashed + Slash Reported assert_eq!( System::::read_events_for_pallet::>().len(), - 1 * (offender_count + 1) as usize + 1 + 1 * (offender_count + 1) + 1 ); // offence assert_eq!(System::::read_events_for_pallet::().len(), 1); diff --git a/substrate/frame/offences/benchmarking/src/mock.rs b/substrate/frame/offences/benchmarking/src/mock.rs index 3c81f2a664e3..c5c178aa4443 100644 --- a/substrate/frame/offences/benchmarking/src/mock.rs +++ b/substrate/frame/offences/benchmarking/src/mock.rs @@ -125,7 +125,6 @@ impl onchain::Config for OnChainSeqPhragmen { #[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] impl pallet_staking::Config for Test { - type OldCurrency = Balances; type Currency = Balances; type CurrencyBalance = ::Balance; type UnixTime = pallet_timestamp::Pallet; diff --git a/substrate/frame/root-offences/src/mock.rs b/substrate/frame/root-offences/src/mock.rs index 3f14dc00b560..7a96b8eade4e 100644 --- a/substrate/frame/root-offences/src/mock.rs +++ b/substrate/frame/root-offences/src/mock.rs @@ -126,7 +126,6 @@ parameter_types! { #[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] impl pallet_staking::Config for Test { - type OldCurrency = Balances; type Currency = Balances; type CurrencyBalance = ::Balance; type UnixTime = Timestamp; @@ -207,10 +206,10 @@ impl ExtBuilder { (30, self.balance_factor * 50), (40, self.balance_factor * 50), // stashes - (11, self.balance_factor * 1500), - (21, self.balance_factor * 1500), - (31, self.balance_factor * 1000), - (41, self.balance_factor * 2000), + (11, self.balance_factor * 1000), + (21, self.balance_factor * 1000), + (31, self.balance_factor * 500), + (41, self.balance_factor * 1000), ], } .assimilate_storage(&mut storage) diff --git a/substrate/frame/session/benchmarking/src/mock.rs b/substrate/frame/session/benchmarking/src/mock.rs index 74201da3d2f3..346cd04c0fa9 100644 --- a/substrate/frame/session/benchmarking/src/mock.rs +++ b/substrate/frame/session/benchmarking/src/mock.rs @@ -133,7 +133,6 @@ impl onchain::Config for OnChainSeqPhragmen { #[derive_impl(pallet_staking::config_preludes::TestDefaultConfig)] impl pallet_staking::Config for Test { - type OldCurrency = Balances; type Currency = Balances; type CurrencyBalance = ::Balance; type UnixTime = pallet_timestamp::Pallet; diff --git a/substrate/frame/staking/Cargo.toml b/substrate/frame/staking/Cargo.toml index 74b1c78e9cbe..22176b6d720b 100644 --- a/substrate/frame/staking/Cargo.toml +++ b/substrate/frame/staking/Cargo.toml @@ -41,7 +41,6 @@ rand_chacha = { optional = true, workspace = true } [dev-dependencies] frame-benchmarking = { workspace = true, default-features = true } frame-election-provider-support = { workspace = true, default-features = true } -frame-support = { features = ["experimental"], workspace = true, default-features = true } pallet-bags-list = { workspace = true, default-features = true } pallet-balances = { workspace = true, default-features = true } pallet-staking-reward-curve = { workspace = true, default-features = true } diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index a1140d317c20..23368b1f8fca 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -18,15 +18,9 @@ //! Contains all the interactions with [`Config::Currency`] to manipulate the underlying staking //! asset. -use crate::{BalanceOf, Config, HoldReason, NegativeImbalanceOf, PositiveImbalanceOf}; -use frame_support::traits::{ - fungible::{ - hold::{Balanced as FunHoldBalanced, Inspect as FunHoldInspect, Mutate as FunHoldMutate}, - Balanced, Inspect as FunInspect, - }, - tokens::{Fortitude, Precision, Preservation}, -}; -use sp_runtime::{DispatchResult, Saturating}; +use frame_support::traits::{Currency, InspectLockableCurrency, LockableCurrency}; + +use crate::{BalanceOf, Config, NegativeImbalanceOf, PositiveImbalanceOf}; /// Existential deposit for the chain. pub fn existential_deposit() -> BalanceOf { @@ -38,7 +32,7 @@ pub fn total_issuance() -> BalanceOf { T::Currency::total_issuance() } -/// Total balance of `who`. Includes both free and staked. +/// Total balance of `who`. Includes both, free and reserved. pub fn total_balance(who: &T::AccountId) -> BalanceOf { T::Currency::total_balance(who) } @@ -47,65 +41,42 @@ pub fn total_balance(who: &T::AccountId) -> BalanceOf { /// /// This includes balance free to stake along with any balance that is already staked. pub fn stakeable_balance(who: &T::AccountId) -> BalanceOf { - free_to_stake::(who).saturating_add(staked::(who)) + T::Currency::free_balance(who) } /// Balance of `who` that is currently at stake. /// -/// The staked amount is on hold and cannot be transferred out of `who`s account. +/// The staked amount is locked and cannot be transferred out of `who`s account. pub fn staked(who: &T::AccountId) -> BalanceOf { - T::Currency::balance_on_hold(&HoldReason::Staking.into(), who) -} - -/// Balance of who that can be staked additionally. -/// -/// Does not include the current stake. -pub fn free_to_stake(who: &T::AccountId) -> BalanceOf { - // since we want to be able to use frozen funds for staking, we force the reduction. - T::Currency::reducible_balance(who, Preservation::Preserve, Fortitude::Force) + T::Currency::balance_locked(crate::STAKING_ID, who) } /// Set balance that can be staked for `who`. /// -/// If `Value` is lower than the current staked balance, the difference is unlocked. -/// -/// Should only be used with test. +/// This includes any balance that is already staked. #[cfg(any(test, feature = "runtime-benchmarks"))] pub fn set_stakeable_balance(who: &T::AccountId, value: BalanceOf) { - use frame_support::traits::fungible::Mutate; - - // minimum free balance (non-staked) required to keep the account alive. - let ed = existential_deposit::(); - // currently on stake - let staked_balance = staked::(who); - - // if new value is greater than staked balance, mint some free balance. - if value > staked_balance { - let _ = T::Currency::set_balance(who, value - staked_balance + ed); - } else { - // else reduce the staked balance. - update_stake::(who, value).expect("can remove from what is staked"); - // burn all free, only leaving ED. - let _ = T::Currency::set_balance(who, ed); - } - - // ensure new stakeable balance same as desired `value`. - assert_eq!(stakeable_balance::(who), value); + T::Currency::make_free_balance_be(who, value); } /// Update `amount` at stake for `who`. /// /// Overwrites the existing stake amount. If passed amount is lower than the existing stake, the /// difference is unlocked. -pub fn update_stake(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { - T::Currency::set_on_hold(&HoldReason::Staking.into(), who, amount) +pub fn update_stake(who: &T::AccountId, amount: BalanceOf) { + T::Currency::set_lock( + crate::STAKING_ID, + who, + amount, + frame_support::traits::WithdrawReasons::all(), + ); } -/// Release all staked amount to `who`. +/// Kill the stake of `who`. /// -/// Fails if there are consumers left on `who` that restricts it from being reaped. -pub fn kill_stake(who: &T::AccountId) -> DispatchResult { - T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort).map(|_| ()) +/// All locked amount is unlocked. +pub fn kill_stake(who: &T::AccountId) { + T::Currency::remove_lock(crate::STAKING_ID, who); } /// Slash the value from `who`. @@ -115,32 +86,29 @@ pub fn slash( who: &T::AccountId, value: BalanceOf, ) -> (NegativeImbalanceOf, BalanceOf) { - T::Currency::slash(&HoldReason::Staking.into(), who, value) + T::Currency::slash(who, value) } /// Mint `value` into an existing account `who`. /// /// This does not increase the total issuance. -pub fn mint_into_existing( +pub fn mint_existing( who: &T::AccountId, value: BalanceOf, ) -> Option> { - // since the account already exists, we mint exact value even if value is below ED. - T::Currency::deposit(who, value, Precision::Exact).ok() + T::Currency::deposit_into_existing(who, value).ok() } -/// Mint `value` and create account for `who` if it does not exist. -/// -/// If value is below existential deposit, the account is not created. +/// Mint reward and create account for `who` if it does not exist. /// -/// Note: This does not increase the total issuance. +/// This does not increase the total issuance. pub fn mint_creating(who: &T::AccountId, value: BalanceOf) -> PositiveImbalanceOf { - T::Currency::deposit(who, value, Precision::BestEffort).unwrap_or_default() + T::Currency::deposit_creating(who, value) } /// Deposit newly issued or slashed `value` into `who`. pub fn deposit_slashed(who: &T::AccountId, value: NegativeImbalanceOf) { - let _ = T::Currency::resolve(who, value); + T::Currency::resolve_creating(who, value) } /// Issue `value` increasing total issuance. @@ -153,5 +121,5 @@ pub fn issue(value: BalanceOf) -> NegativeImbalanceOf { /// Burn the amount from the total issuance. #[cfg(feature = "runtime-benchmarks")] pub fn burn(amount: BalanceOf) -> PositiveImbalanceOf { - T::Currency::rescind(amount) + T::Currency::burn(amount) } diff --git a/substrate/frame/staking/src/benchmarking.rs b/substrate/frame/staking/src/benchmarking.rs index 59d272168d68..79d8dd3fbc30 100644 --- a/substrate/frame/staking/src/benchmarking.rs +++ b/substrate/frame/staking/src/benchmarking.rs @@ -257,11 +257,7 @@ mod benchmarks { .map(|l| l.active) .ok_or("ledger not created after")?; - let _ = asset::mint_into_existing::( - &stash, - max_additional + asset::existential_deposit::(), - ) - .unwrap(); + let _ = asset::mint_existing::(&stash, max_additional).unwrap(); whitelist_account!(stash); @@ -1137,23 +1133,6 @@ mod benchmarks { Ok(()) } - #[benchmark] - fn migrate_currency() -> Result<(), BenchmarkError> { - let (stash, _ctrl) = - create_stash_controller::(USER_SEED, 100, RewardDestination::Staked)?; - let stake = asset::staked::(&stash); - migrate_to_old_currency::(stash.clone()); - // no holds - assert!(asset::staked::(&stash).is_zero()); - whitelist_account!(stash); - - #[extrinsic_call] - _(RawOrigin::Signed(stash.clone()), stash.clone()); - - assert_eq!(asset::staked::(&stash), stake); - Ok(()) - } - impl_benchmark_test_suite!( Staking, crate::mock::ExtBuilder::default().has_stakers(true), diff --git a/substrate/frame/staking/src/ledger.rs b/substrate/frame/staking/src/ledger.rs index 1d66ebd27e9f..ac3be04cf607 100644 --- a/substrate/frame/staking/src/ledger.rs +++ b/substrate/frame/staking/src/ledger.rs @@ -32,7 +32,6 @@ //! state consistency. use frame_support::{defensive, ensure, traits::Defensive}; -use sp_runtime::DispatchResult; use sp_staking::{StakingAccount, StakingInterface}; use crate::{ @@ -188,8 +187,7 @@ impl StakingLedger { // We skip locking virtual stakers. if !Pallet::::is_virtual_staker(&self.stash) { // for direct stakers, update lock on stash based on ledger. - asset::update_stake::(&self.stash, self.total) - .map_err(|_| Error::::NotEnoughFunds)?; + asset::update_stake::(&self.stash, self.total); } Ledger::::insert( @@ -252,7 +250,7 @@ impl StakingLedger { /// Clears all data related to a staking ledger and its bond in both [`Ledger`] and [`Bonded`] /// storage items and updates the stash staking lock. - pub(crate) fn kill(stash: &T::AccountId) -> DispatchResult { + pub(crate) fn kill(stash: &T::AccountId) -> Result<(), Error> { let controller = >::get(stash).ok_or(Error::::NotStash)?; >::get(&controller).ok_or(Error::::NotController).map(|ledger| { @@ -261,9 +259,9 @@ impl StakingLedger { >::remove(&stash); // kill virtual staker if it exists. - if >::take(&ledger.stash).is_none() { + if >::take(&stash).is_none() { // if not virtual staker, clear locks. - asset::kill_stake::(&ledger.stash)?; + asset::kill_stake::(&ledger.stash); } Ok(()) diff --git a/substrate/frame/staking/src/lib.rs b/substrate/frame/staking/src/lib.rs index 42230cb27b75..6361663b2b1c 100644 --- a/substrate/frame/staking/src/lib.rs +++ b/substrate/frame/staking/src/lib.rs @@ -312,8 +312,7 @@ use codec::{Decode, Encode, HasCompact, MaxEncodedLen}; use frame_support::{ defensive, defensive_assert, traits::{ - tokens::fungible::{Credit, Debt}, - ConstU32, Defensive, DefensiveMax, DefensiveSaturating, Get, LockIdentifier, + ConstU32, Currency, Defensive, DefensiveMax, DefensiveSaturating, Get, LockIdentifier, }, weights::Weight, BoundedVec, CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, @@ -362,9 +361,12 @@ pub type RewardPoint = u32; /// The balance type of this pallet. pub type BalanceOf = ::CurrencyBalance; -type PositiveImbalanceOf = Debt<::AccountId, ::Currency>; -pub type NegativeImbalanceOf = - Credit<::AccountId, ::Currency>; +type PositiveImbalanceOf = <::Currency as Currency< + ::AccountId, +>>::PositiveImbalance; +pub type NegativeImbalanceOf = <::Currency as Currency< + ::AccountId, +>>::NegativeImbalance; type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index 6346949576fa..769b84826b41 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -25,7 +25,8 @@ use frame_election_provider_support::{ use frame_support::{ assert_ok, derive_impl, ord_parameter_types, parameter_types, traits::{ - ConstU64, EitherOfDiverse, FindAuthor, Get, Imbalance, OnUnbalanced, OneSessionHandler, + ConstU64, Currency, EitherOfDiverse, FindAuthor, Get, Imbalance, LockableCurrency, + OnUnbalanced, OneSessionHandler, WithdrawReasons, }, weights::constants::RocksDbWeight, }; @@ -263,7 +264,6 @@ pub(crate) const DISABLING_LIMIT_FACTOR: usize = 3; #[derive_impl(crate::config_preludes::TestDefaultConfig)] impl crate::pallet::pallet::Config for Test { - type OldCurrency = Balances; type Currency = Balances; type UnixTime = Timestamp; type RewardRemainder = RewardRemainderMock; @@ -432,7 +432,6 @@ impl ExtBuilder { fn build(self) -> sp_io::TestExternalities { sp_tracing::try_init_simple(); let mut storage = frame_system::GenesisConfig::::default().build_storage().unwrap(); - let ed = ExistentialDeposit::get(); let _ = pallet_balances::GenesisConfig:: { balances: vec![ @@ -447,23 +446,19 @@ impl ExtBuilder { (40, self.balance_factor), (50, self.balance_factor), // stashes - // Note: Previously this pallet used locks and stakers could stake all their - // balance including ED. Now with holds, stakers are required to maintain - // (non-staked) ED in their accounts. Therefore, we drop an additional existential - // deposit to genesis stakers. - (11, self.balance_factor * 1000 + ed), - (21, self.balance_factor * 2000 + ed), - (31, self.balance_factor * 2000 + ed), - (41, self.balance_factor * 2000 + ed), - (51, self.balance_factor * 2000 + ed), - (201, self.balance_factor * 2000 + ed), - (202, self.balance_factor * 2000 + ed), + (11, self.balance_factor * 1000), + (21, self.balance_factor * 2000), + (31, self.balance_factor * 2000), + (41, self.balance_factor * 2000), + (51, self.balance_factor * 2000), + (201, self.balance_factor * 2000), + (202, self.balance_factor * 2000), // optional nominator - (100, self.balance_factor * 2000 + ed), - (101, self.balance_factor * 2000 + ed), + (100, self.balance_factor * 2000), + (101, self.balance_factor * 2000), // aux accounts (60, self.balance_factor), - (61, self.balance_factor * 2000 + ed), + (61, self.balance_factor * 2000), (70, self.balance_factor), (71, self.balance_factor * 2000), (80, self.balance_factor), @@ -580,7 +575,7 @@ pub(crate) fn current_era() -> EraIndex { } pub(crate) fn bond(who: AccountId, val: Balance) { - let _ = asset::set_stakeable_balance::(&who, val); + let _ = Balances::make_free_balance_be(&who, val); assert_ok!(Staking::bond(RuntimeOrigin::signed(who), val, RewardDestination::Stash)); } @@ -605,6 +600,10 @@ pub(crate) fn bond_virtual_nominator( val: Balance, target: Vec, ) { + // In a real scenario, `who` is a keyless account managed by another pallet which provides for + // it. + System::inc_providers(&who); + // Bond who virtually. assert_ok!(::virtual_bond(&who, val, &payee)); assert_ok!(Staking::nominate(RuntimeOrigin::signed(who), target)); @@ -810,7 +809,7 @@ pub(crate) fn bond_extra_no_checks(stash: &AccountId, amount: Balance) { let mut ledger = Ledger::::get(&controller).expect("ledger must exist to bond_extra"); let new_total = ledger.total + amount; - let _ = asset::update_stake::(stash, new_total); + Balances::set_lock(crate::STAKING_ID, stash, new_total, WithdrawReasons::all()); ledger.total = new_total; ledger.active = new_total; Ledger::::insert(controller, ledger); @@ -819,10 +818,10 @@ pub(crate) fn bond_extra_no_checks(stash: &AccountId, amount: Balance) { pub(crate) fn setup_double_bonded_ledgers() { let init_ledgers = Ledger::::iter().count(); - let _ = asset::set_stakeable_balance::(&333, 2000); - let _ = asset::set_stakeable_balance::(&444, 2000); - let _ = asset::set_stakeable_balance::(&555, 2000); - let _ = asset::set_stakeable_balance::(&777, 2000); + let _ = Balances::make_free_balance_be(&333, 2000); + let _ = Balances::make_free_balance_be(&444, 2000); + let _ = Balances::make_free_balance_be(&555, 2000); + let _ = Balances::make_free_balance_be(&777, 2000); assert_ok!(Staking::bond(RuntimeOrigin::signed(333), 10, RewardDestination::Staked)); assert_ok!(Staking::bond(RuntimeOrigin::signed(444), 20, RewardDestination::Staked)); @@ -924,5 +923,5 @@ pub(crate) fn staking_events_since_last_call() -> Vec> { } pub(crate) fn balances(who: &AccountId) -> (Balance, Balance) { - (asset::stakeable_balance::(who), Balances::reserved_balance(who)) + (Balances::free_balance(who), Balances::reserved_balance(who)) } diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 8c3ff23315a4..2ae925d03643 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -27,8 +27,8 @@ use frame_support::{ dispatch::WithPostDispatchInfo, pallet_prelude::*, traits::{ - Defensive, DefensiveSaturating, EstimateNextNewSession, Get, Imbalance, - InspectLockableCurrency, Len, LockableCurrency, OnUnbalanced, TryCollect, UnixTime, + Defensive, DefensiveSaturating, EstimateNextNewSession, Get, Imbalance, Len, OnUnbalanced, + TryCollect, UnixTime, }, weights::Weight, }; @@ -36,9 +36,10 @@ use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin}; use pallet_session::historical; use sp_runtime::{ traits::{ - Bounded, CheckedAdd, Convert, One, SaturatedConversion, Saturating, StaticLookup, Zero, + Bounded, CheckedAdd, CheckedSub, Convert, One, SaturatedConversion, Saturating, + StaticLookup, Zero, }, - ArithmeticError, DispatchResult, Perbill, Percent, + ArithmeticError, Perbill, Percent, }; use sp_staking::{ currency_to_vote::CurrencyToVote, @@ -53,7 +54,6 @@ use crate::{ BalanceOf, EraInfo, EraPayout, Exposure, ExposureOf, Forcing, IndividualExposure, LedgerIntegrityState, MaxNominationsOf, MaxWinnersOf, Nominations, NominationsQuota, PositiveImbalanceOf, RewardDestination, SessionInterface, StakingLedger, ValidatorPrefs, - STAKING_ID, }; use alloc::{boxed::Box, vec, vec::Vec}; @@ -96,12 +96,10 @@ impl Pallet { pub(crate) fn inspect_bond_state( stash: &T::AccountId, ) -> Result> { - // look at any old unmigrated lock as well. - let hold_or_lock = asset::staked::(&stash) - .max(T::OldCurrency::balance_locked(STAKING_ID, &stash).into()); + let lock = asset::staked::(&stash); let controller = >::get(stash).ok_or_else(|| { - if hold_or_lock == Zero::zero() { + if lock == Zero::zero() { Error::::NotStash } else { Error::::BadState @@ -113,7 +111,7 @@ impl Pallet { if ledger.stash != *stash { Ok(LedgerIntegrityState::Corrupted) } else { - if hold_or_lock != ledger.total { + if lock != ledger.total { Ok(LedgerIntegrityState::LockCorrupted) } else { Ok(LedgerIntegrityState::Ok) @@ -165,7 +163,11 @@ impl Pallet { additional } else { // additional amount or actual balance of stash whichever is lower. - additional.min(asset::free_to_stake::(stash)) + additional.min( + asset::stakeable_balance::(stash) + .checked_sub(&ledger.total) + .ok_or(ArithmeticError::Overflow)?, + ) }; ledger.total = ledger.total.checked_add(&extra).ok_or(ArithmeticError::Overflow)?; @@ -414,12 +416,12 @@ impl Pallet { let dest = Self::payee(StakingAccount::Stash(stash.clone()))?; let maybe_imbalance = match dest { - RewardDestination::Stash => asset::mint_into_existing::(stash, amount), + RewardDestination::Stash => asset::mint_existing::(stash, amount), RewardDestination::Staked => Self::ledger(Stash(stash.clone())) .and_then(|mut ledger| { ledger.active += amount; ledger.total += amount; - let r = asset::mint_into_existing::(stash, amount); + let r = asset::mint_existing::(stash, amount); let _ = ledger .update() @@ -797,6 +799,8 @@ impl Pallet { Self::do_remove_validator(&stash); Self::do_remove_nominator(&stash); + frame_system::Pallet::::dec_consumers(&stash); + Ok(()) } @@ -1159,81 +1163,6 @@ impl Pallet { ) -> Exposure> { EraInfo::::get_full_exposure(era, account) } - - pub(super) fn do_migrate_currency(stash: &T::AccountId) -> DispatchResult { - if Self::is_virtual_staker(stash) { - return Self::do_migrate_virtual_staker(stash); - } - - let ledger = Self::ledger(Stash(stash.clone()))?; - let staked: BalanceOf = T::OldCurrency::balance_locked(STAKING_ID, stash).into(); - ensure!(!staked.is_zero(), Error::::AlreadyMigrated); - ensure!(ledger.total == staked, Error::::BadState); - - // remove old staking lock - T::OldCurrency::remove_lock(STAKING_ID, &stash); - - // check if we can hold all stake. - let max_hold = asset::free_to_stake::(&stash); - let force_withdraw = if max_hold >= staked { - // this means we can hold all stake. yay! - asset::update_stake::(&stash, staked)?; - Zero::zero() - } else { - // if we are here, it means we cannot hold all user stake. We will do a force withdraw - // from ledger, but that's okay since anyways user do not have funds for it. - let force_withdraw = staked.saturating_sub(max_hold); - - // we ignore if active is 0. It implies the locked amount is not actively staked. The - // account can still get away from potential slash but we can't do much better here. - StakingLedger { - total: max_hold, - active: ledger.active.saturating_sub(force_withdraw), - // we are not changing the stash, so we can keep the stash. - ..ledger - } - .update()?; - force_withdraw - }; - - // Get rid of the extra consumer we used to have with OldCurrency. - frame_system::Pallet::::dec_consumers(&stash); - - Self::deposit_event(Event::::CurrencyMigrated { stash: stash.clone(), force_withdraw }); - Ok(()) - } - - fn do_migrate_virtual_staker(stash: &T::AccountId) -> DispatchResult { - // Funds for virtual stakers not managed/held by this pallet. We only need to clear - // the extra consumer we used to have with OldCurrency. - frame_system::Pallet::::dec_consumers(&stash); - - // The delegation system that manages the virtual staker needed to increment provider - // previously because of the consumer needed by this pallet. In reality, this stash - // is just a key for managing the ledger and the account does not need to hold any - // balance or exist. We decrement this provider. - let actual_providers = frame_system::Pallet::::providers(stash); - - let expected_providers = - // provider is expected to be 1 but someone can always transfer some free funds to - // these accounts, increasing the provider. - if asset::free_to_stake::(&stash) >= asset::existential_deposit::() { - 2 - } else { - 1 - }; - - // We should never have more than expected providers. - ensure!(actual_providers <= expected_providers, Error::::BadState); - - // if actual provider is less than expected, it is already migrated. - ensure!(actual_providers == expected_providers, Error::::AlreadyMigrated); - - // dec provider - let _ = frame_system::Pallet::::dec_providers(&stash)?; - - return Ok(()) - } } impl Pallet { @@ -1996,10 +1925,9 @@ impl StakingInterface for Pallet { } impl sp_staking::StakingUnchecked for Pallet { - fn migrate_to_virtual_staker(who: &Self::AccountId) -> DispatchResult { - asset::kill_stake::(who)?; + fn migrate_to_virtual_staker(who: &Self::AccountId) { + asset::kill_stake::(who); VirtualStakers::::insert(who, ()); - Ok(()) } /// Virtually bonds `keyless_who` to `payee` with `value`. @@ -2017,6 +1945,9 @@ impl sp_staking::StakingUnchecked for Pallet { // check if payee not same as who. ensure!(keyless_who != payee, Error::::RewardDestinationRestricted); + // mark this pallet as consumer of `who`. + frame_system::Pallet::::inc_consumers(&keyless_who).map_err(|_| Error::::BadState)?; + // mark who as a virtual staker. VirtualStakers::::insert(keyless_who, ()); @@ -2028,13 +1959,11 @@ impl sp_staking::StakingUnchecked for Pallet { Ok(()) } - /// Only meant to be used in tests. #[cfg(feature = "runtime-benchmarks")] fn migrate_to_direct_staker(who: &Self::AccountId) { assert!(VirtualStakers::::contains_key(who)); let ledger = StakingLedger::::get(Stash(who.clone())).unwrap(); - let _ = asset::update_stake::(who, ledger.total) - .expect("funds must be transferred to stash"); + asset::update_stake::(who, ledger.total); VirtualStakers::::remove(who); } } @@ -2171,7 +2100,7 @@ impl Pallet { if VirtualStakers::::contains_key(stash.clone()) { ensure!( asset::staked::(&stash) == Zero::zero(), - "virtual stakers should not have any staked balance" + "virtual stakers should not have any locked balance" ); ensure!( >::get(stash.clone()).unwrap() == stash.clone(), @@ -2199,7 +2128,7 @@ impl Pallet { } else { ensure!( Self::inspect_bond_state(&stash) == Ok(LedgerIntegrityState::Ok), - "bond, ledger and/or staking hold inconsistent for a bonded stash." + "bond, ledger and/or staking lock inconsistent for a bonded stash." ); } diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index 7d5da9ea0c49..b3f8c18f704c 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -25,12 +25,8 @@ use frame_election_provider_support::{ use frame_support::{ pallet_prelude::*, traits::{ - fungible::{ - hold::{Balanced as FunHoldBalanced, Mutate as FunHoldMutate}, - Mutate as FunMutate, - }, Defensive, DefensiveSaturating, EnsureOrigin, EstimateNextNewSession, Get, - InspectLockableCurrency, OnUnbalanced, UnixTime, + InspectLockableCurrency, LockableCurrency, OnUnbalanced, UnixTime, }, weights::Weight, BoundedVec, @@ -93,27 +89,13 @@ pub mod pallet { #[pallet::config(with_default)] pub trait Config: frame_system::Config { - /// The old trait for staking balance. Deprecated and only used for migrating old ledgers. - #[pallet::no_default] - type OldCurrency: InspectLockableCurrency< - Self::AccountId, - Moment = BlockNumberFor, - Balance = Self::CurrencyBalance, - >; - /// The staking balance. #[pallet::no_default] - type Currency: FunHoldMutate< + type Currency: LockableCurrency< Self::AccountId, - Reason = Self::RuntimeHoldReason, + Moment = BlockNumberFor, Balance = Self::CurrencyBalance, - > + FunMutate - + FunHoldBalanced; - - /// Overarching hold reason. - #[pallet::no_default_bounds] - type RuntimeHoldReason: From; - + > + InspectLockableCurrency; /// Just the `Currency::Balance` type; we have this item to allow us to constrain it to /// `From`. type CurrencyBalance: sp_runtime::traits::AtLeast32BitUnsigned @@ -124,8 +106,6 @@ pub mod pallet { + Default + From + TypeInfo - + Send - + Sync + MaxEncodedLen; /// Time used for computing era duration. /// @@ -329,14 +309,6 @@ pub mod pallet { type WeightInfo: WeightInfo; } - /// A reason for placing a hold on funds. - #[pallet::composite_enum] - pub enum HoldReason { - /// Funds on stake by a nominator or a validator. - #[codec(index = 0)] - Staking, - } - /// Default implementations of [`DefaultConfig`], which can be used to implement [`Config`]. pub mod config_preludes { use super::*; @@ -355,8 +327,6 @@ pub mod pallet { impl DefaultConfig for TestDefaultConfig { #[inject_runtime_type] type RuntimeEvent = (); - #[inject_runtime_type] - type RuntimeHoldReason = (); type CurrencyBalance = u128; type CurrencyToVote = (); type NominationsQuota = crate::FixedNominationsQuota<16>; @@ -795,7 +765,7 @@ pub mod pallet { status ); assert!( - asset::free_to_stake::(stash) >= balance, + asset::stakeable_balance::(stash) >= balance, "Stash does not have enough balance to bond." ); frame_support::assert_ok!(>::bond( @@ -888,9 +858,6 @@ pub mod pallet { ValidatorDisabled { stash: T::AccountId }, /// Validator has been re-enabled. ValidatorReenabled { stash: T::AccountId }, - /// Staking balance migrated from locks to holds, with any balance that could not be held - /// is force withdrawn. - CurrencyMigrated { stash: T::AccountId, force_withdraw: BalanceOf }, } #[pallet::error] @@ -962,10 +929,6 @@ pub mod pallet { NotEnoughFunds, /// Operation not allowed for virtual stakers. VirtualStakerNotAllowed, - /// Stash could not be reaped as other pallet might depend on it. - CannotReapStash, - /// The stake of this account is already migrated to `Fungible` holds. - AlreadyMigrated, } #[pallet::hooks] @@ -1209,7 +1172,10 @@ pub mod pallet { return Err(Error::::InsufficientBond.into()) } - let stash_balance = asset::free_to_stake::(&stash); + // Would fail if account has no provider. + frame_system::Pallet::::inc_consumers(&stash)?; + + let stash_balance = asset::stakeable_balance::(&stash); let value = value.min(stash_balance); Self::deposit_event(Event::::Bonded { stash: stash.clone(), amount: value }); let ledger = StakingLedger::::new(stash.clone(), value); @@ -2265,8 +2231,8 @@ pub mod pallet { let new_total = if let Some(total) = maybe_total { let new_total = total.min(stash_balance); - // enforce hold == ledger.amount. - asset::update_stake::(&stash, new_total)?; + // enforce lock == ledger.amount. + asset::update_stake::(&stash, new_total); new_total } else { current_lock @@ -2293,13 +2259,13 @@ pub mod pallet { // to enforce a new ledger.total and staking lock for this stash. let new_total = maybe_total.ok_or(Error::::CannotRestoreLedger)?.min(stash_balance); - asset::update_stake::(&stash, new_total)?; + asset::update_stake::(&stash, new_total); Ok((stash.clone(), new_total)) }, Err(Error::::BadState) => { // the stash and ledger do not exist but lock is lingering. - asset::kill_stake::(&stash)?; + asset::kill_stake::(&stash); ensure!( Self::inspect_bond_state(&stash) == Err(Error::::NotStash), Error::::BadState @@ -2325,26 +2291,6 @@ pub mod pallet { ); Ok(()) } - - /// Migrates permissionlessly a stash from locks to holds. - /// - /// This removes the old lock on the stake and creates a hold on it atomically. If all - /// stake cannot be held, the best effort is made to hold as much as possible. The remaining - /// stake is removed from the ledger. - /// - /// The fee is waived if the migration is successful. - #[pallet::call_index(30)] - #[pallet::weight(T::WeightInfo::migrate_currency())] - pub fn migrate_currency( - origin: OriginFor, - stash: T::AccountId, - ) -> DispatchResultWithPostInfo { - let _ = ensure_signed(origin)?; - Self::do_migrate_currency(&stash)?; - - // Refund the transaction fee if successful. - Ok(Pays::No.into()) - } } } diff --git a/substrate/frame/staking/src/testing_utils.rs b/substrate/frame/staking/src/testing_utils.rs index dfd5422106c0..81337710aa90 100644 --- a/substrate/frame/staking/src/testing_utils.rs +++ b/substrate/frame/staking/src/testing_utils.rs @@ -238,21 +238,3 @@ pub fn create_validators_with_nominators_for_era( pub fn current_era() -> EraIndex { CurrentEra::::get().unwrap_or(0) } - -pub fn migrate_to_old_currency(who: T::AccountId) { - use frame_support::traits::LockableCurrency; - let staked = asset::staked::(&who); - - // apply locks (this also adds a consumer). - T::OldCurrency::set_lock( - STAKING_ID, - &who, - staked, - frame_support::traits::WithdrawReasons::all(), - ); - // remove holds. - asset::kill_stake::(&who).expect("remove hold failed"); - - // replicate old behaviour of explicit increment of consumer. - frame_system::Pallet::::inc_consumers(&who).expect("increment consumer failed"); -} diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 908415143994..6c2335e1aac8 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -26,12 +26,8 @@ use frame_election_provider_support::{ use frame_support::{ assert_noop, assert_ok, assert_storage_noop, dispatch::{extract_actual_weight, GetDispatchInfo, WithPostDispatchInfo}, - hypothetically, pallet_prelude::*, - traits::{ - fungible::Inspect, Currency, Get, InspectLockableCurrency, LockableCurrency, - ReservableCurrency, WithdrawReasons, - }, + traits::{Currency, Get, ReservableCurrency}, }; use mock::*; @@ -112,7 +108,7 @@ fn force_unstake_works() { // Cant transfer assert_noop!( Balances::transfer_allow_death(RuntimeOrigin::signed(11), 1, 10), - TokenError::FundsUnavailable, + TokenError::Frozen, ); // Force unstake requires root. assert_noop!(Staking::force_unstake(RuntimeOrigin::signed(11), 11, 2), BadOrigin); @@ -233,7 +229,8 @@ fn basic_setup_works() { assert_eq!(active_era(), 0); // Account 10 has `balance_factor` free balance - assert_eq!(Balances::balance(&10), 1); + assert_eq!(asset::stakeable_balance::(&10), 1); + assert_eq!(asset::stakeable_balance::(&10), 1); // New era is not being forced assert_eq!(ForceEra::::get(), Forcing::NotForcing); @@ -363,16 +360,8 @@ fn rewards_should_work() { remainder: maximum_payout - total_payout_0 } ); - - // make note of total issuance before rewards. - let total_issuance_0 = asset::total_issuance::(); - mock::make_all_reward_payment(0); - // total issuance should have increased - let total_issuance_1 = asset::total_issuance::(); - assert_eq!(total_issuance_1, total_issuance_0 + total_payout_0); - assert_eq_error_rate!( asset::total_balance::(&11), init_balance_11 + part_for_11 * total_payout_0 * 2 / 3, @@ -412,7 +401,6 @@ fn rewards_should_work() { ); mock::make_all_reward_payment(1); - assert_eq!(asset::total_issuance::(), total_issuance_1 + total_payout_1); assert_eq_error_rate!( asset::total_balance::(&11), init_balance_11 + part_for_11 * (total_payout_0 * 2 / 3 + total_payout_1), @@ -502,7 +490,7 @@ fn staking_should_work() { } ); // e.g. it cannot reserve more than 500 that it has free from the total 2000 - assert_noop!(Balances::reserve(&3, 501), DispatchError::ConsumerRemaining); + assert_noop!(Balances::reserve(&3, 501), BalancesError::::LiquidityRestrictions); assert_ok!(Balances::reserve(&3, 409)); }); } @@ -701,7 +689,7 @@ fn nominating_and_rewards_should_work() { ); // Nominator 3: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 21]'s reward. ==> // 2/9 + 3/11 - assert_eq!(asset::stakeable_balance::(&3), initial_balance); + assert_eq!(asset::total_balance::(&3), initial_balance); // 333 is the reward destination for 3. assert_eq_error_rate!( asset::total_balance::(&333), @@ -1004,9 +992,9 @@ fn cannot_transfer_staked_balance() { ExtBuilder::default().nominate(false).build_and_execute(|| { // Confirm account 11 is stashed assert_eq!(Staking::bonded(&11), Some(11)); - // Confirm account 11 has some stakeable balance + // Confirm account 11 has some free balance assert_eq!(asset::stakeable_balance::(&11), 1000); - // Confirm account 11 is totally staked + // Confirm account 11 (via controller) is totally staked assert_eq!(Staking::eras_stakers(active_era(), &11).total, 1000); // Confirm account 11 cannot transfer as a result assert_noop!( @@ -1033,12 +1021,11 @@ fn cannot_transfer_staked_balance_2() { assert_eq!(asset::stakeable_balance::(&21), 2000); // Confirm account 21 (via controller) is totally staked assert_eq!(Staking::eras_stakers(active_era(), &21).total, 1000); - // Confirm account 21 cannot transfer more than 1000 + // Confirm account 21 can transfer at most 1000 assert_noop!( Balances::transfer_allow_death(RuntimeOrigin::signed(21), 21, 1001), TokenError::Frozen, ); - // Confirm account 21 needs to leave at least ED in free balance to be able to transfer assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(21), 21, 1000)); }); } @@ -1049,61 +1036,17 @@ fn cannot_reserve_staked_balance() { ExtBuilder::default().build_and_execute(|| { // Confirm account 11 is stashed assert_eq!(Staking::bonded(&11), Some(11)); - // Confirm account 11 is totally staked - assert_eq!(asset::staked::(&11), 1000); - + // Confirm account 11 has some free balance + assert_eq!(asset::stakeable_balance::(&11), 1000); + // Confirm account 11 (via controller 10) is totally staked + assert_eq!(Staking::eras_stakers(active_era(), &11).own, 1000); // Confirm account 11 cannot reserve as a result - assert_noop!(Balances::reserve(&11, 2), BalancesError::::InsufficientBalance); - assert_noop!(Balances::reserve(&11, 1), DispatchError::ConsumerRemaining); + assert_noop!(Balances::reserve(&11, 1), BalancesError::::LiquidityRestrictions); // Give account 11 extra free balance - let _ = asset::set_stakeable_balance::(&11, 1000 + 1000); - assert_eq!(asset::free_to_stake::(&11), 1000); - + let _ = asset::set_stakeable_balance::(&11, 10000); // Confirm account 11 can now reserve balance - assert_ok!(Balances::reserve(&11, 500)); - - // free to stake balance has reduced - assert_eq!(asset::free_to_stake::(&11), 500); - }); -} - -#[test] -fn locked_balance_can_be_staked() { - // Checks that a bonded account cannot reserve balance from free balance - ExtBuilder::default().build_and_execute(|| { - // Confirm account 11 is stashed - assert_eq!(Staking::bonded(&11), Some(11)); - assert_eq!(asset::staked::(&11), 1000); - assert_eq!(asset::free_to_stake::(&11), 0); - - // add some staking balance to 11 - let _ = asset::set_stakeable_balance::(&11, 1000 + 1000); - // free to stake is 1000 - assert_eq!(asset::free_to_stake::(&11), 1000); - - // lock some balance - Balances::set_lock(*b"somelock", &11, 500, WithdrawReasons::all()); - - // locked balance still available for staking - assert_eq!(asset::free_to_stake::(&11), 1000); - - // can stake free balance - assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(11), 500)); - assert_eq!(asset::staked::(&11), 1500); - - // Can stake the locked balance - assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(11), 500)); - assert_eq!(asset::staked::(&11), 2000); - // no balance left to stake - assert_eq!(asset::free_to_stake::(&11), 0); - - // this does not fail if someone tries to stake more than free balance but just stakes - // whatever is available. (not sure if that is the best way, but we keep it backward - // compatible) - assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(11), 10)); - // no extra balance staked. - assert_eq!(asset::staked::(&11), 2000); + assert_ok!(Balances::reserve(&11, 1)); }); } @@ -1114,9 +1057,9 @@ fn reward_destination_works() { // Check that account 11 is a validator assert!(Session::validators().contains(&11)); // Check the balance of the validator account - assert_eq!(asset::total_balance::(&10), 1); + assert_eq!(asset::stakeable_balance::(&10), 1); // Check the balance of the stash account - assert_eq!(asset::total_balance::(&11), 1001); + assert_eq!(asset::stakeable_balance::(&11), 1000); // Check how much is at stake assert_eq!( Staking::ledger(11.into()).unwrap(), @@ -1351,12 +1294,12 @@ fn bond_extra_and_withdraw_unbonded_works() { // Give account 11 some large free balance greater than total let _ = asset::set_stakeable_balance::(&11, 1000000); - // ensure it has the correct balance. - assert_eq!(asset::stakeable_balance::(&11), 1000000); - // Initial config should be correct assert_eq!(active_era(), 0); + // check the balance of a validator accounts. + assert_eq!(asset::total_balance::(&11), 1000000); + // confirm that 10 is a normal validator and gets paid at the end of the era. mock::start_active_era(1); @@ -2134,7 +2077,7 @@ fn bond_with_no_staked_value() { ); // bonded with absolute minimum value possible. assert_ok!(Staking::bond(RuntimeOrigin::signed(1), 5, RewardDestination::Account(1))); - assert_eq!(pallet_balances::Holds::::get(&1)[0].amount, 5); + assert_eq!(pallet_balances::Locks::::get(&1)[0].amount, 5); // unbonding even 1 will cause all to be unbonded. assert_ok!(Staking::unbond(RuntimeOrigin::signed(1), 1)); @@ -2155,14 +2098,14 @@ fn bond_with_no_staked_value() { // not yet removed. assert_ok!(Staking::withdraw_unbonded(RuntimeOrigin::signed(1), 0)); assert!(Staking::ledger(1.into()).is_ok()); - assert_eq!(pallet_balances::Holds::::get(&1)[0].amount, 5); + assert_eq!(pallet_balances::Locks::::get(&1)[0].amount, 5); mock::start_active_era(3); // poof. Account 1 is removed from the staking system. assert_ok!(Staking::withdraw_unbonded(RuntimeOrigin::signed(1), 0)); assert!(Staking::ledger(1.into()).is_err()); - assert_eq!(pallet_balances::Holds::::get(&1).len(), 0); + assert_eq!(pallet_balances::Locks::::get(&1).len(), 0); }); } @@ -2395,20 +2338,9 @@ fn reward_validator_slashing_validator_does_not_overflow() { EraInfo::::set_exposure(0, &11, exposure); ErasValidatorReward::::insert(0, stake); assert_ok!(Staking::payout_stakers_by_page(RuntimeOrigin::signed(1337), 11, 0, 0)); - assert_eq!(asset::stakeable_balance::(&11), stake * 2); + assert_eq!(asset::total_balance::(&11), stake * 2); - // ensure ledger has `stake` and no more. - Ledger::::insert( - 11, - StakingLedgerInspect { - stash: 11, - total: stake, - active: stake, - unlocking: Default::default(), - legacy_claimed_rewards: bounded_vec![1], - }, - ); - // Set staker (unsafe, can reduce balance below actual stake) + // Set staker let _ = asset::set_stakeable_balance::(&11, stake); let _ = asset::set_stakeable_balance::(&2, stake); @@ -2434,8 +2366,8 @@ fn reward_validator_slashing_validator_does_not_overflow() { &[Perbill::from_percent(100)], ); - assert_eq!(asset::stakeable_balance::(&11), stake - 1); - assert_eq!(asset::stakeable_balance::(&2), 1); + assert_eq!(asset::total_balance::(&11), stake - 1); + assert_eq!(asset::total_balance::(&2), 1); }) } @@ -2695,8 +2627,8 @@ fn reporters_receive_their_slice() { // 50% * (10% * initial_balance / 2) let reward = (initial_balance / 20) / 2; let reward_each = reward / 2; // split into two pieces. - assert_eq!(asset::total_balance::(&1), 10 + reward_each); - assert_eq!(asset::total_balance::(&2), 20 + reward_each); + assert_eq!(asset::stakeable_balance::(&1), 10 + reward_each); + assert_eq!(asset::stakeable_balance::(&2), 20 + reward_each); }); } @@ -2721,7 +2653,7 @@ fn subsequent_reports_in_same_span_pay_out_less() { // F1 * (reward_proportion * slash - 0) // 50% * (10% * initial_balance * 20%) let reward = (initial_balance / 5) / 20; - assert_eq!(asset::total_balance::(&1), 10 + reward); + assert_eq!(asset::stakeable_balance::(&1), 10 + reward); on_offence_now( &[OffenceDetails { @@ -2736,7 +2668,7 @@ fn subsequent_reports_in_same_span_pay_out_less() { // F1 * (reward_proportion * slash - prior_payout) // 50% * (10% * (initial_balance / 2) - prior_payout) let reward = ((initial_balance / 20) - prior_payout) / 2; - assert_eq!(asset::total_balance::(&1), 10 + prior_payout + reward); + assert_eq!(asset::stakeable_balance::(&1), 10 + prior_payout + reward); }); } @@ -2880,9 +2812,8 @@ fn garbage_collection_after_slashing() { // validator and nominator slash in era are garbage-collected by era change, // so we don't test those here. - assert_eq!(asset::stakeable_balance::(&11), 0); - // Non staked balance is not touched. - assert_eq!(asset::total_balance::(&11), ExistentialDeposit::get()); + assert_eq!(asset::stakeable_balance::(&11), 2); + assert_eq!(asset::total_balance::(&11), 2); let slashing_spans = SlashingSpans::::get(&11).unwrap(); assert_eq!(slashing_spans.iter().count(), 2); @@ -6161,7 +6092,7 @@ fn nomination_quota_max_changes_decoding() { .add_staker(70, 71, 10, StakerStatus::Nominator(vec![1, 2, 3])) .add_staker(30, 330, 10, StakerStatus::Nominator(vec![1, 2, 3, 4])) .add_staker(50, 550, 10, StakerStatus::Nominator(vec![1, 2, 3, 4])) - .balance_factor(11) + .balance_factor(10) .build_and_execute(|| { // pre-condition. assert_eq!(MaxNominationsOf::::get(), 16); @@ -6277,248 +6208,240 @@ fn force_apply_min_commission_works() { #[test] fn proportional_slash_stop_slashing_if_remaining_zero() { - ExtBuilder::default().nominate(true).build_and_execute(|| { - let c = |era, value| UnlockChunk:: { era, value }; + let c = |era, value| UnlockChunk:: { era, value }; - // we have some chunks, but they are not affected. - let unlocking = bounded_vec![c(1, 10), c(2, 10)]; + // we have some chunks, but they are not affected. + let unlocking = bounded_vec![c(1, 10), c(2, 10)]; - // Given - let mut ledger = StakingLedger::::new(123, 20); - ledger.total = 40; - ledger.unlocking = unlocking; + // Given + let mut ledger = StakingLedger::::new(123, 20); + ledger.total = 40; + ledger.unlocking = unlocking; - assert_eq!(BondingDuration::get(), 3); + assert_eq!(BondingDuration::get(), 3); - // should not slash more than the amount requested, by accidentally slashing the first - // chunk. - assert_eq!(ledger.slash(18, 1, 0), 18); - }); + // should not slash more than the amount requested, by accidentally slashing the first chunk. + assert_eq!(ledger.slash(18, 1, 0), 18); } #[test] fn proportional_ledger_slash_works() { - ExtBuilder::default().nominate(true).build_and_execute(|| { - let c = |era, value| UnlockChunk:: { era, value }; - // Given - let mut ledger = StakingLedger::::new(123, 10); - assert_eq!(BondingDuration::get(), 3); - - // When we slash a ledger with no unlocking chunks - assert_eq!(ledger.slash(5, 1, 0), 5); - // Then - assert_eq!(ledger.total, 5); - assert_eq!(ledger.active, 5); - assert_eq!(LedgerSlashPerEra::get().0, 5); - assert_eq!(LedgerSlashPerEra::get().1, Default::default()); - - // When we slash a ledger with no unlocking chunks and the slash amount is greater then the - // total - assert_eq!(ledger.slash(11, 1, 0), 5); - // Then - assert_eq!(ledger.total, 0); - assert_eq!(ledger.active, 0); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, Default::default()); - - // Given - ledger.unlocking = bounded_vec![c(4, 10), c(5, 10)]; - ledger.total = 2 * 10; - ledger.active = 0; - // When all the chunks overlap with the slash eras - assert_eq!(ledger.slash(20, 0, 0), 20); - // Then - assert_eq!(ledger.unlocking, vec![]); - assert_eq!(ledger.total, 0); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(4, 0), (5, 0)])); - - // Given - ledger.unlocking = bounded_vec![c(4, 100), c(5, 100), c(6, 100), c(7, 100)]; - ledger.total = 4 * 100; - ledger.active = 0; - // When the first 2 chunks don't overlap with the affected range of unlock eras. - assert_eq!(ledger.slash(140, 0, 3), 140); - // Then - assert_eq!(ledger.unlocking, vec![c(4, 100), c(5, 100), c(6, 30), c(7, 30)]); - assert_eq!(ledger.total, 4 * 100 - 140); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(6, 30), (7, 30)])); - - // Given - ledger.unlocking = bounded_vec![c(4, 100), c(5, 100), c(6, 100), c(7, 100)]; - ledger.total = 4 * 100; - ledger.active = 0; - // When the first 2 chunks don't overlap with the affected range of unlock eras. - assert_eq!(ledger.slash(15, 0, 3), 15); - // Then - assert_eq!(ledger.unlocking, vec![c(4, 100), c(5, 100), c(6, 100 - 8), c(7, 100 - 7)]); - assert_eq!(ledger.total, 4 * 100 - 15); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(6, 92), (7, 93)])); - - // Given - ledger.unlocking = bounded_vec![c(4, 40), c(5, 100), c(6, 10), c(7, 250)]; - ledger.active = 500; - // 900 - ledger.total = 40 + 10 + 100 + 250 + 500; - // When we have a partial slash that touches all chunks - assert_eq!(ledger.slash(900 / 2, 0, 0), 450); - // Then - assert_eq!(ledger.active, 500 / 2); - assert_eq!( - ledger.unlocking, - vec![c(4, 40 / 2), c(5, 100 / 2), c(6, 10 / 2), c(7, 250 / 2)] - ); - assert_eq!(ledger.total, 900 / 2); - assert_eq!(LedgerSlashPerEra::get().0, 500 / 2); - assert_eq!( - LedgerSlashPerEra::get().1, - BTreeMap::from([(4, 40 / 2), (5, 100 / 2), (6, 10 / 2), (7, 250 / 2)]) - ); - - // slash 1/4th with not chunk. - ledger.unlocking = bounded_vec![]; - ledger.active = 500; - ledger.total = 500; - // When we have a partial slash that touches all chunks - assert_eq!(ledger.slash(500 / 4, 0, 0), 500 / 4); - // Then - assert_eq!(ledger.active, 3 * 500 / 4); - assert_eq!(ledger.unlocking, vec![]); - assert_eq!(ledger.total, ledger.active); - assert_eq!(LedgerSlashPerEra::get().0, 3 * 500 / 4); - assert_eq!(LedgerSlashPerEra::get().1, Default::default()); - - // Given we have the same as above, - ledger.unlocking = bounded_vec![c(4, 40), c(5, 100), c(6, 10), c(7, 250)]; - ledger.active = 500; - ledger.total = 40 + 10 + 100 + 250 + 500; // 900 - assert_eq!(ledger.total, 900); - // When we have a higher min balance - assert_eq!( - ledger.slash( - 900 / 2, - 25, /* min balance - chunks with era 0 & 2 will be slashed to <=25, causing it - * to get swept */ - 0 - ), - 450 - ); - assert_eq!(ledger.active, 500 / 2); - // the last chunk was not slashed 50% like all the rest, because some other earlier chunks - // got dusted. - assert_eq!(ledger.unlocking, vec![c(5, 100 / 2), c(7, 150)]); - assert_eq!(ledger.total, 900 / 2); - assert_eq!(LedgerSlashPerEra::get().0, 500 / 2); - assert_eq!( - LedgerSlashPerEra::get().1, - BTreeMap::from([(4, 0), (5, 100 / 2), (6, 0), (7, 150)]) - ); - - // Given - // slash order --------------------NA--------2----------0----------1---- - ledger.unlocking = bounded_vec![c(4, 40), c(5, 100), c(6, 10), c(7, 250)]; - ledger.active = 500; - ledger.total = 40 + 10 + 100 + 250 + 500; // 900 - assert_eq!( - ledger.slash( - 500 + 10 + 250 + 100 / 2, // active + era 6 + era 7 + era 5 / 2 - 0, - 3 /* slash era 6 first, so the affected parts are era 6, era 7 and - * ledge.active. This will cause the affected to go to zero, and then we will - * start slashing older chunks */ - ), - 500 + 250 + 10 + 100 / 2 - ); - // Then - assert_eq!(ledger.active, 0); - assert_eq!(ledger.unlocking, vec![c(4, 40), c(5, 100 / 2)]); - assert_eq!(ledger.total, 90); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(5, 100 / 2), (6, 0), (7, 0)])); - - // Given - // iteration order------------------NA---------2----------0----------1---- - ledger.unlocking = bounded_vec![c(4, 100), c(5, 100), c(6, 100), c(7, 100)]; - ledger.active = 100; - ledger.total = 5 * 100; - // When - assert_eq!( - ledger.slash( - 351, // active + era 6 + era 7 + era 5 / 2 + 1 - 50, // min balance - everything slashed below 50 will get dusted - 3 /* slash era 3+3 first, so the affected parts are era 6, era 7 and - * ledge.active. This will cause the affected to go to zero, and then we - * will start slashing older chunks */ - ), - 400 - ); - // Then - assert_eq!(ledger.active, 0); - assert_eq!(ledger.unlocking, vec![c(4, 100)]); - assert_eq!(ledger.total, 100); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(5, 0), (6, 0), (7, 0)])); - - // Tests for saturating arithmetic + let c = |era, value| UnlockChunk:: { era, value }; + // Given + let mut ledger = StakingLedger::::new(123, 10); + assert_eq!(BondingDuration::get(), 3); + + // When we slash a ledger with no unlocking chunks + assert_eq!(ledger.slash(5, 1, 0), 5); + // Then + assert_eq!(ledger.total, 5); + assert_eq!(ledger.active, 5); + assert_eq!(LedgerSlashPerEra::get().0, 5); + assert_eq!(LedgerSlashPerEra::get().1, Default::default()); + + // When we slash a ledger with no unlocking chunks and the slash amount is greater then the + // total + assert_eq!(ledger.slash(11, 1, 0), 5); + // Then + assert_eq!(ledger.total, 0); + assert_eq!(ledger.active, 0); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, Default::default()); + + // Given + ledger.unlocking = bounded_vec![c(4, 10), c(5, 10)]; + ledger.total = 2 * 10; + ledger.active = 0; + // When all the chunks overlap with the slash eras + assert_eq!(ledger.slash(20, 0, 0), 20); + // Then + assert_eq!(ledger.unlocking, vec![]); + assert_eq!(ledger.total, 0); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(4, 0), (5, 0)])); + + // Given + ledger.unlocking = bounded_vec![c(4, 100), c(5, 100), c(6, 100), c(7, 100)]; + ledger.total = 4 * 100; + ledger.active = 0; + // When the first 2 chunks don't overlap with the affected range of unlock eras. + assert_eq!(ledger.slash(140, 0, 3), 140); + // Then + assert_eq!(ledger.unlocking, vec![c(4, 100), c(5, 100), c(6, 30), c(7, 30)]); + assert_eq!(ledger.total, 4 * 100 - 140); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(6, 30), (7, 30)])); + + // Given + ledger.unlocking = bounded_vec![c(4, 100), c(5, 100), c(6, 100), c(7, 100)]; + ledger.total = 4 * 100; + ledger.active = 0; + // When the first 2 chunks don't overlap with the affected range of unlock eras. + assert_eq!(ledger.slash(15, 0, 3), 15); + // Then + assert_eq!(ledger.unlocking, vec![c(4, 100), c(5, 100), c(6, 100 - 8), c(7, 100 - 7)]); + assert_eq!(ledger.total, 4 * 100 - 15); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(6, 92), (7, 93)])); + + // Given + ledger.unlocking = bounded_vec![c(4, 40), c(5, 100), c(6, 10), c(7, 250)]; + ledger.active = 500; + // 900 + ledger.total = 40 + 10 + 100 + 250 + 500; + // When we have a partial slash that touches all chunks + assert_eq!(ledger.slash(900 / 2, 0, 0), 450); + // Then + assert_eq!(ledger.active, 500 / 2); + assert_eq!(ledger.unlocking, vec![c(4, 40 / 2), c(5, 100 / 2), c(6, 10 / 2), c(7, 250 / 2)]); + assert_eq!(ledger.total, 900 / 2); + assert_eq!(LedgerSlashPerEra::get().0, 500 / 2); + assert_eq!( + LedgerSlashPerEra::get().1, + BTreeMap::from([(4, 40 / 2), (5, 100 / 2), (6, 10 / 2), (7, 250 / 2)]) + ); - // Given - let slash = u64::MAX as Balance * 2; - // The value of the other parts of ledger that will get slashed - let value = slash - (10 * 4); - - ledger.active = 10; - ledger.unlocking = bounded_vec![c(4, 10), c(5, 10), c(6, 10), c(7, value)]; - ledger.total = value + 40; - // When - let slash_amount = ledger.slash(slash, 0, 0); - assert_eq_error_rate!(slash_amount, slash, 5); - // Then - assert_eq!(ledger.active, 0); // slash of 9 - assert_eq!(ledger.unlocking, vec![]); - assert_eq!(ledger.total, 0); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(4, 0), (5, 0), (6, 0), (7, 0)])); + // slash 1/4th with not chunk. + ledger.unlocking = bounded_vec![]; + ledger.active = 500; + ledger.total = 500; + // When we have a partial slash that touches all chunks + assert_eq!(ledger.slash(500 / 4, 0, 0), 500 / 4); + // Then + assert_eq!(ledger.active, 3 * 500 / 4); + assert_eq!(ledger.unlocking, vec![]); + assert_eq!(ledger.total, ledger.active); + assert_eq!(LedgerSlashPerEra::get().0, 3 * 500 / 4); + assert_eq!(LedgerSlashPerEra::get().1, Default::default()); + + // Given we have the same as above, + ledger.unlocking = bounded_vec![c(4, 40), c(5, 100), c(6, 10), c(7, 250)]; + ledger.active = 500; + ledger.total = 40 + 10 + 100 + 250 + 500; // 900 + assert_eq!(ledger.total, 900); + // When we have a higher min balance + assert_eq!( + ledger.slash( + 900 / 2, + 25, /* min balance - chunks with era 0 & 2 will be slashed to <=25, causing it to + * get swept */ + 0 + ), + 450 + ); + assert_eq!(ledger.active, 500 / 2); + // the last chunk was not slashed 50% like all the rest, because some other earlier chunks got + // dusted. + assert_eq!(ledger.unlocking, vec![c(5, 100 / 2), c(7, 150)]); + assert_eq!(ledger.total, 900 / 2); + assert_eq!(LedgerSlashPerEra::get().0, 500 / 2); + assert_eq!( + LedgerSlashPerEra::get().1, + BTreeMap::from([(4, 0), (5, 100 / 2), (6, 0), (7, 150)]) + ); - // Given - use sp_runtime::PerThing as _; - let slash = u64::MAX as Balance * 2; - let value = u64::MAX as Balance * 2; - let unit = 100; - // slash * value that will saturate - assert!(slash.checked_mul(value).is_none()); - // but slash * unit won't. - assert!(slash.checked_mul(unit).is_some()); - ledger.unlocking = bounded_vec![c(4, unit), c(5, value), c(6, unit), c(7, unit)]; - //--------------------------------------note value^^^ - ledger.active = unit; - ledger.total = unit * 4 + value; - // When - assert_eq!(ledger.slash(slash, 0, 0), slash); - // Then - // The amount slashed out of `unit` - let affected_balance = value + unit * 4; - let ratio = Perquintill::from_rational_with_rounding(slash, affected_balance, Rounding::Up) - .unwrap(); - // `unit` after the slash is applied - let unit_slashed = { - let unit_slash = ratio.mul_ceil(unit); - unit - unit_slash - }; - let value_slashed = { - let value_slash = ratio.mul_ceil(value); - value - value_slash - }; - assert_eq!(ledger.active, unit_slashed); - assert_eq!(ledger.unlocking, vec![c(5, value_slashed), c(7, 32)]); - assert_eq!(ledger.total, value_slashed + 32); - assert_eq!(LedgerSlashPerEra::get().0, 0); - assert_eq!( - LedgerSlashPerEra::get().1, - BTreeMap::from([(4, 0), (5, value_slashed), (6, 0), (7, 32)]) - ); - }); + // Given + // slash order --------------------NA--------2----------0----------1---- + ledger.unlocking = bounded_vec![c(4, 40), c(5, 100), c(6, 10), c(7, 250)]; + ledger.active = 500; + ledger.total = 40 + 10 + 100 + 250 + 500; // 900 + assert_eq!( + ledger.slash( + 500 + 10 + 250 + 100 / 2, // active + era 6 + era 7 + era 5 / 2 + 0, + 3 /* slash era 6 first, so the affected parts are era 6, era 7 and + * ledge.active. This will cause the affected to go to zero, and then we will + * start slashing older chunks */ + ), + 500 + 250 + 10 + 100 / 2 + ); + // Then + assert_eq!(ledger.active, 0); + assert_eq!(ledger.unlocking, vec![c(4, 40), c(5, 100 / 2)]); + assert_eq!(ledger.total, 90); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(5, 100 / 2), (6, 0), (7, 0)])); + + // Given + // iteration order------------------NA---------2----------0----------1---- + ledger.unlocking = bounded_vec![c(4, 100), c(5, 100), c(6, 100), c(7, 100)]; + ledger.active = 100; + ledger.total = 5 * 100; + // When + assert_eq!( + ledger.slash( + 351, // active + era 6 + era 7 + era 5 / 2 + 1 + 50, // min balance - everything slashed below 50 will get dusted + 3 /* slash era 3+3 first, so the affected parts are era 6, era 7 and + * ledge.active. This will cause the affected to go to zero, and then we will + * start slashing older chunks */ + ), + 400 + ); + // Then + assert_eq!(ledger.active, 0); + assert_eq!(ledger.unlocking, vec![c(4, 100)]); + assert_eq!(ledger.total, 100); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(5, 0), (6, 0), (7, 0)])); + + // Tests for saturating arithmetic + + // Given + let slash = u64::MAX as Balance * 2; + // The value of the other parts of ledger that will get slashed + let value = slash - (10 * 4); + + ledger.active = 10; + ledger.unlocking = bounded_vec![c(4, 10), c(5, 10), c(6, 10), c(7, value)]; + ledger.total = value + 40; + // When + let slash_amount = ledger.slash(slash, 0, 0); + assert_eq_error_rate!(slash_amount, slash, 5); + // Then + assert_eq!(ledger.active, 0); // slash of 9 + assert_eq!(ledger.unlocking, vec![]); + assert_eq!(ledger.total, 0); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!(LedgerSlashPerEra::get().1, BTreeMap::from([(4, 0), (5, 0), (6, 0), (7, 0)])); + + // Given + use sp_runtime::PerThing as _; + let slash = u64::MAX as Balance * 2; + let value = u64::MAX as Balance * 2; + let unit = 100; + // slash * value that will saturate + assert!(slash.checked_mul(value).is_none()); + // but slash * unit won't. + assert!(slash.checked_mul(unit).is_some()); + ledger.unlocking = bounded_vec![c(4, unit), c(5, value), c(6, unit), c(7, unit)]; + //--------------------------------------note value^^^ + ledger.active = unit; + ledger.total = unit * 4 + value; + // When + assert_eq!(ledger.slash(slash, 0, 0), slash); + // Then + // The amount slashed out of `unit` + let affected_balance = value + unit * 4; + let ratio = + Perquintill::from_rational_with_rounding(slash, affected_balance, Rounding::Up).unwrap(); + // `unit` after the slash is applied + let unit_slashed = { + let unit_slash = ratio.mul_ceil(unit); + unit - unit_slash + }; + let value_slashed = { + let value_slash = ratio.mul_ceil(value); + value - value_slash + }; + assert_eq!(ledger.active, unit_slashed); + assert_eq!(ledger.unlocking, vec![c(5, value_slashed), c(7, 32)]); + assert_eq!(ledger.total, value_slashed + 32); + assert_eq!(LedgerSlashPerEra::get().0, 0); + assert_eq!( + LedgerSlashPerEra::get().1, + BTreeMap::from([(4, 0), (5, value_slashed), (6, 0), (7, 32)]) + ); } #[test] @@ -7203,7 +7126,7 @@ mod staking_unchecked { fn virtual_bond_does_not_lock() { ExtBuilder::default().build_and_execute(|| { mock::start_active_era(1); - assert_eq!(asset::total_balance::(&10), 1); + assert_eq!(asset::stakeable_balance::(&10), 1); // 10 can bond more than its balance amount since we do not require lock for virtual // bonding. assert_ok!(::virtual_bond(&10, 100, &15)); @@ -7342,7 +7265,7 @@ mod staking_unchecked { assert_eq!(asset::staked::(&200), 1000); // migrate them to virtual staker - assert_ok!(::migrate_to_virtual_staker(&200)); + ::migrate_to_virtual_staker(&200); // payee needs to be updated to a non-stash account. assert_ok!(::set_payee(&200, &201)); @@ -7369,7 +7292,7 @@ mod staking_unchecked { // 101 is a nominator for 11 assert_eq!(initial_exposure.others.first().unwrap().who, 101); // make 101 a virtual nominator - assert_ok!(::migrate_to_virtual_staker(&101)); + ::migrate_to_virtual_staker(&101); // set payee different to self. assert_ok!(::set_payee(&101, &102)); @@ -7444,7 +7367,7 @@ mod staking_unchecked { // 101 is a nominator for 11 assert_eq!(initial_exposure.others.first().unwrap().who, 101); // make 101 a virtual nominator - assert_ok!(::migrate_to_virtual_staker(&101)); + ::migrate_to_virtual_staker(&101); // set payee different to self. assert_ok!(::set_payee(&101, &102)); @@ -7500,7 +7423,7 @@ mod staking_unchecked { // 333 is corrupted assert_eq!(Staking::inspect_bond_state(&333).unwrap(), LedgerIntegrityState::Corrupted); // migrate to virtual staker. - assert_ok!(::migrate_to_virtual_staker(&333)); + ::migrate_to_virtual_staker(&333); // recover the ledger won't work for virtual staker assert_noop!( @@ -8111,7 +8034,8 @@ mod ledger_recovery { // side effects on 333 - ledger, bonded, payee, lock should be intact. assert_eq!(asset::staked::(&333), lock_333_before); // OK assert_eq!(Bonded::::get(&333), Some(444)); // OK - assert!(Payee::::get(&333).is_some()); + assert!(Payee::::get(&333).is_some()); // OK + // however, ledger associated with its controller was killed. assert!(Ledger::::get(&444).is_none()); // NOK @@ -9157,249 +9081,3 @@ mod getters { }); } } - -mod hold_migration { - use super::*; - use sp_staking::{Stake, StakingInterface}; - - #[test] - fn ledger_update_creates_hold() { - ExtBuilder::default().has_stakers(true).build_and_execute(|| { - // GIVEN alice who is a nominator with old currency - let alice = 300; - bond_nominator(alice, 1000, vec![11]); - assert_eq!(asset::staked::(&alice), 1000); - assert_eq!(Balances::balance_locked(STAKING_ID, &alice), 0); - // migrate alice currency to legacy locks - testing_utils::migrate_to_old_currency::(alice); - // no more holds - assert_eq!(asset::staked::(&alice), 0); - assert_eq!(Balances::balance_locked(STAKING_ID, &alice), 1000); - assert_eq!( - ::stake(&alice), - Ok(Stake { total: 1000, active: 1000 }) - ); - - // any ledger mutation should create a hold - hypothetically!({ - // give some extra balance to alice. - let _ = asset::mint_into_existing::(&alice, 100); - - // WHEN new fund is bonded to ledger. - assert_ok!(Staking::bond_extra(RuntimeOrigin::signed(alice), 100)); - - // THEN new hold is created - assert_eq!(asset::staked::(&alice), 1000 + 100); - assert_eq!( - ::stake(&alice), - Ok(Stake { total: 1100, active: 1100 }) - ); - - // old locked balance is untouched - assert_eq!(Balances::balance_locked(STAKING_ID, &alice), 1000); - }); - - hypothetically!({ - // WHEN new fund is unbonded from ledger. - assert_ok!(Staking::unbond(RuntimeOrigin::signed(alice), 100)); - - // THEN hold is updated. - assert_eq!(asset::staked::(&alice), 1000); - assert_eq!( - ::stake(&alice), - Ok(Stake { total: 1000, active: 900 }) - ); - - // old locked balance is untouched - assert_eq!(Balances::balance_locked(STAKING_ID, &alice), 1000); - }); - - // WHEN alice currency is migrated. - assert_ok!(Staking::migrate_currency(RuntimeOrigin::signed(1), alice)); - - // THEN hold is updated. - assert_eq!(asset::staked::(&alice), 1000); - assert_eq!( - ::stake(&alice), - Ok(Stake { total: 1000, active: 1000 }) - ); - - // ensure cannot migrate again. - assert_noop!( - Staking::migrate_currency(RuntimeOrigin::signed(1), alice), - Error::::AlreadyMigrated - ); - - // locked balance is removed - assert_eq!(Balances::balance_locked(STAKING_ID, &alice), 0); - }); - } - - #[test] - fn migrate_removes_old_lock() { - ExtBuilder::default().has_stakers(true).build_and_execute(|| { - // GIVEN alice who is a nominator with old currency - let alice = 300; - bond_nominator(alice, 1000, vec![11]); - testing_utils::migrate_to_old_currency::(alice); - assert_eq!(asset::staked::(&alice), 0); - assert_eq!(Balances::balance_locked(STAKING_ID, &alice), 1000); - let pre_migrate_consumer = System::consumers(&alice); - System::reset_events(); - - // WHEN alice currency is migrated. - assert_ok!(Staking::migrate_currency(RuntimeOrigin::signed(1), alice)); - - // THEN - // the extra consumer from old code is removed. - assert_eq!(System::consumers(&alice), pre_migrate_consumer - 1); - // ensure no lock - assert_eq!(Balances::balance_locked(STAKING_ID, &alice), 0); - // ensure stake and hold are same. - assert_eq!( - ::stake(&alice), - Ok(Stake { total: 1000, active: 1000 }) - ); - assert_eq!(asset::staked::(&alice), 1000); - // ensure events are emitted. - assert_eq!( - staking_events_since_last_call(), - vec![Event::CurrencyMigrated { stash: alice, force_withdraw: 0 }] - ); - - // ensure cannot migrate again. - assert_noop!( - Staking::migrate_currency(RuntimeOrigin::signed(1), alice), - Error::::AlreadyMigrated - ); - }); - } - #[test] - fn cannot_hold_all_stake() { - // When there is not enough funds to hold all stake, part of the stake if force withdrawn. - // At end of the migration, the stake and hold should be same. - ExtBuilder::default().has_stakers(true).build_and_execute(|| { - // GIVEN alice who is a nominator with old currency. - let alice = 300; - let stake = 1000; - bond_nominator(alice, stake, vec![11]); - testing_utils::migrate_to_old_currency::(alice); - assert_eq!(asset::staked::(&alice), 0); - assert_eq!(Balances::balance_locked(STAKING_ID, &alice), stake); - // ledger has 1000 staked. - assert_eq!( - ::stake(&alice), - Ok(Stake { total: stake, active: stake }) - ); - - // Get rid of the extra ED to emulate all their balance including ED is staked. - assert_ok!(Balances::transfer_allow_death( - RuntimeOrigin::signed(alice), - 10, - ExistentialDeposit::get() - )); - - let expected_force_withdraw = ExistentialDeposit::get(); - - // ledger mutation would fail in this case before migration because of failing hold. - assert_noop!( - Staking::unbond(RuntimeOrigin::signed(alice), 100), - Error::::NotEnoughFunds - ); - - // clear events - System::reset_events(); - - // WHEN alice currency is migrated. - assert_ok!(Staking::migrate_currency(RuntimeOrigin::signed(1), alice)); - - // THEN - let expected_hold = stake - expected_force_withdraw; - // ensure no lock - assert_eq!(Balances::balance_locked(STAKING_ID, &alice), 0); - // ensure stake and hold are same. - assert_eq!( - ::stake(&alice), - Ok(Stake { total: expected_hold, active: expected_hold }) - ); - assert_eq!(asset::staked::(&alice), expected_hold); - // ensure events are emitted. - assert_eq!( - staking_events_since_last_call(), - vec![Event::CurrencyMigrated { - stash: alice, - force_withdraw: expected_force_withdraw - }] - ); - - // ensure cannot migrate again. - assert_noop!( - Staking::migrate_currency(RuntimeOrigin::signed(1), alice), - Error::::AlreadyMigrated - ); - - // unbond works after migration. - assert_ok!(Staking::unbond(RuntimeOrigin::signed(alice), 100)); - }); - } - - #[test] - fn virtual_staker_consumer_provider_dec() { - // Ensure virtual stakers consumer and provider count is decremented. - ExtBuilder::default().has_stakers(true).build_and_execute(|| { - // 200 virtual bonds - bond_virtual_nominator(200, 201, 500, vec![11, 21]); - - // previously the virtual nominator had a provider inc by the delegation system as - // well as a consumer by this pallet. - System::inc_providers(&200); - System::inc_consumers(&200).expect("has provider, can consume"); - - hypothetically!({ - // migrate 200 - assert_ok!(Staking::migrate_currency(RuntimeOrigin::signed(1), 200)); - - // ensure account does not exist in system anymore. - assert_eq!(System::consumers(&200), 0); - assert_eq!(System::providers(&200), 0); - assert!(!System::account_exists(&200)); - - // ensure cannot migrate again. - assert_noop!( - Staking::migrate_currency(RuntimeOrigin::signed(1), 200), - Error::::AlreadyMigrated - ); - }); - - hypothetically!({ - // 200 has an erroneously extra provider - System::inc_providers(&200); - - // causes migration to fail. - assert_noop!( - Staking::migrate_currency(RuntimeOrigin::signed(1), 200), - Error::::BadState - ); - }); - - // 200 is funded for more than ED by a random account. - assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(999), 200, 10)); - - // it has an extra provider now. - assert_eq!(System::providers(&200), 2); - - // migrate 200 - assert_ok!(Staking::migrate_currency(RuntimeOrigin::signed(1), 200)); - - // 1 provider is left, consumers is 0. - assert_eq!(System::providers(&200), 1); - assert_eq!(System::consumers(&200), 0); - - // ensure cannot migrate again. - assert_noop!( - Staking::migrate_currency(RuntimeOrigin::signed(1), 200), - Error::::AlreadyMigrated - ); - }); - } -} diff --git a/substrate/frame/staking/src/weights.rs b/substrate/frame/staking/src/weights.rs index 02ccdacb01c4..56f561679cfc 100644 --- a/substrate/frame/staking/src/weights.rs +++ b/substrate/frame/staking/src/weights.rs @@ -18,25 +18,27 @@ //! Autogenerated weights for `pallet_staking` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-09-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-04-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-obbyq9g6-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-anb7yjbi-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/production/substrate-node +// ./target/production/substrate-node // benchmark // pallet +// --chain=dev // --steps=50 // --repeat=20 +// --pallet=pallet_staking +// --no-storage-info +// --no-median-slopes +// --no-min-squares // --extrinsic=* // --wasm-execution=compiled // --heap-pages=4096 -// --json-file=/builds/parity/mirrors/polkadot-sdk/.git/.artifacts/bench.json -// --pallet=pallet_staking -// --chain=dev -// --header=./substrate/HEADER-APACHE2 // --output=./substrate/frame/staking/src/weights.rs +// --header=./substrate/HEADER-APACHE2 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -81,7 +83,6 @@ pub trait WeightInfo { fn force_apply_min_commission() -> Weight; fn set_min_commission() -> Weight; fn restore_ledger() -> Weight; - fn migrate_currency() -> Weight; } /// Weights for `pallet_staking` using the Substrate node and recommended hardware. @@ -91,18 +92,18 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn bond() -> Weight { // Proof Size summary in bytes: - // Measured: `1068` - // Estimated: `4556` - // Minimum execution time: 71_854_000 picoseconds. - Weight::from_parts(73_408_000, 4556) + // Measured: `1042` + // Estimated: `4764` + // Minimum execution time: 46_504_000 picoseconds. + Weight::from_parts(48_459_000, 4764) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -110,20 +111,20 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn bond_extra() -> Weight { // Proof Size summary in bytes: - // Measured: `2049` + // Measured: `1990` // Estimated: `8877` - // Minimum execution time: 127_442_000 picoseconds. - Weight::from_parts(130_845_000, 8877) + // Minimum execution time: 90_475_000 picoseconds. + Weight::from_parts(93_619_000, 8877) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -137,22 +138,22 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn unbond() -> Weight { // Proof Size summary in bytes: - // Measured: `2151` + // Measured: `2195` // Estimated: `8877` - // Minimum execution time: 105_259_000 picoseconds. - Weight::from_parts(107_112_000, 8877) + // Minimum execution time: 99_335_000 picoseconds. + Weight::from_parts(101_440_000, 8877) .saturating_add(T::DbWeight::get().reads(12_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + .saturating_add(T::DbWeight::get().writes(7_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -160,21 +161,21 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1393` - // Estimated: `4556` - // Minimum execution time: 77_158_000 picoseconds. - Weight::from_parts(79_140_122, 4556) - // Standard Error: 1_688 - .saturating_add(Weight::from_parts(62_663, 0).saturating_mul(s.into())) + // Measured: `1297` + // Estimated: `4764` + // Minimum execution time: 50_067_000 picoseconds. + Weight::from_parts(52_396_327, 4764) + // Standard Error: 1_419 + .saturating_add(Weight::from_parts(51_406, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -186,10 +187,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::SlashingSpans` (r:1 w:1) /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Staking::VirtualStakers` (r:1 w:1) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) @@ -209,14 +210,14 @@ impl WeightInfo for SubstrateWeight { /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_kill(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2255 + s * (4 ±0)` + // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 125_396_000 picoseconds. - Weight::from_parts(134_915_543, 6248) - // Standard Error: 3_660 - .saturating_add(Weight::from_parts(1_324_736, 0).saturating_mul(s.into())) + // Minimum execution time: 92_931_000 picoseconds. + Weight::from_parts(101_398_156, 6248) + // Standard Error: 4_180 + .saturating_add(Weight::from_parts(1_377_850, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) - .saturating_add(T::DbWeight::get().writes(12_u64)) + .saturating_add(T::DbWeight::get().writes(11_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -244,10 +245,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn validate() -> Weight { // Proof Size summary in bytes: - // Measured: `1438` + // Measured: `1372` // Estimated: `4556` - // Minimum execution time: 68_826_000 picoseconds. - Weight::from_parts(71_261_000, 4556) + // Minimum execution time: 56_291_000 picoseconds. + Weight::from_parts(58_372_000, 4556) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } @@ -260,12 +261,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `k` is `[1, 128]`. fn kick(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1848 + k * (572 ±0)` + // Measured: `1815 + k * (572 ±0)` // Estimated: `4556 + k * (3033 ±0)` - // Minimum execution time: 46_082_000 picoseconds. - Weight::from_parts(49_541_374, 4556) - // Standard Error: 7_218 - .saturating_add(Weight::from_parts(7_281_079, 0).saturating_mul(k.into())) + // Minimum execution time: 36_218_000 picoseconds. + Weight::from_parts(38_811_308, 4556) + // Standard Error: 8_352 + .saturating_add(Weight::from_parts(6_527_398, 0).saturating_mul(k.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -296,12 +297,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[1, 16]`. fn nominate(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1932 + n * (102 ±0)` + // Measured: `1866 + n * (102 ±0)` // Estimated: `6248 + n * (2520 ±0)` - // Minimum execution time: 83_854_000 picoseconds. - Weight::from_parts(81_387_241, 6248) - // Standard Error: 16_811 - .saturating_add(Weight::from_parts(4_900_554, 0).saturating_mul(n.into())) + // Minimum execution time: 68_607_000 picoseconds. + Weight::from_parts(66_831_185, 6248) + // Standard Error: 14_014 + .saturating_add(Weight::from_parts(4_031_635, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(6_u64)) @@ -325,10 +326,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill() -> Weight { // Proof Size summary in bytes: - // Measured: `1882` + // Measured: `1816` // Estimated: `6248` - // Minimum execution time: 73_939_000 picoseconds. - Weight::from_parts(75_639_000, 6248) + // Minimum execution time: 60_088_000 picoseconds. + Weight::from_parts(62_471_000, 6248) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -340,10 +341,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn set_payee() -> Weight { // Proof Size summary in bytes: - // Measured: `935` + // Measured: `902` // Estimated: `4556` - // Minimum execution time: 24_592_000 picoseconds. - Weight::from_parts(25_092_000, 4556) + // Minimum execution time: 19_777_000 picoseconds. + Weight::from_parts(20_690_000, 4556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -355,10 +356,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn update_payee() -> Weight { // Proof Size summary in bytes: - // Measured: `1002` + // Measured: `969` // Estimated: `4556` - // Minimum execution time: 29_735_000 picoseconds. - Weight::from_parts(30_546_000, 4556) + // Minimum execution time: 23_705_000 picoseconds. + Weight::from_parts(24_409_000, 4556) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -368,10 +369,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) fn set_controller() -> Weight { // Proof Size summary in bytes: - // Measured: `935` + // Measured: `902` // Estimated: `8122` - // Minimum execution time: 28_728_000 picoseconds. - Weight::from_parts(29_709_000, 8122) + // Minimum execution time: 23_479_000 picoseconds. + Weight::from_parts(24_502_000, 8122) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -381,8 +382,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_519_000 picoseconds. - Weight::from_parts(2_673_000, 0) + // Minimum execution time: 2_675_000 picoseconds. + Weight::from_parts(2_802_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -391,8 +392,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_050_000 picoseconds. - Weight::from_parts(8_268_000, 0) + // Minimum execution time: 7_067_000 picoseconds. + Weight::from_parts(7_413_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -401,8 +402,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_131_000 picoseconds. - Weight::from_parts(8_349_000, 0) + // Minimum execution time: 6_977_000 picoseconds. + Weight::from_parts(7_353_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -411,8 +412,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_104_000 picoseconds. - Weight::from_parts(8_317_000, 0) + // Minimum execution time: 7_071_000 picoseconds. + Weight::from_parts(7_463_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::Invulnerables` (r:0 w:1) @@ -422,10 +423,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_669_000 picoseconds. - Weight::from_parts(3_013_436, 0) - // Standard Error: 31 - .saturating_add(Weight::from_parts(10_704, 0).saturating_mul(v.into())) + // Minimum execution time: 2_833_000 picoseconds. + Weight::from_parts(3_328_130, 0) + // Standard Error: 30 + .saturating_add(Weight::from_parts(10_058, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::Ledger` (r:11800 w:11800) @@ -437,12 +438,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `i` is `[0, 5900]`. fn deprecate_controller_batch(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1779 + i * (229 ±0)` + // Measured: `1746 + i * (229 ±0)` // Estimated: `990 + i * (7132 ±0)` - // Minimum execution time: 5_101_000 picoseconds. - Weight::from_parts(5_368_000, 990) - // Standard Error: 75_180 - .saturating_add(Weight::from_parts(33_781_643, 0).saturating_mul(i.into())) + // Minimum execution time: 5_300_000 picoseconds. + Weight::from_parts(5_437_000, 990) + // Standard Error: 66_261 + .saturating_add(Weight::from_parts(30_172_457, 0).saturating_mul(i.into())) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(i.into()))) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 7132).saturating_mul(i.into())) @@ -453,10 +454,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:1) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) @@ -478,14 +479,14 @@ impl WeightInfo for SubstrateWeight { /// The range of component `s` is `[0, 100]`. fn force_unstake(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2255 + s * (4 ±0)` + // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 119_955_000 picoseconds. - Weight::from_parts(128_392_032, 6248) - // Standard Error: 3_773 - .saturating_add(Weight::from_parts(1_302_488, 0).saturating_mul(s.into())) + // Minimum execution time: 87_677_000 picoseconds. + Weight::from_parts(96_386_462, 6248) + // Standard Error: 3_717 + .saturating_add(Weight::from_parts(1_370_585, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(13_u64)) - .saturating_add(T::DbWeight::get().writes(13_u64)) + .saturating_add(T::DbWeight::get().writes(12_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -494,12 +495,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `s` is `[1, 1000]`. fn cancel_deferred_slash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `66705` - // Estimated: `70170` - // Minimum execution time: 139_290_000 picoseconds. - Weight::from_parts(959_667_494, 70170) - // Standard Error: 56_271 - .saturating_add(Weight::from_parts(4_798_293, 0).saturating_mul(s.into())) + // Measured: `66672` + // Estimated: `70137` + // Minimum execution time: 105_086_000 picoseconds. + Weight::from_parts(1_167_895_222, 70137) + // Standard Error: 77_022 + .saturating_add(Weight::from_parts(6_487_305, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -517,10 +518,12 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::ErasValidatorReward` (r:1 w:0) /// Proof: `Staking::ErasValidatorReward` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:257 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:257 w:257) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:257 w:257) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:257 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:257 w:257) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::ErasStakersPaged` (r:1 w:0) /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::ErasRewardPoints` (r:1 w:0) @@ -529,31 +532,29 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::ErasValidatorPrefs` (`max_values`: None, `max_size`: Some(57), added: 2532, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:257 w:0) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:257 w:257) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 256]`. fn payout_stakers_alive_staked(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `33283 + n * (370 ±0)` - // Estimated: `30958 + n * (3566 ±0)` - // Minimum execution time: 193_068_000 picoseconds. - Weight::from_parts(252_762_568, 30958) - // Standard Error: 22_743 - .saturating_add(Weight::from_parts(81_185_306, 0).saturating_mul(n.into())) + // Measured: `33297 + n * (377 ±0)` + // Estimated: `30944 + n * (3774 ±3)` + // Minimum execution time: 154_210_000 picoseconds. + Weight::from_parts(192_836_012, 30944) + // Standard Error: 40_441 + .saturating_add(Weight::from_parts(47_646_642, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(14_u64)) .saturating_add(T::DbWeight::get().reads((6_u64).saturating_mul(n.into()))) .saturating_add(T::DbWeight::get().writes(4_u64)) .saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(n.into())) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) @@ -561,25 +562,25 @@ impl WeightInfo for SubstrateWeight { /// The range of component `l` is `[1, 32]`. fn rebond(l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1947 + l * (7 ±0)` + // Measured: `1991 + l * (7 ±0)` // Estimated: `8877` - // Minimum execution time: 91_151_000 picoseconds. - Weight::from_parts(93_596_096, 8877) - // Standard Error: 5_313 - .saturating_add(Weight::from_parts(124_684, 0).saturating_mul(l.into())) + // Minimum execution time: 88_337_000 picoseconds. + Weight::from_parts(91_391_254, 8877) + // Standard Error: 4_485 + .saturating_add(Weight::from_parts(103_443, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(9_u64)) - .saturating_add(T::DbWeight::get().writes(6_u64)) + .saturating_add(T::DbWeight::get().writes(7_u64)) } - /// Storage: `Staking::VirtualStakers` (r:1 w:1) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:1) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::SlashingSpans` (r:1 w:1) /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) @@ -599,14 +600,14 @@ impl WeightInfo for SubstrateWeight { /// The range of component `s` is `[1, 100]`. fn reap_stash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2255 + s * (4 ±0)` + // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 133_214_000 picoseconds. - Weight::from_parts(137_290_527, 6248) - // Standard Error: 4_153 - .saturating_add(Weight::from_parts(1_291_007, 0).saturating_mul(s.into())) + // Minimum execution time: 98_014_000 picoseconds. + Weight::from_parts(102_537_670, 6248) + // Standard Error: 3_324 + .saturating_add(Weight::from_parts(1_353_142, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(12_u64)) - .saturating_add(T::DbWeight::get().writes(12_u64)) + .saturating_add(T::DbWeight::get().writes(11_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -650,12 +651,12 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0 + n * (720 ±0) + v * (3598 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 692_301_000 picoseconds. - Weight::from_parts(708_732_000, 512390) - // Standard Error: 2_117_299 - .saturating_add(Weight::from_parts(70_087_600, 0).saturating_mul(v.into())) - // Standard Error: 210_977 - .saturating_add(Weight::from_parts(22_953_405, 0).saturating_mul(n.into())) + // Minimum execution time: 608_575_000 picoseconds. + Weight::from_parts(613_663_000, 512390) + // Standard Error: 2_286_521 + .saturating_add(Weight::from_parts(72_108_001, 0).saturating_mul(v.into())) + // Standard Error: 227_839 + .saturating_add(Weight::from_parts(20_314_085, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(206_u64)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -684,14 +685,14 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[500, 1000]`. fn get_npos_voters(v: u32, n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `3241 + n * (911 ±0) + v * (395 ±0)` + // Measured: `3175 + n * (911 ±0) + v * (395 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 43_708_472_000 picoseconds. - Weight::from_parts(44_048_436_000, 512390) - // Standard Error: 493_244 - .saturating_add(Weight::from_parts(6_697_278, 0).saturating_mul(v.into())) - // Standard Error: 493_244 - .saturating_add(Weight::from_parts(4_559_779, 0).saturating_mul(n.into())) + // Minimum execution time: 37_173_756_000 picoseconds. + Weight::from_parts(37_488_937_000, 512390) + // Standard Error: 467_413 + .saturating_add(Weight::from_parts(8_086_367, 0).saturating_mul(v.into())) + // Standard Error: 467_413 + .saturating_add(Weight::from_parts(3_108_193, 0).saturating_mul(n.into())) .saturating_add(T::DbWeight::get().reads(201_u64)) .saturating_add(T::DbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(T::DbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -706,12 +707,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `v` is `[500, 1000]`. fn get_npos_targets(v: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1012 + v * (50 ±0)` + // Measured: `979 + v * (50 ±0)` // Estimated: `3510 + v * (2520 ±0)` - // Minimum execution time: 2_917_165_000 picoseconds. - Weight::from_parts(2_948_999_000, 3510) - // Standard Error: 33_372 - .saturating_add(Weight::from_parts(2_126_909, 0).saturating_mul(v.into())) + // Minimum execution time: 2_641_258_000 picoseconds. + Weight::from_parts(382_882_595, 3510) + // Standard Error: 11_991 + .saturating_add(Weight::from_parts(4_695_820, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(v.into()))) .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) @@ -734,8 +735,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_748_000 picoseconds. - Weight::from_parts(5_052_000, 0) + // Minimum execution time: 5_753_000 picoseconds. + Weight::from_parts(6_529_000, 0) .saturating_add(T::DbWeight::get().writes(7_u64)) } /// Storage: `Staking::MinCommission` (r:0 w:1) @@ -756,8 +757,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_316_000 picoseconds. - Weight::from_parts(4_526_000, 0) + // Minimum execution time: 5_212_000 picoseconds. + Weight::from_parts(5_451_000, 0) .saturating_add(T::DbWeight::get().writes(7_u64)) } /// Storage: `Staking::Bonded` (r:1 w:0) @@ -784,10 +785,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill_other() -> Weight { // Proof Size summary in bytes: - // Measured: `2005` + // Measured: `1939` // Estimated: `6248` - // Minimum execution time: 87_374_000 picoseconds. - Weight::from_parts(89_848_000, 6248) + // Minimum execution time: 73_000_000 picoseconds. + Weight::from_parts(75_184_000, 6248) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -797,10 +798,10 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) fn force_apply_min_commission() -> Weight { // Proof Size summary in bytes: - // Measured: `724` + // Measured: `691` // Estimated: `3510` - // Minimum execution time: 15_529_000 picoseconds. - Weight::from_parts(16_094_000, 3510) + // Minimum execution time: 13_056_000 picoseconds. + Weight::from_parts(13_517_000, 3510) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -810,51 +811,28 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_533_000 picoseconds. - Weight::from_parts(2_817_000, 0) + // Minimum execution time: 3_201_000 picoseconds. + Weight::from_parts(3_442_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:0) + /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:1) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - fn restore_ledger() -> Weight { - // Proof Size summary in bytes: - // Measured: `1110` - // Estimated: `4764` - // Minimum execution time: 50_105_000 picoseconds. - Weight::from_parts(50_966_000, 4764) - .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) - } - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:1 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - fn migrate_currency() -> Weight { + fn restore_ledger() -> Weight { // Proof Size summary in bytes: - // Measured: `1246` + // Measured: `1047` // Estimated: `4764` - // Minimum execution time: 94_054_000 picoseconds. - Weight::from_parts(96_272_000, 4764) - .saturating_add(T::DbWeight::get().reads(6_u64)) - .saturating_add(T::DbWeight::get().writes(2_u64)) + // Minimum execution time: 44_671_000 picoseconds. + Weight::from_parts(45_611_000, 4764) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) } } @@ -864,18 +842,18 @@ impl WeightInfo for () { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:0 w:1) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn bond() -> Weight { // Proof Size summary in bytes: - // Measured: `1068` - // Estimated: `4556` - // Minimum execution time: 71_854_000 picoseconds. - Weight::from_parts(73_408_000, 4556) + // Measured: `1042` + // Estimated: `4764` + // Minimum execution time: 46_504_000 picoseconds. + Weight::from_parts(48_459_000, 4764) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -883,20 +861,20 @@ impl WeightInfo for () { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn bond_extra() -> Weight { // Proof Size summary in bytes: - // Measured: `2049` + // Measured: `1990` // Estimated: `8877` - // Minimum execution time: 127_442_000 picoseconds. - Weight::from_parts(130_845_000, 8877) + // Minimum execution time: 90_475_000 picoseconds. + Weight::from_parts(93_619_000, 8877) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -910,22 +888,22 @@ impl WeightInfo for () { /// Proof: `Staking::MinNominatorBond` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) /// Proof: `VoterList::ListBags` (`max_values`: None, `max_size`: Some(82), added: 2557, mode: `MaxEncodedLen`) fn unbond() -> Weight { // Proof Size summary in bytes: - // Measured: `2151` + // Measured: `2195` // Estimated: `8877` - // Minimum execution time: 105_259_000 picoseconds. - Weight::from_parts(107_112_000, 8877) + // Minimum execution time: 99_335_000 picoseconds. + Weight::from_parts(101_440_000, 8877) .saturating_add(RocksDbWeight::get().reads(12_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + .saturating_add(RocksDbWeight::get().writes(7_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -933,21 +911,21 @@ impl WeightInfo for () { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::CurrentEra` (r:1 w:0) /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `NominationPools::ReversePoolIdLookup` (r:1 w:0) /// Proof: `NominationPools::ReversePoolIdLookup` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_update(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1393` - // Estimated: `4556` - // Minimum execution time: 77_158_000 picoseconds. - Weight::from_parts(79_140_122, 4556) - // Standard Error: 1_688 - .saturating_add(Weight::from_parts(62_663, 0).saturating_mul(s.into())) + // Measured: `1297` + // Estimated: `4764` + // Minimum execution time: 50_067_000 picoseconds. + Weight::from_parts(52_396_327, 4764) + // Standard Error: 1_419 + .saturating_add(Weight::from_parts(51_406, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -959,10 +937,10 @@ impl WeightInfo for () { /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::SlashingSpans` (r:1 w:1) /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Staking::VirtualStakers` (r:1 w:1) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) @@ -982,14 +960,14 @@ impl WeightInfo for () { /// The range of component `s` is `[0, 100]`. fn withdraw_unbonded_kill(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2255 + s * (4 ±0)` + // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 125_396_000 picoseconds. - Weight::from_parts(134_915_543, 6248) - // Standard Error: 3_660 - .saturating_add(Weight::from_parts(1_324_736, 0).saturating_mul(s.into())) + // Minimum execution time: 92_931_000 picoseconds. + Weight::from_parts(101_398_156, 6248) + // Standard Error: 4_180 + .saturating_add(Weight::from_parts(1_377_850, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) - .saturating_add(RocksDbWeight::get().writes(12_u64)) + .saturating_add(RocksDbWeight::get().writes(11_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -1017,10 +995,10 @@ impl WeightInfo for () { /// Proof: `Staking::CounterForValidators` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn validate() -> Weight { // Proof Size summary in bytes: - // Measured: `1438` + // Measured: `1372` // Estimated: `4556` - // Minimum execution time: 68_826_000 picoseconds. - Weight::from_parts(71_261_000, 4556) + // Minimum execution time: 56_291_000 picoseconds. + Weight::from_parts(58_372_000, 4556) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } @@ -1033,12 +1011,12 @@ impl WeightInfo for () { /// The range of component `k` is `[1, 128]`. fn kick(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1848 + k * (572 ±0)` + // Measured: `1815 + k * (572 ±0)` // Estimated: `4556 + k * (3033 ±0)` - // Minimum execution time: 46_082_000 picoseconds. - Weight::from_parts(49_541_374, 4556) - // Standard Error: 7_218 - .saturating_add(Weight::from_parts(7_281_079, 0).saturating_mul(k.into())) + // Minimum execution time: 36_218_000 picoseconds. + Weight::from_parts(38_811_308, 4556) + // Standard Error: 8_352 + .saturating_add(Weight::from_parts(6_527_398, 0).saturating_mul(k.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(k.into()))) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(k.into()))) @@ -1069,12 +1047,12 @@ impl WeightInfo for () { /// The range of component `n` is `[1, 16]`. fn nominate(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1932 + n * (102 ±0)` + // Measured: `1866 + n * (102 ±0)` // Estimated: `6248 + n * (2520 ±0)` - // Minimum execution time: 83_854_000 picoseconds. - Weight::from_parts(81_387_241, 6248) - // Standard Error: 16_811 - .saturating_add(Weight::from_parts(4_900_554, 0).saturating_mul(n.into())) + // Minimum execution time: 68_607_000 picoseconds. + Weight::from_parts(66_831_185, 6248) + // Standard Error: 14_014 + .saturating_add(Weight::from_parts(4_031_635, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(6_u64)) @@ -1098,10 +1076,10 @@ impl WeightInfo for () { /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill() -> Weight { // Proof Size summary in bytes: - // Measured: `1882` + // Measured: `1816` // Estimated: `6248` - // Minimum execution time: 73_939_000 picoseconds. - Weight::from_parts(75_639_000, 6248) + // Minimum execution time: 60_088_000 picoseconds. + Weight::from_parts(62_471_000, 6248) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -1113,10 +1091,10 @@ impl WeightInfo for () { /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn set_payee() -> Weight { // Proof Size summary in bytes: - // Measured: `935` + // Measured: `902` // Estimated: `4556` - // Minimum execution time: 24_592_000 picoseconds. - Weight::from_parts(25_092_000, 4556) + // Minimum execution time: 19_777_000 picoseconds. + Weight::from_parts(20_690_000, 4556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1128,10 +1106,10 @@ impl WeightInfo for () { /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) fn update_payee() -> Weight { // Proof Size summary in bytes: - // Measured: `1002` + // Measured: `969` // Estimated: `4556` - // Minimum execution time: 29_735_000 picoseconds. - Weight::from_parts(30_546_000, 4556) + // Minimum execution time: 23_705_000 picoseconds. + Weight::from_parts(24_409_000, 4556) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1141,10 +1119,10 @@ impl WeightInfo for () { /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) fn set_controller() -> Weight { // Proof Size summary in bytes: - // Measured: `935` + // Measured: `902` // Estimated: `8122` - // Minimum execution time: 28_728_000 picoseconds. - Weight::from_parts(29_709_000, 8122) + // Minimum execution time: 23_479_000 picoseconds. + Weight::from_parts(24_502_000, 8122) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -1154,8 +1132,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_519_000 picoseconds. - Weight::from_parts(2_673_000, 0) + // Minimum execution time: 2_675_000 picoseconds. + Weight::from_parts(2_802_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1164,8 +1142,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_050_000 picoseconds. - Weight::from_parts(8_268_000, 0) + // Minimum execution time: 7_067_000 picoseconds. + Weight::from_parts(7_413_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1174,8 +1152,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_131_000 picoseconds. - Weight::from_parts(8_349_000, 0) + // Minimum execution time: 6_977_000 picoseconds. + Weight::from_parts(7_353_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1184,8 +1162,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 8_104_000 picoseconds. - Weight::from_parts(8_317_000, 0) + // Minimum execution time: 7_071_000 picoseconds. + Weight::from_parts(7_463_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::Invulnerables` (r:0 w:1) @@ -1195,10 +1173,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_669_000 picoseconds. - Weight::from_parts(3_013_436, 0) - // Standard Error: 31 - .saturating_add(Weight::from_parts(10_704, 0).saturating_mul(v.into())) + // Minimum execution time: 2_833_000 picoseconds. + Weight::from_parts(3_328_130, 0) + // Standard Error: 30 + .saturating_add(Weight::from_parts(10_058, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::Ledger` (r:11800 w:11800) @@ -1210,12 +1188,12 @@ impl WeightInfo for () { /// The range of component `i` is `[0, 5900]`. fn deprecate_controller_batch(i: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1779 + i * (229 ±0)` + // Measured: `1746 + i * (229 ±0)` // Estimated: `990 + i * (7132 ±0)` - // Minimum execution time: 5_101_000 picoseconds. - Weight::from_parts(5_368_000, 990) - // Standard Error: 75_180 - .saturating_add(Weight::from_parts(33_781_643, 0).saturating_mul(i.into())) + // Minimum execution time: 5_300_000 picoseconds. + Weight::from_parts(5_437_000, 990) + // Standard Error: 66_261 + .saturating_add(Weight::from_parts(30_172_457, 0).saturating_mul(i.into())) .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(i.into()))) .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(i.into()))) .saturating_add(Weight::from_parts(0, 7132).saturating_mul(i.into())) @@ -1226,10 +1204,10 @@ impl WeightInfo for () { /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:1) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) @@ -1251,14 +1229,14 @@ impl WeightInfo for () { /// The range of component `s` is `[0, 100]`. fn force_unstake(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2255 + s * (4 ±0)` + // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 119_955_000 picoseconds. - Weight::from_parts(128_392_032, 6248) - // Standard Error: 3_773 - .saturating_add(Weight::from_parts(1_302_488, 0).saturating_mul(s.into())) + // Minimum execution time: 87_677_000 picoseconds. + Weight::from_parts(96_386_462, 6248) + // Standard Error: 3_717 + .saturating_add(Weight::from_parts(1_370_585, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(13_u64)) - .saturating_add(RocksDbWeight::get().writes(13_u64)) + .saturating_add(RocksDbWeight::get().writes(12_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -1267,12 +1245,12 @@ impl WeightInfo for () { /// The range of component `s` is `[1, 1000]`. fn cancel_deferred_slash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `66705` - // Estimated: `70170` - // Minimum execution time: 139_290_000 picoseconds. - Weight::from_parts(959_667_494, 70170) - // Standard Error: 56_271 - .saturating_add(Weight::from_parts(4_798_293, 0).saturating_mul(s.into())) + // Measured: `66672` + // Estimated: `70137` + // Minimum execution time: 105_086_000 picoseconds. + Weight::from_parts(1_167_895_222, 70137) + // Standard Error: 77_022 + .saturating_add(Weight::from_parts(6_487_305, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1290,10 +1268,12 @@ impl WeightInfo for () { /// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) /// Storage: `Staking::ErasValidatorReward` (r:1 w:0) /// Proof: `Staking::ErasValidatorReward` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:257 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:257 w:257) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:257 w:257) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:257 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:257 w:257) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::ErasStakersPaged` (r:1 w:0) /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::ErasRewardPoints` (r:1 w:0) @@ -1302,31 +1282,29 @@ impl WeightInfo for () { /// Proof: `Staking::ErasValidatorPrefs` (`max_values`: None, `max_size`: Some(57), added: 2532, mode: `MaxEncodedLen`) /// Storage: `Staking::Payee` (r:257 w:0) /// Proof: `Staking::Payee` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:257 w:257) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// The range of component `n` is `[0, 256]`. fn payout_stakers_alive_staked(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `33283 + n * (370 ±0)` - // Estimated: `30958 + n * (3566 ±0)` - // Minimum execution time: 193_068_000 picoseconds. - Weight::from_parts(252_762_568, 30958) - // Standard Error: 22_743 - .saturating_add(Weight::from_parts(81_185_306, 0).saturating_mul(n.into())) + // Measured: `33297 + n * (377 ±0)` + // Estimated: `30944 + n * (3774 ±3)` + // Minimum execution time: 154_210_000 picoseconds. + Weight::from_parts(192_836_012, 30944) + // Standard Error: 40_441 + .saturating_add(Weight::from_parts(47_646_642, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(14_u64)) .saturating_add(RocksDbWeight::get().reads((6_u64).saturating_mul(n.into()))) .saturating_add(RocksDbWeight::get().writes(4_u64)) .saturating_add(RocksDbWeight::get().writes((3_u64).saturating_mul(n.into()))) - .saturating_add(Weight::from_parts(0, 3566).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 3774).saturating_mul(n.into())) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:0) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListNodes` (r:3 w:3) /// Proof: `VoterList::ListNodes` (`max_values`: None, `max_size`: Some(154), added: 2629, mode: `MaxEncodedLen`) /// Storage: `VoterList::ListBags` (r:2 w:2) @@ -1334,25 +1312,25 @@ impl WeightInfo for () { /// The range of component `l` is `[1, 32]`. fn rebond(l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1947 + l * (7 ±0)` + // Measured: `1991 + l * (7 ±0)` // Estimated: `8877` - // Minimum execution time: 91_151_000 picoseconds. - Weight::from_parts(93_596_096, 8877) - // Standard Error: 5_313 - .saturating_add(Weight::from_parts(124_684, 0).saturating_mul(l.into())) + // Minimum execution time: 88_337_000 picoseconds. + Weight::from_parts(91_391_254, 8877) + // Standard Error: 4_485 + .saturating_add(Weight::from_parts(103_443, 0).saturating_mul(l.into())) .saturating_add(RocksDbWeight::get().reads(9_u64)) - .saturating_add(RocksDbWeight::get().writes(6_u64)) + .saturating_add(RocksDbWeight::get().writes(7_u64)) } - /// Storage: `Staking::VirtualStakers` (r:1 w:1) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:1) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) /// Storage: `Staking::SlashingSpans` (r:1 w:1) /// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) + /// Storage: `Balances::Locks` (r:1 w:1) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `Balances::Freezes` (r:1 w:0) + /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) /// Storage: `Staking::Validators` (r:1 w:0) /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) /// Storage: `Staking::Nominators` (r:1 w:1) @@ -1372,14 +1350,14 @@ impl WeightInfo for () { /// The range of component `s` is `[1, 100]`. fn reap_stash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2255 + s * (4 ±0)` + // Measured: `2196 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 133_214_000 picoseconds. - Weight::from_parts(137_290_527, 6248) - // Standard Error: 4_153 - .saturating_add(Weight::from_parts(1_291_007, 0).saturating_mul(s.into())) + // Minimum execution time: 98_014_000 picoseconds. + Weight::from_parts(102_537_670, 6248) + // Standard Error: 3_324 + .saturating_add(Weight::from_parts(1_353_142, 0).saturating_mul(s.into())) .saturating_add(RocksDbWeight::get().reads(12_u64)) - .saturating_add(RocksDbWeight::get().writes(12_u64)) + .saturating_add(RocksDbWeight::get().writes(11_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -1423,12 +1401,12 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0 + n * (720 ±0) + v * (3598 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 692_301_000 picoseconds. - Weight::from_parts(708_732_000, 512390) - // Standard Error: 2_117_299 - .saturating_add(Weight::from_parts(70_087_600, 0).saturating_mul(v.into())) - // Standard Error: 210_977 - .saturating_add(Weight::from_parts(22_953_405, 0).saturating_mul(n.into())) + // Minimum execution time: 608_575_000 picoseconds. + Weight::from_parts(613_663_000, 512390) + // Standard Error: 2_286_521 + .saturating_add(Weight::from_parts(72_108_001, 0).saturating_mul(v.into())) + // Standard Error: 227_839 + .saturating_add(Weight::from_parts(20_314_085, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(206_u64)) .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -1457,14 +1435,14 @@ impl WeightInfo for () { /// The range of component `n` is `[500, 1000]`. fn get_npos_voters(v: u32, n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `3241 + n * (911 ±0) + v * (395 ±0)` + // Measured: `3175 + n * (911 ±0) + v * (395 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 43_708_472_000 picoseconds. - Weight::from_parts(44_048_436_000, 512390) - // Standard Error: 493_244 - .saturating_add(Weight::from_parts(6_697_278, 0).saturating_mul(v.into())) - // Standard Error: 493_244 - .saturating_add(Weight::from_parts(4_559_779, 0).saturating_mul(n.into())) + // Minimum execution time: 37_173_756_000 picoseconds. + Weight::from_parts(37_488_937_000, 512390) + // Standard Error: 467_413 + .saturating_add(Weight::from_parts(8_086_367, 0).saturating_mul(v.into())) + // Standard Error: 467_413 + .saturating_add(Weight::from_parts(3_108_193, 0).saturating_mul(n.into())) .saturating_add(RocksDbWeight::get().reads(201_u64)) .saturating_add(RocksDbWeight::get().reads((5_u64).saturating_mul(v.into()))) .saturating_add(RocksDbWeight::get().reads((4_u64).saturating_mul(n.into()))) @@ -1479,12 +1457,12 @@ impl WeightInfo for () { /// The range of component `v` is `[500, 1000]`. fn get_npos_targets(v: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1012 + v * (50 ±0)` + // Measured: `979 + v * (50 ±0)` // Estimated: `3510 + v * (2520 ±0)` - // Minimum execution time: 2_917_165_000 picoseconds. - Weight::from_parts(2_948_999_000, 3510) - // Standard Error: 33_372 - .saturating_add(Weight::from_parts(2_126_909, 0).saturating_mul(v.into())) + // Minimum execution time: 2_641_258_000 picoseconds. + Weight::from_parts(382_882_595, 3510) + // Standard Error: 11_991 + .saturating_add(Weight::from_parts(4_695_820, 0).saturating_mul(v.into())) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(v.into()))) .saturating_add(Weight::from_parts(0, 2520).saturating_mul(v.into())) @@ -1507,8 +1485,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_748_000 picoseconds. - Weight::from_parts(5_052_000, 0) + // Minimum execution time: 5_753_000 picoseconds. + Weight::from_parts(6_529_000, 0) .saturating_add(RocksDbWeight::get().writes(7_u64)) } /// Storage: `Staking::MinCommission` (r:0 w:1) @@ -1529,8 +1507,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 4_316_000 picoseconds. - Weight::from_parts(4_526_000, 0) + // Minimum execution time: 5_212_000 picoseconds. + Weight::from_parts(5_451_000, 0) .saturating_add(RocksDbWeight::get().writes(7_u64)) } /// Storage: `Staking::Bonded` (r:1 w:0) @@ -1557,10 +1535,10 @@ impl WeightInfo for () { /// Proof: `VoterList::CounterForListNodes` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) fn chill_other() -> Weight { // Proof Size summary in bytes: - // Measured: `2005` + // Measured: `1939` // Estimated: `6248` - // Minimum execution time: 87_374_000 picoseconds. - Weight::from_parts(89_848_000, 6248) + // Minimum execution time: 73_000_000 picoseconds. + Weight::from_parts(75_184_000, 6248) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -1570,10 +1548,10 @@ impl WeightInfo for () { /// Proof: `Staking::Validators` (`max_values`: None, `max_size`: Some(45), added: 2520, mode: `MaxEncodedLen`) fn force_apply_min_commission() -> Weight { // Proof Size summary in bytes: - // Measured: `724` + // Measured: `691` // Estimated: `3510` - // Minimum execution time: 15_529_000 picoseconds. - Weight::from_parts(16_094_000, 3510) + // Minimum execution time: 13_056_000 picoseconds. + Weight::from_parts(13_517_000, 3510) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1583,50 +1561,27 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_533_000 picoseconds. - Weight::from_parts(2_817_000, 0) + // Minimum execution time: 3_201_000 picoseconds. + Weight::from_parts(3_442_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:0) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) - /// Storage: `System::Account` (r:1 w:0) - /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:0) + /// Storage: `Balances::Locks` (r:1 w:1) /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) /// Storage: `Staking::Bonded` (r:1 w:1) /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - fn restore_ledger() -> Weight { - // Proof Size summary in bytes: - // Measured: `1110` - // Estimated: `4764` - // Minimum execution time: 50_105_000 picoseconds. - Weight::from_parts(50_966_000, 4764) - .saturating_add(RocksDbWeight::get().reads(6_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) - } - /// Storage: `Staking::VirtualStakers` (r:1 w:0) - /// Proof: `Staking::VirtualStakers` (`max_values`: None, `max_size`: Some(40), added: 2515, mode: `MaxEncodedLen`) - /// Storage: `Staking::Bonded` (r:1 w:0) - /// Proof: `Staking::Bonded` (`max_values`: None, `max_size`: Some(72), added: 2547, mode: `MaxEncodedLen`) - /// Storage: `Staking::Ledger` (r:1 w:0) - /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) - /// Storage: `Balances::Locks` (r:1 w:1) - /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, mode: `MaxEncodedLen`) - /// Storage: `Balances::Holds` (r:1 w:1) - /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`) /// Storage: `Balances::Freezes` (r:1 w:0) /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) - fn migrate_currency() -> Weight { + fn restore_ledger() -> Weight { // Proof Size summary in bytes: - // Measured: `1246` + // Measured: `1047` // Estimated: `4764` - // Minimum execution time: 94_054_000 picoseconds. - Weight::from_parts(96_272_000, 4764) - .saturating_add(RocksDbWeight::get().reads(6_u64)) - .saturating_add(RocksDbWeight::get().writes(2_u64)) + // Minimum execution time: 44_671_000 picoseconds. + Weight::from_parts(45_611_000, 4764) + .saturating_add(RocksDbWeight::get().reads(5_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) } } \ No newline at end of file diff --git a/substrate/primitives/staking/src/lib.rs b/substrate/primitives/staking/src/lib.rs index 8e23c6800a9d..17010a8907fc 100644 --- a/substrate/primitives/staking/src/lib.rs +++ b/substrate/primitives/staking/src/lib.rs @@ -325,7 +325,7 @@ pub trait StakingUnchecked: StakingInterface { /// Migrate an existing staker to a virtual staker. /// /// It would release all funds held by the implementation pallet. - fn migrate_to_virtual_staker(who: &Self::AccountId) -> DispatchResult; + fn migrate_to_virtual_staker(who: &Self::AccountId); /// Book-keep a new bond for `keyless_who` without applying any locks (hence virtual). ///