From c92a0bd907afb421a07f7ffd0e11e0bc673a6d29 Mon Sep 17 00:00:00 2001 From: Ankan Date: Sun, 18 Aug 2024 23:07:14 +0200 Subject: [PATCH 01/56] add fungible to config balance hold checks both frozen and reserved wip: around 25 tests failing check Holds instead of locks 20 tests failing fmt 11 fails 4 fails 2 failing 1 fail all tests pass but pending a hygiene check of code fix compile minor refactor remove T::Currency calls from asset mod --- substrate/frame/staking/src/asset.rs | 70 +++++++++++++-------- substrate/frame/staking/src/benchmarking.rs | 4 +- substrate/frame/staking/src/ledger.rs | 5 +- substrate/frame/staking/src/lib.rs | 13 ++-- substrate/frame/staking/src/mock.rs | 16 ++--- substrate/frame/staking/src/pallet/impls.rs | 4 +- substrate/frame/staking/src/pallet/mod.rs | 38 ++++++++++- substrate/frame/staking/src/tests.rs | 33 ++++++---- 8 files changed, 123 insertions(+), 60 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 8d125cd0034b..e4bc82ed6ba9 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -1,63 +1,79 @@ //! Facade of currency implementation. Useful while migrating from old to new currency system. -use frame_support::traits::{Currency, InspectLockableCurrency, LockableCurrency}; - -use crate::{BalanceOf, Config, NegativeImbalanceOf, PositiveImbalanceOf}; +use frame_support::traits::{ + fungible::{ + hold::{Balanced as FunHoldBalanced, Inspect as FunHoldInspect, Mutate as FunHoldMutate}, + Balanced, Inspect as FunInspect, Mutate as FunMutate, + }, + tokens::{Fortitude, Precision}, + Currency, Imbalance, InspectLockableCurrency, LockableCurrency, +}; +use sp_runtime::{traits::Zero, DispatchResult}; + +use crate::{BalanceOf, Config, Error, HoldReason, NegativeImbalanceOf, PositiveImbalanceOf}; /// Existential deposit for the chain. pub fn existential_deposit() -> BalanceOf { - T::Currency::minimum_balance() + T::Fungible::minimum_balance() } /// Total issuance of the chain. pub fn total_issuance() -> BalanceOf { - T::Currency::total_issuance() + T::Fungible::total_issuance() } /// Total balance of `who`. Includes both, free and reserved. pub fn total_balance(who: &T::AccountId) -> BalanceOf { - T::Currency::total_balance(who) + T::Fungible::total_balance(who) } /// Stakeable balance of `who`. /// /// This includes balance free to stake along with any balance that is already staked. pub fn stakeable_balance(who: &T::AccountId) -> BalanceOf { - T::Currency::free_balance(who) + T::Fungible::balance(who) + T::Fungible::balance_on_hold(&HoldReason::Staking.into(), who) } /// Balance of `who` that is currently at stake. /// /// The staked amount is locked and cannot be transferred out of `who`s account. pub fn staked(who: &T::AccountId) -> BalanceOf { - T::Currency::balance_locked(crate::STAKING_ID, who) + T::Fungible::balance_on_hold(&HoldReason::Staking.into(), who) } /// Set balance that can be staked for `who`. /// /// This includes any balance that is already staked. +#[cfg(any(test, feature = "runtime-benchmarks"))] pub fn set_stakeable_balance(who: &T::AccountId, value: BalanceOf) { - T::Currency::make_free_balance_be(who, value); + let reserved_balance = staked::(who); + if reserved_balance < value { + let _ = T::Fungible::set_balance(who, value - reserved_balance); + } else { + update_stake::(who, value).expect("can remove from what is staked"); + // burn all free + let _ = T::Fungible::set_balance(who, Zero::zero()); + } + + assert!(total_balance::(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) { - T::Currency::set_lock( - crate::STAKING_ID, - who, - amount, - frame_support::traits::WithdrawReasons::all(), - ); +pub fn update_stake(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { + // if first stake, inc provider. + if staked::(who) == Zero::zero() && amount > Zero::zero() { + frame_system::Pallet::::inc_providers(who); + } + + T::Fungible::set_on_hold(&HoldReason::Staking.into(), who, amount) } -/// Kill the stake of `who`. -/// -/// All locked amount is unlocked. -pub fn kill_stake(who: &T::AccountId) { - T::Currency::remove_lock(crate::STAKING_ID, who); +pub fn kill_stake(who: &T::AccountId) -> DispatchResult { + let _ = frame_system::Pallet::::dec_providers(who); + T::Fungible::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort).map(|_| ()) } /// Slash the value from `who`. @@ -67,7 +83,7 @@ pub fn slash( who: &T::AccountId, value: BalanceOf, ) -> (NegativeImbalanceOf, BalanceOf) { - T::Currency::slash(who, value) + T::Fungible::slash(&HoldReason::Staking.into(), who, value) } /// Mint reward into an existing account. @@ -77,30 +93,30 @@ pub fn mint_existing( who: &T::AccountId, value: BalanceOf, ) -> Option> { - T::Currency::deposit_into_existing(who, value).ok() + T::Fungible::deposit(who, value, Precision::Exact).ok() } /// Mint reward and create account for `who` if it does not exist. /// /// This does not increase the total issuance. pub fn mint_creating(who: &T::AccountId, value: BalanceOf) -> PositiveImbalanceOf { - T::Currency::deposit_creating(who, value) + T::Fungible::deposit(who, value, Precision::Exact).unwrap_or_default() } /// Deposit newly issued or slashed `value` into `who`. pub fn deposit_slashed(who: &T::AccountId, value: NegativeImbalanceOf) { - T::Currency::resolve_creating(who, value) + let _ = T::Fungible::resolve(who, value); } /// Issue `value` increasing total issuance. /// /// Creates a negative imbalance. pub fn issue(value: BalanceOf) -> NegativeImbalanceOf { - T::Currency::issue(value) + T::Fungible::issue(value) } /// Burn the amount from the total issuance. #[cfg(feature = "runtime-benchmarks")] pub fn burn(amount: BalanceOf) -> PositiveImbalanceOf { - T::Currency::burn(amount) + T::Fungible::rescind(amount) } diff --git a/substrate/frame/staking/src/benchmarking.rs b/substrate/frame/staking/src/benchmarking.rs index e4b5cfccd0b4..e32bd7540cc0 100644 --- a/substrate/frame/staking/src/benchmarking.rs +++ b/substrate/frame/staking/src/benchmarking.rs @@ -1019,14 +1019,14 @@ mod tests { let current_era = CurrentEra::::get().unwrap(); - let original_free_balance = Balances::free_balance(&validator_stash); + let original_free_balance = asset::stakeable_balance::(&validator_stash); assert_ok!(Staking::payout_stakers_by_page( RuntimeOrigin::signed(1337), validator_stash, current_era, 0 )); - let new_free_balance = Balances::free_balance(&validator_stash); + let new_free_balance = asset::stakeable_balance::(&validator_stash); assert!(original_free_balance < new_free_balance); }); diff --git a/substrate/frame/staking/src/ledger.rs b/substrate/frame/staking/src/ledger.rs index ac3be04cf607..0a91c6472d20 100644 --- a/substrate/frame/staking/src/ledger.rs +++ b/substrate/frame/staking/src/ledger.rs @@ -187,7 +187,8 @@ 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); + asset::update_stake::(&self.stash, self.total) + .map_err(|_| Error::::NotEnoughFunds)?; } Ledger::::insert( @@ -261,7 +262,7 @@ impl StakingLedger { // kill virtual staker if it exists. if >::take(&stash).is_none() { // if not virtual staker, clear locks. - asset::kill_stake::(&ledger.stash); + let _ = asset::kill_stake::(&ledger.stash).defensive(); } Ok(()) diff --git a/substrate/frame/staking/src/lib.rs b/substrate/frame/staking/src/lib.rs index 19d999109d8d..3bfbc11f3262 100644 --- a/substrate/frame/staking/src/lib.rs +++ b/substrate/frame/staking/src/lib.rs @@ -312,6 +312,10 @@ use codec::{Decode, Encode, HasCompact, MaxEncodedLen}; use frame_support::{ defensive, defensive_assert, traits::{ + tokens::{ + fungible::{Credit, Debt, Inspect, InspectHold}, + Fortitude, Preservation, + }, ConstU32, Currency, Defensive, DefensiveMax, DefensiveSaturating, Get, LockIdentifier, }, weights::Weight, @@ -361,12 +365,9 @@ pub type RewardPoint = u32; /// The balance type of this pallet. pub type BalanceOf = ::CurrencyBalance; -type PositiveImbalanceOf = <::Currency as Currency< - ::AccountId, ->>::PositiveImbalance; -pub type NegativeImbalanceOf = <::Currency as Currency< - ::AccountId, ->>::NegativeImbalance; +type PositiveImbalanceOf = Debt<::AccountId, ::Fungible>; +pub type NegativeImbalanceOf = + Credit<::AccountId, ::Fungible>; type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index 4a0209fc5b08..787b9ec19467 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -25,6 +25,7 @@ use frame_election_provider_support::{ use frame_support::{ assert_ok, derive_impl, ord_parameter_types, parameter_types, traits::{ + fungible::{Inspect, Mutate, MutateHold}, ConstU64, Currency, EitherOfDiverse, FindAuthor, Get, Hooks, Imbalance, LockableCurrency, OnUnbalanced, OneSessionHandler, WithdrawReasons, }, @@ -264,6 +265,7 @@ pub(crate) const DISABLING_LIMIT_FACTOR: usize = 3; #[derive_impl(crate::config_preludes::TestDefaultConfig)] impl crate::pallet::pallet::Config for Test { type Currency = Balances; + type Fungible = Balances; type UnixTime = Timestamp; type RewardRemainder = RewardRemainderMock; type Reward = MockReward; @@ -576,7 +578,7 @@ pub(crate) fn current_era() -> EraIndex { } pub(crate) fn bond(who: AccountId, val: Balance) { - let _ = Balances::make_free_balance_be(&who, val); + let _ = asset::set_stakeable_balance::(&who, val); assert_ok!(Staking::bond(RuntimeOrigin::signed(who), val, RewardDestination::Stash)); } @@ -812,7 +814,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; - Balances::set_lock(crate::STAKING_ID, stash, new_total, WithdrawReasons::all()); + let _ = asset::update_stake::(stash, new_total); ledger.total = new_total; ledger.active = new_total; Ledger::::insert(controller, ledger); @@ -821,10 +823,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 _ = 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); + 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); assert_ok!(Staking::bond(RuntimeOrigin::signed(333), 10, RewardDestination::Staked)); assert_ok!(Staking::bond(RuntimeOrigin::signed(444), 20, RewardDestination::Staked)); @@ -926,5 +928,5 @@ pub(crate) fn staking_events_since_last_call() -> Vec> { } pub(crate) fn balances(who: &AccountId) -> (Balance, Balance) { - (Balances::free_balance(who), Balances::reserved_balance(who)) + (asset::stakeable_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 6c4fe8140e8e..797aff003243 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -1919,7 +1919,7 @@ impl StakingInterface for Pallet { impl sp_staking::StakingUnchecked for Pallet { fn migrate_to_virtual_staker(who: &Self::AccountId) { - asset::kill_stake::(who); + let _ = asset::kill_stake::(who).defensive(); VirtualStakers::::insert(who, ()); } @@ -1956,7 +1956,7 @@ impl sp_staking::StakingUnchecked for Pallet { fn migrate_to_direct_staker(who: &Self::AccountId) { assert!(VirtualStakers::::contains_key(who)); let ledger = StakingLedger::::get(Stash(who.clone())).unwrap(); - asset::update_stake::(who, ledger.total); + let _ = asset::update_stake::(who, ledger.total); VirtualStakers::::remove(who); } } diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index 63861d77f368..93c042875fc0 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -25,6 +25,13 @@ use frame_election_provider_support::{ use frame_support::{ pallet_prelude::*, traits::{ + fungible::{ + hold::{ + Balanced as FunHoldBalanced, Inspect as FunHoldInspect, Mutate as FunHoldMutate, + }, + Balanced, Inspect as FunInspect, Mutate as FunMutate, + }, + tokens::Precision, Defensive, DefensiveSaturating, EnsureOrigin, EstimateNextNewSession, Get, InspectLockableCurrency, LockableCurrency, OnUnbalanced, UnixTime, }, @@ -95,6 +102,19 @@ pub mod pallet { Moment = BlockNumberFor, Balance = Self::CurrencyBalance, > + InspectLockableCurrency; + + #[pallet::no_default] + type Fungible: FunHoldMutate< + Self::AccountId, + Reason = Self::RuntimeHoldReason, + Balance = Self::CurrencyBalance, + > + FunMutate + + FunHoldBalanced; + + /// Overarching hold reason. + #[pallet::no_default_bounds] + type RuntimeHoldReason: From; + /// Just the `Currency::Balance` type; we have this item to allow us to constrain it to /// `From`. type CurrencyBalance: sp_runtime::traits::AtLeast32BitUnsigned @@ -105,6 +125,8 @@ pub mod pallet { + Default + From + TypeInfo + + Send + + Sync + MaxEncodedLen; /// Time used for computing era duration. /// @@ -308,6 +330,14 @@ pub mod pallet { type WeightInfo: WeightInfo; } + /// A reason for placing a hold on funds. + #[pallet::composite_enum] + pub enum HoldReason { + /// Funds held for stake delegation to another account. + #[codec(index = 0)] + Staking, + } + /// Default implementations of [`DefaultConfig`], which can be used to implement [`Config`]. pub mod config_preludes { use super::*; @@ -326,6 +356,8 @@ 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>; @@ -2086,7 +2118,7 @@ pub mod pallet { let new_total = if let Some(total) = maybe_total { let new_total = total.min(stash_balance); // enforce lock == ledger.amount. - asset::update_stake::(&stash, new_total); + asset::update_stake::(&stash, new_total)?; new_total } else { current_lock @@ -2113,13 +2145,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 diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 5eb9eff39efa..6a844be32509 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -108,7 +108,7 @@ fn force_unstake_works() { // Cant transfer assert_noop!( Balances::transfer_allow_death(RuntimeOrigin::signed(11), 1, 10), - TokenError::Frozen, + TokenError::FundsUnavailable, ); // Force unstake requires root. assert_noop!(Staking::force_unstake(RuntimeOrigin::signed(11), 11, 2), BadOrigin); @@ -490,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), BalancesError::::LiquidityRestrictions); + assert_noop!(Balances::reserve(&3, 501), BalancesError::::InsufficientBalance); assert_ok!(Balances::reserve(&3, 409)); }); } @@ -999,7 +999,7 @@ fn cannot_transfer_staked_balance() { // Confirm account 11 cannot transfer as a result assert_noop!( Balances::transfer_allow_death(RuntimeOrigin::signed(11), 21, 1), - TokenError::Frozen, + TokenError::FundsUnavailable, ); // Give account 11 extra free balance @@ -1024,7 +1024,7 @@ fn cannot_transfer_staked_balance_2() { // Confirm account 21 can transfer at most 1000 assert_noop!( Balances::transfer_allow_death(RuntimeOrigin::signed(21), 21, 1001), - TokenError::Frozen, + TokenError::FundsUnavailable, ); assert_ok!(Balances::transfer_allow_death(RuntimeOrigin::signed(21), 21, 1000)); }); @@ -1041,7 +1041,7 @@ fn cannot_reserve_staked_balance() { // 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, 1), BalancesError::::LiquidityRestrictions); + assert_noop!(Balances::reserve(&11, 1), BalancesError::::InsufficientBalance); // Give account 11 extra free balance let _ = asset::set_stakeable_balance::(&11, 10000); @@ -2077,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::Locks::::get(&1)[0].amount, 5); + assert_eq!(pallet_balances::Holds::::get(&1)[0].amount, 5); // unbonding even 1 will cause all to be unbonded. assert_ok!(Staking::unbond(RuntimeOrigin::signed(1), 1)); @@ -2098,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::Locks::::get(&1)[0].amount, 5); + assert_eq!(pallet_balances::Holds::::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::Locks::::get(&1).len(), 0); + assert_eq!(pallet_balances::Holds::::get(&1).len(), 0); }); } @@ -2340,7 +2340,18 @@ fn reward_validator_slashing_validator_does_not_overflow() { assert_ok!(Staking::payout_stakers_by_page(RuntimeOrigin::signed(1337), 11, 0, 0)); assert_eq!(asset::total_balance::(&11), stake * 2); - // Set staker + // 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) let _ = asset::set_stakeable_balance::(&11, stake); let _ = asset::set_stakeable_balance::(&2, stake); @@ -2812,8 +2823,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), 2); - assert_eq!(asset::total_balance::(&11), 2); + assert_eq!(asset::stakeable_balance::(&11), 0); + assert_eq!(asset::total_balance::(&11), 0); let slashing_spans = SlashingSpans::::get(&11).unwrap(); assert_eq!(slashing_spans.iter().count(), 2); From ebf60efd978db9a2a73f796a326f3086dc93f800 Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 27 Aug 2024 13:37:44 +0200 Subject: [PATCH 02/56] rustdoc fix --- substrate/frame/staking/src/asset.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index e4bc82ed6ba9..606f04158560 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -43,7 +43,10 @@ pub fn staked(who: &T::AccountId) -> BalanceOf { /// Set balance that can be staked for `who`. /// -/// This includes any balance that is already staked. +/// If `value` is less than already staked, the difference is amount is unlocked. Otherwise, +/// the difference is added to free balance. +/// +/// Should only be used with test. #[cfg(any(test, feature = "runtime-benchmarks"))] pub fn set_stakeable_balance(who: &T::AccountId, value: BalanceOf) { let reserved_balance = staked::(who); From 07e3ca93bd076c1d9d56c3502ec251443b198266 Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 27 Aug 2024 14:03:58 +0200 Subject: [PATCH 03/56] rename Fungible to Currency --- substrate/frame/staking/src/asset.rs | 30 +++++++++++------------ substrate/frame/staking/src/lib.rs | 4 +-- substrate/frame/staking/src/mock.rs | 1 - substrate/frame/staking/src/pallet/mod.rs | 9 +------ 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 606f04158560..a1bb9cdd2438 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -14,31 +14,31 @@ use crate::{BalanceOf, Config, Error, HoldReason, NegativeImbalanceOf, PositiveI /// Existential deposit for the chain. pub fn existential_deposit() -> BalanceOf { - T::Fungible::minimum_balance() + T::Currency::minimum_balance() } /// Total issuance of the chain. pub fn total_issuance() -> BalanceOf { - T::Fungible::total_issuance() + T::Currency::total_issuance() } /// Total balance of `who`. Includes both, free and reserved. pub fn total_balance(who: &T::AccountId) -> BalanceOf { - T::Fungible::total_balance(who) + T::Currency::total_balance(who) } /// Stakeable balance of `who`. /// /// This includes balance free to stake along with any balance that is already staked. pub fn stakeable_balance(who: &T::AccountId) -> BalanceOf { - T::Fungible::balance(who) + T::Fungible::balance_on_hold(&HoldReason::Staking.into(), who) + T::Currency::balance(who) + T::Currency::balance_on_hold(&HoldReason::Staking.into(), who) } /// Balance of `who` that is currently at stake. /// /// The staked amount is locked and cannot be transferred out of `who`s account. pub fn staked(who: &T::AccountId) -> BalanceOf { - T::Fungible::balance_on_hold(&HoldReason::Staking.into(), who) + T::Currency::balance_on_hold(&HoldReason::Staking.into(), who) } /// Set balance that can be staked for `who`. @@ -51,11 +51,11 @@ pub fn staked(who: &T::AccountId) -> BalanceOf { pub fn set_stakeable_balance(who: &T::AccountId, value: BalanceOf) { let reserved_balance = staked::(who); if reserved_balance < value { - let _ = T::Fungible::set_balance(who, value - reserved_balance); + let _ = T::Currency::set_balance(who, value - reserved_balance); } else { update_stake::(who, value).expect("can remove from what is staked"); // burn all free - let _ = T::Fungible::set_balance(who, Zero::zero()); + let _ = T::Currency::set_balance(who, Zero::zero()); } assert!(total_balance::(who) == value); @@ -71,12 +71,12 @@ pub fn update_stake(who: &T::AccountId, amount: BalanceOf) -> Disp frame_system::Pallet::::inc_providers(who); } - T::Fungible::set_on_hold(&HoldReason::Staking.into(), who, amount) + T::Currency::set_on_hold(&HoldReason::Staking.into(), who, amount) } pub fn kill_stake(who: &T::AccountId) -> DispatchResult { let _ = frame_system::Pallet::::dec_providers(who); - T::Fungible::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort).map(|_| ()) + T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort).map(|_| ()) } /// Slash the value from `who`. @@ -86,7 +86,7 @@ pub fn slash( who: &T::AccountId, value: BalanceOf, ) -> (NegativeImbalanceOf, BalanceOf) { - T::Fungible::slash(&HoldReason::Staking.into(), who, value) + T::Currency::slash(&HoldReason::Staking.into(), who, value) } /// Mint reward into an existing account. @@ -96,30 +96,30 @@ pub fn mint_existing( who: &T::AccountId, value: BalanceOf, ) -> Option> { - T::Fungible::deposit(who, value, Precision::Exact).ok() + T::Currency::deposit(who, value, Precision::Exact).ok() } /// Mint reward and create account for `who` if it does not exist. /// /// This does not increase the total issuance. pub fn mint_creating(who: &T::AccountId, value: BalanceOf) -> PositiveImbalanceOf { - T::Fungible::deposit(who, value, Precision::Exact).unwrap_or_default() + T::Currency::deposit(who, value, Precision::Exact).unwrap_or_default() } /// Deposit newly issued or slashed `value` into `who`. pub fn deposit_slashed(who: &T::AccountId, value: NegativeImbalanceOf) { - let _ = T::Fungible::resolve(who, value); + let _ = T::Currency::resolve(who, value); } /// Issue `value` increasing total issuance. /// /// Creates a negative imbalance. pub fn issue(value: BalanceOf) -> NegativeImbalanceOf { - T::Fungible::issue(value) + T::Currency::issue(value) } /// Burn the amount from the total issuance. #[cfg(feature = "runtime-benchmarks")] pub fn burn(amount: BalanceOf) -> PositiveImbalanceOf { - T::Fungible::rescind(amount) + T::Currency::rescind(amount) } diff --git a/substrate/frame/staking/src/lib.rs b/substrate/frame/staking/src/lib.rs index 3bfbc11f3262..f8a708152866 100644 --- a/substrate/frame/staking/src/lib.rs +++ b/substrate/frame/staking/src/lib.rs @@ -365,9 +365,9 @@ pub type RewardPoint = u32; /// The balance type of this pallet. pub type BalanceOf = ::CurrencyBalance; -type PositiveImbalanceOf = Debt<::AccountId, ::Fungible>; +type PositiveImbalanceOf = Debt<::AccountId, ::Currency>; pub type NegativeImbalanceOf = - Credit<::AccountId, ::Fungible>; + Credit<::AccountId, ::Currency>; type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index 787b9ec19467..e952d91c9c28 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -265,7 +265,6 @@ pub(crate) const DISABLING_LIMIT_FACTOR: usize = 3; #[derive_impl(crate::config_preludes::TestDefaultConfig)] impl crate::pallet::pallet::Config for Test { type Currency = Balances; - type Fungible = Balances; type UnixTime = Timestamp; type RewardRemainder = RewardRemainderMock; type Reward = MockReward; diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index 93c042875fc0..19f8a73cfbb7 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -97,14 +97,7 @@ pub mod pallet { pub trait Config: frame_system::Config { /// The staking balance. #[pallet::no_default] - type Currency: LockableCurrency< - Self::AccountId, - Moment = BlockNumberFor, - Balance = Self::CurrencyBalance, - > + InspectLockableCurrency; - - #[pallet::no_default] - type Fungible: FunHoldMutate< + type Currency: FunHoldMutate< Self::AccountId, Reason = Self::RuntimeHoldReason, Balance = Self::CurrencyBalance, From 58e8e83e133e2859080b36f208b21c64a5ebd31f Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 27 Aug 2024 14:18:49 +0200 Subject: [PATCH 04/56] add support for fungible imbalance handler in pallet treasury --- polkadot/runtime/test-runtime/src/lib.rs | 1 + polkadot/runtime/westend/src/lib.rs | 1 + substrate/bin/node/runtime/src/lib.rs | 5 +++-- substrate/frame/treasury/src/lib.rs | 21 ++++++++++++++++++--- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index 8e34320d38f2..450517e7692d 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -345,6 +345,7 @@ impl pallet_staking::Config for Runtime { 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 519c7dcde54e..ea43108fe32f 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -728,6 +728,7 @@ parameter_types! { impl pallet_staking::Config for Runtime { type Currency = Balances; type CurrencyBalance = Balance; + type RuntimeHoldReason = RuntimeHoldReason; type UnixTime = Timestamp; type CurrencyToVote = CurrencyToVote; type RewardRemainder = (); diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index ef5c52bf6e6e..7249b79ac0d3 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -671,9 +671,10 @@ impl pallet_staking::Config for Runtime { type CurrencyBalance = Balance; type UnixTime = Timestamp; type CurrencyToVote = sp_staking::currency_to_vote::U128CurrencyToVote; - type RewardRemainder = Treasury; + type RewardRemainder = pallet_treasury::FungibleCompat; type RuntimeEvent = RuntimeEvent; - type Slash = Treasury; // send the slashed funds to the treasury. + type RuntimeHoldReason = RuntimeHoldReason; + type Slash = pallet_treasury::FungibleCompat; // send the slashed funds to the treasury. type Reward = (); // rewards are minted from the void type SessionsPerEra = SessionsPerEra; type BondingDuration = BondingDuration; diff --git a/substrate/frame/treasury/src/lib.rs b/substrate/frame/treasury/src/lib.rs index 3954489a2d15..f74fce028648 100644 --- a/substrate/frame/treasury/src/lib.rs +++ b/substrate/frame/treasury/src/lib.rs @@ -96,8 +96,8 @@ use frame_support::{ dispatch::{DispatchResult, DispatchResultWithPostInfo}, ensure, print, traits::{ - tokens::Pay, Currency, ExistenceRequirement::KeepAlive, Get, Imbalance, OnUnbalanced, - ReservableCurrency, WithdrawReasons, + fungible::Credit, tokens::Pay, Currency, ExistenceRequirement::KeepAlive, Get, Imbalance, + OnUnbalanced, ReservableCurrency, WithdrawReasons, }, weights::Weight, PalletId, @@ -205,7 +205,9 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { /// The staking balance. - type Currency: Currency + ReservableCurrency; + type Currency: Currency + + ReservableCurrency + + frame_support::traits::fungible::Balanced>; /// Origin from which rejections must come. type RejectOrigin: EnsureOrigin; @@ -974,6 +976,19 @@ impl, I: 'static> OnUnbalanced> for Palle } } +/// Implement the `OnUnbalanced` handler for [`frame_support::traits::fungible`] trait currency. +pub struct FungibleCompat(PhantomData); +impl OnUnbalanced> for FungibleCompat { + fn on_nonzero_unbalanced(credit: Credit) { + use frame_support::traits::fungible::Balanced; + let numeric_amount = credit.peek(); + + let _ = T::Currency::resolve(&Pallet::::account_id(), credit); + + Pallet::::deposit_event(Event::Deposit { value: numeric_amount }); + } +} + /// TypedGet implementation to get the AccountId of the Treasury. pub struct TreasuryAccountId(PhantomData); impl sp_runtime::traits::TypedGet for TreasuryAccountId From a9d0345cdce0f80dcbff3097a02561d83151f304 Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 27 Aug 2024 14:42:44 +0200 Subject: [PATCH 05/56] fix unused imports --- substrate/frame/staking/src/asset.rs | 7 +++---- substrate/frame/staking/src/lib.rs | 8 ++------ substrate/frame/staking/src/pallet/mod.rs | 11 ++++------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index a1bb9cdd2438..53fb499cb7b0 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -3,14 +3,13 @@ use frame_support::traits::{ fungible::{ hold::{Balanced as FunHoldBalanced, Inspect as FunHoldInspect, Mutate as FunHoldMutate}, - Balanced, Inspect as FunInspect, Mutate as FunMutate, + Balanced, Inspect as FunInspect, }, - tokens::{Fortitude, Precision}, - Currency, Imbalance, InspectLockableCurrency, LockableCurrency, + tokens::Precision, }; use sp_runtime::{traits::Zero, DispatchResult}; -use crate::{BalanceOf, Config, Error, HoldReason, NegativeImbalanceOf, PositiveImbalanceOf}; +use crate::{BalanceOf, Config, HoldReason, NegativeImbalanceOf, PositiveImbalanceOf}; /// Existential deposit for the chain. pub fn existential_deposit() -> BalanceOf { diff --git a/substrate/frame/staking/src/lib.rs b/substrate/frame/staking/src/lib.rs index f8a708152866..73f08f9d0be3 100644 --- a/substrate/frame/staking/src/lib.rs +++ b/substrate/frame/staking/src/lib.rs @@ -312,11 +312,8 @@ use codec::{Decode, Encode, HasCompact, MaxEncodedLen}; use frame_support::{ defensive, defensive_assert, traits::{ - tokens::{ - fungible::{Credit, Debt, Inspect, InspectHold}, - Fortitude, Preservation, - }, - ConstU32, Currency, Defensive, DefensiveMax, DefensiveSaturating, Get, LockIdentifier, + tokens::fungible::{Credit, Debt}, + ConstU32, Defensive, DefensiveMax, DefensiveSaturating, Get, }, weights::Weight, BoundedVec, CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, @@ -337,7 +334,6 @@ pub use weights::WeightInfo; pub use pallet::{pallet::*, UseNominatorsAndValidatorsMap, UseValidatorsMap}; -pub(crate) const STAKING_ID: LockIdentifier = *b"staking "; pub(crate) const LOG_TARGET: &str = "runtime::staking"; // syntactic sugar for logging. diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index 19f8a73cfbb7..715b6b710254 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -26,14 +26,11 @@ use frame_support::{ pallet_prelude::*, traits::{ fungible::{ - hold::{ - Balanced as FunHoldBalanced, Inspect as FunHoldInspect, Mutate as FunHoldMutate, - }, - Balanced, Inspect as FunInspect, Mutate as FunMutate, + hold::{Balanced as FunHoldBalanced, Mutate as FunHoldMutate}, + Mutate as FunMutate, }, - tokens::Precision, - Defensive, DefensiveSaturating, EnsureOrigin, EstimateNextNewSession, Get, - InspectLockableCurrency, LockableCurrency, OnUnbalanced, UnixTime, + Defensive, DefensiveSaturating, EnsureOrigin, EstimateNextNewSession, Get, OnUnbalanced, + UnixTime, }, weights::Weight, BoundedVec, From e6c705e0c24c315ddfb149ee0445f79a3a1c00e8 Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 27 Aug 2024 15:13:00 +0200 Subject: [PATCH 06/56] missing import --- substrate/frame/staking/src/asset.rs | 2 +- substrate/frame/staking/src/mock.rs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 2822c05dadea..fb9676af96a0 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -21,7 +21,7 @@ use frame_support::traits::{ fungible::{ hold::{Balanced as FunHoldBalanced, Inspect as FunHoldInspect, Mutate as FunHoldMutate}, - Balanced, Inspect as FunInspect, + Balanced, Inspect as FunInspect, Mutate as FunMutate, }, tokens::Precision, }; diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index e952d91c9c28..64f3011ea3c4 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -25,9 +25,8 @@ use frame_election_provider_support::{ use frame_support::{ assert_ok, derive_impl, ord_parameter_types, parameter_types, traits::{ - fungible::{Inspect, Mutate, MutateHold}, - ConstU64, Currency, EitherOfDiverse, FindAuthor, Get, Hooks, Imbalance, LockableCurrency, - OnUnbalanced, OneSessionHandler, WithdrawReasons, + ConstU64, EitherOfDiverse, FindAuthor, Get, Hooks, Imbalance, + OnUnbalanced, OneSessionHandler, }, weights::constants::RocksDbWeight, }; From c4a9c9d95b1e27330da7d277c86a89f877310926 Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 27 Aug 2024 15:23:37 +0200 Subject: [PATCH 07/56] conditional import of fun mutate --- substrate/frame/staking/src/asset.rs | 4 +++- substrate/frame/staking/src/mock.rs | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index fb9676af96a0..eaefd6893cb7 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -21,7 +21,7 @@ use frame_support::traits::{ fungible::{ hold::{Balanced as FunHoldBalanced, Inspect as FunHoldInspect, Mutate as FunHoldMutate}, - Balanced, Inspect as FunInspect, Mutate as FunMutate, + Balanced, Inspect as FunInspect, }, tokens::Precision, }; @@ -66,6 +66,8 @@ pub fn staked(who: &T::AccountId) -> BalanceOf { /// Should only be used with test. #[cfg(any(test, feature = "runtime-benchmarks"))] pub fn set_stakeable_balance(who: &T::AccountId, value: BalanceOf) { + use frame_support::traits::fungible::Mutate; + let reserved_balance = staked::(who); if reserved_balance < value { let _ = T::Currency::set_balance(who, value - reserved_balance); diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index 64f3011ea3c4..61602253d3a1 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -25,8 +25,8 @@ use frame_election_provider_support::{ use frame_support::{ assert_ok, derive_impl, ord_parameter_types, parameter_types, traits::{ - ConstU64, EitherOfDiverse, FindAuthor, Get, Hooks, Imbalance, - OnUnbalanced, OneSessionHandler, + ConstU64, EitherOfDiverse, FindAuthor, Get, Hooks, Imbalance, OnUnbalanced, + OneSessionHandler, }, weights::constants::RocksDbWeight, }; From e5b80ce4c0aa5acdf9edb980a6a0569aebe8689c Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 28 Aug 2024 15:09:16 +0200 Subject: [PATCH 08/56] fix event count with fungibles --- substrate/frame/offences/benchmarking/src/inner.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/substrate/frame/offences/benchmarking/src/inner.rs b/substrate/frame/offences/benchmarking/src/inner.rs index ed61b59bb46a..73b300a4c441 100644 --- a/substrate/frame/offences/benchmarking/src/inner.rs +++ b/substrate/frame/offences/benchmarking/src/inner.rs @@ -204,9 +204,8 @@ benchmarks! { } verify { // make sure that all slashes have been applied - // (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 * (n + 1) as usize + 3); + // deposit to reporter + reporter account endowed. + assert_eq!(System::::read_events_for_pallet::>().len(), 2); // (n nominators + one validator) * slashed + Slash Reported assert_eq!(System::::read_events_for_pallet::>().len(), 1 * (n + 1) as usize + 1); // offence @@ -240,9 +239,8 @@ benchmarks! { } verify { // make sure that all slashes have been applied - // (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 * (n + 1) as usize + 3); + // deposit to reporter + reporter account endowed. + assert_eq!(System::::read_events_for_pallet::>().len(), 2); // (n nominators + one validator) * slashed + Slash Reported assert_eq!(System::::read_events_for_pallet::>().len(), 1 * (n + 1) as usize + 1); // offence From 0ec6a3baf2017b3a1db383de17881c1c3cb9f536 Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 28 Aug 2024 16:34:48 +0200 Subject: [PATCH 09/56] fix failing tests --- .../frame/delegated-staking/src/tests.rs | 2 +- substrate/frame/fast-unstake/src/tests.rs | 21 ++++++++++++------- .../frame/nomination-pools/src/adapter.rs | 3 ++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/substrate/frame/delegated-staking/src/tests.rs b/substrate/frame/delegated-staking/src/tests.rs index 2c965e18b1b3..b7b82a43771e 100644 --- a/substrate/frame/delegated-staking/src/tests.rs +++ b/substrate/frame/delegated-staking/src/tests.rs @@ -676,7 +676,7 @@ mod staking_integration { // in equal parts. lets try to migrate this nominator into delegate based stake. // all balance currently is in 200 - assert_eq!(Balances::free_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 diff --git a/substrate/frame/fast-unstake/src/tests.rs b/substrate/frame/fast-unstake/src/tests.rs index 77128872f285..3e4eb7915769 100644 --- a/substrate/frame/fast-unstake/src/tests.rs +++ b/substrate/frame/fast-unstake/src/tests.rs @@ -137,15 +137,16 @@ fn deregister_works() { ExtBuilder::default().build_and_execute(|| { ErasToCheckPerBlock::::put(1); - assert_eq!(::Currency::reserved_balance(&1), 0); + // reserved balance prior to registering for fast unstake. + let pre_reserved = ::Currency::reserved_balance(&1); // Controller account registers for fast unstake. assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1))); - assert_eq!(::Currency::reserved_balance(&1), Deposit::get()); + assert_eq!(::Currency::reserved_balance(&1) - pre_reserved, Deposit::get()); // Controller then changes mind and deregisters. assert_ok!(FastUnstake::deregister(RuntimeOrigin::signed(1))); - assert_eq!(::Currency::reserved_balance(&1), 0); + assert_eq!(::Currency::reserved_balance(&1) - pre_reserved, 0); // Ensure stash no longer exists in the queue. assert_eq!(Queue::::get(1), None); @@ -243,15 +244,18 @@ mod on_idle { CurrentEra::::put(BondingDuration::get()); // given - assert_eq!(::Currency::reserved_balance(&1), 0); - + // reserved balance prior to registering for fast unstake. + let pre_reserved = ::Currency::reserved_balance(&1); assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1))); assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(3))); assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(5))); assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(7))); assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(9))); - assert_eq!(::Currency::reserved_balance(&1), Deposit::get()); + assert_eq!( + ::Currency::reserved_balance(&1) - pre_reserved, + Deposit::get() + ); assert_eq!(Queue::::count(), 5); assert_eq!(Head::::get(), None); @@ -279,6 +283,9 @@ mod on_idle { // when next_block(true); + // pre_reserve may change due to unstaked amount. + let pre_reserved = ::Currency::reserved_balance(&1); + // then assert_eq!( Head::::get(), @@ -289,7 +296,7 @@ mod on_idle { ); assert_eq!(Queue::::count(), 3); - assert_eq!(::Currency::reserved_balance(&1), 0); + assert_eq!(::Currency::reserved_balance(&1) - pre_reserved, 0); assert_eq!( fast_unstake_events_since_last_call(), diff --git a/substrate/frame/nomination-pools/src/adapter.rs b/substrate/frame/nomination-pools/src/adapter.rs index 272b3b60612b..bdd24ffc26e5 100644 --- a/substrate/frame/nomination-pools/src/adapter.rs +++ b/substrate/frame/nomination-pools/src/adapter.rs @@ -262,7 +262,8 @@ impl, AccountId = T: pool_account: Pool, _: Member, ) -> BalanceOf { - T::Currency::balance(&pool_account.0).saturating_sub(Self::active_stake(pool_account)) + // free/liquid balance of the pool account. + T::Currency::balance(&pool_account.0) } fn total_balance(pool_account: Pool) -> Option> { From 0188158d470386f4d80f4b22b6432e1906c84eba Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 28 Aug 2024 18:16:44 +0200 Subject: [PATCH 10/56] best effort while minting money --- substrate/frame/staking/src/asset.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index eaefd6893cb7..e64a0a77e55e 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -115,14 +115,14 @@ pub fn mint_existing( who: &T::AccountId, value: BalanceOf, ) -> Option> { - T::Currency::deposit(who, value, Precision::Exact).ok() + T::Currency::deposit(who, value, Precision::BestEffort).ok() } /// Mint reward and create account for `who` if it does not exist. /// /// This does not increase the total issuance. pub fn mint_creating(who: &T::AccountId, value: BalanceOf) -> PositiveImbalanceOf { - T::Currency::deposit(who, value, Precision::Exact).unwrap_or_default() + T::Currency::deposit(who, value, Precision::BestEffort).unwrap_or_default() } /// Deposit newly issued or slashed `value` into `who`. From 0dc0ca412e9ce95a20038c23a769f3edfda5a27c Mon Sep 17 00:00:00 2001 From: Ankan Date: Mon, 2 Sep 2024 01:06:01 +0200 Subject: [PATCH 11/56] fix ed bug while minting --- substrate/frame/staking/src/asset.rs | 9 ++++++--- .../frame/support/src/traits/tokens/fungible/regular.rs | 5 ++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index e64a0a77e55e..59cef415905d 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -108,17 +108,20 @@ pub fn slash( T::Currency::slash(&HoldReason::Staking.into(), who, value) } -/// Mint reward into an existing account. +/// Mint `value` into an existing account. /// /// This does not increase the total issuance. pub fn mint_existing( who: &T::AccountId, value: BalanceOf, ) -> Option> { - T::Currency::deposit(who, value, Precision::BestEffort).ok() + // since the account already exists, we mint exact value even if value is below ED. + T::Currency::deposit(who, value, Precision::Exact).ok() } -/// Mint reward and create account for `who` if it does not exist. +/// Mint `value` and create account for `who` if it does not exist. +/// +/// If value is below existential deposit, the account is not created. /// /// This does not increase the total issuance. pub fn mint_creating(who: &T::AccountId, value: BalanceOf) -> PositiveImbalanceOf { diff --git a/substrate/frame/support/src/traits/tokens/fungible/regular.rs b/substrate/frame/support/src/traits/tokens/fungible/regular.rs index 54a04444649d..c54b5e4c8c68 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/regular.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/regular.rs @@ -213,7 +213,10 @@ pub trait Unbalanced: Inspect { } else { old_balance.checked_add(&amount).ok_or(ArithmeticError::Overflow)? }; - if new_balance < Self::minimum_balance() { + // FIXME(ank4n): add test for this case + // look at total balance to ensure ED is respected + let new_total_balance = amount.saturating_add(Self::total_balance(who)); + if new_total_balance < Self::minimum_balance() { // Attempt to increase from 0 to below minimum -> stays at zero. if let BestEffort = precision { Ok(Default::default()) From f0ef9d171ff04b4767b1d6250cdaa6130b4c0019 Mon Sep 17 00:00:00 2001 From: Ankan Date: Mon, 2 Sep 2024 22:05:05 +0200 Subject: [PATCH 12/56] release/dec consumer before dec providers --- substrate/frame/staking/src/asset.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 59cef415905d..3c333934f4f5 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -94,8 +94,9 @@ pub fn update_stake(who: &T::AccountId, amount: BalanceOf) -> Disp } pub fn kill_stake(who: &T::AccountId) -> DispatchResult { + T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort).map(|_| ())?; let _ = frame_system::Pallet::::dec_providers(who); - T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort).map(|_| ()) + Ok(()) } /// Slash the value from `who`. From ca81fea267010114d7c4256d1934b5a3b212813d Mon Sep 17 00:00:00 2001 From: Ankan Date: Mon, 2 Sep 2024 23:38:20 +0200 Subject: [PATCH 13/56] works, but hacky --- substrate/frame/staking/src/asset.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 3c333934f4f5..533675964e3e 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -77,7 +77,7 @@ pub fn set_stakeable_balance(who: &T::AccountId, value: BalanceOf) let _ = T::Currency::set_balance(who, Zero::zero()); } - assert!(total_balance::(who) == value); + assert_eq!(total_balance::(who), value); } /// Update `amount` at stake for `who`. @@ -85,17 +85,22 @@ pub fn set_stakeable_balance(who: &T::AccountId, value: BalanceOf) /// 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 { - // if first stake, inc provider. + // if first stake, inc provider. This allows us to stake all free balance. if staked::(who) == Zero::zero() && amount > Zero::zero() { frame_system::Pallet::::inc_providers(who); } + // FIXME(ank4n) hacky, find a better way. + // if all amount is getting staked, inc an extra provider that would get decremented on hold. + if stakeable_balance::(who) == amount { + frame_system::Pallet::::inc_providers(who); + } + T::Currency::set_on_hold(&HoldReason::Staking.into(), who, amount) } pub fn kill_stake(who: &T::AccountId) -> DispatchResult { T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort).map(|_| ())?; - let _ = frame_system::Pallet::::dec_providers(who); Ok(()) } From b15efb616344266c8d69728114258f88366cc939 Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 3 Sep 2024 00:24:36 +0200 Subject: [PATCH 14/56] fix provider --- substrate/frame/staking/src/asset.rs | 22 ++++++++++++------- substrate/frame/staking/src/tests.rs | 3 ++- .../src/traits/tokens/fungible/regular.rs | 2 +- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 533675964e3e..422d5d1243b6 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -24,6 +24,7 @@ use frame_support::traits::{ Balanced, Inspect as FunInspect, }, tokens::Precision, + Defensive, }; use sp_runtime::{traits::Zero, DispatchResult}; @@ -60,18 +61,19 @@ pub fn staked(who: &T::AccountId) -> BalanceOf { /// Set balance that can be staked for `who`. /// -/// If `value` is less than already staked, the difference is amount is unlocked. Otherwise, -/// the difference is added to free balance. +/// `Value` must be greater than already staked plus existential deposit for free balance. /// /// Should only be used with test. #[cfg(any(test, feature = "runtime-benchmarks"))] pub fn set_stakeable_balance(who: &T::AccountId, value: BalanceOf) { use frame_support::traits::fungible::Mutate; - let reserved_balance = staked::(who); - if reserved_balance < value { - let _ = T::Currency::set_balance(who, value - reserved_balance); + let staked_balance = staked::(who); + // if value is greater than staked balance, we need to increase the free balance. + if value > staked_balance { + let _ = T::Currency::set_balance(who, value - staked_balance); } else { + // else reduce the staked balance. update_stake::(who, value).expect("can remove from what is staked"); // burn all free let _ = T::Currency::set_balance(who, Zero::zero()); @@ -90,8 +92,9 @@ pub fn update_stake(who: &T::AccountId, amount: BalanceOf) -> Disp frame_system::Pallet::::inc_providers(who); } - // FIXME(ank4n) hacky, find a better way. - // if all amount is getting staked, inc an extra provider that would get decremented on hold. + // Hacky but this allows us to replicate the old currency behaviour of allowing free balance to + // go below ED if an account transfers funds. + // FIXME(ank4n): probably not needed to replicate old behaviour and can be refactored. if stakeable_balance::(who) == amount { frame_system::Pallet::::inc_providers(who); } @@ -100,7 +103,10 @@ pub fn update_stake(who: &T::AccountId, amount: BalanceOf) -> Disp } pub fn kill_stake(who: &T::AccountId) -> DispatchResult { - T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort).map(|_| ())?; + T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort) + .map(|_| ())?; + // dec provider that we incremented for a new stake. + let _ = frame_system::Pallet::::dec_providers(who).defensive(); Ok(()) } diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 6a844be32509..bfc674ec704e 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -1021,11 +1021,12 @@ 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 can transfer at most 1000 + // Confirm account 21 cannot transfer more than 1000 assert_noop!( Balances::transfer_allow_death(RuntimeOrigin::signed(21), 21, 1001), TokenError::FundsUnavailable, ); + // 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)); }); } diff --git a/substrate/frame/support/src/traits/tokens/fungible/regular.rs b/substrate/frame/support/src/traits/tokens/fungible/regular.rs index c54b5e4c8c68..29f907ce2654 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/regular.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/regular.rs @@ -216,7 +216,7 @@ pub trait Unbalanced: Inspect { // FIXME(ank4n): add test for this case // look at total balance to ensure ED is respected let new_total_balance = amount.saturating_add(Self::total_balance(who)); - if new_total_balance < Self::minimum_balance() { + if new_total_balance < Self::minimum_balance() { // Attempt to increase from 0 to below minimum -> stays at zero. if let BestEffort = precision { Ok(Default::default()) From b1f313bffe1ef6b26390c6f5cdfbf44c7be93470 Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 3 Sep 2024 02:07:08 +0200 Subject: [PATCH 15/56] remove the hack provider logic --- substrate/frame/staking/src/asset.rs | 7 ------- substrate/frame/staking/src/benchmarking.rs | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 422d5d1243b6..7a4c3a39d5a6 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -92,13 +92,6 @@ pub fn update_stake(who: &T::AccountId, amount: BalanceOf) -> Disp frame_system::Pallet::::inc_providers(who); } - // Hacky but this allows us to replicate the old currency behaviour of allowing free balance to - // go below ED if an account transfers funds. - // FIXME(ank4n): probably not needed to replicate old behaviour and can be refactored. - if stakeable_balance::(who) == amount { - frame_system::Pallet::::inc_providers(who); - } - T::Currency::set_on_hold(&HoldReason::Staking.into(), who, amount) } diff --git a/substrate/frame/staking/src/benchmarking.rs b/substrate/frame/staking/src/benchmarking.rs index a25085a18036..97a76932f1ba 100644 --- a/substrate/frame/staking/src/benchmarking.rs +++ b/substrate/frame/staking/src/benchmarking.rs @@ -249,7 +249,7 @@ benchmarks! { let original_bonded: BalanceOf = Ledger::::get(&controller).map(|l| l.active).ok_or("ledger not created after")?; - let _ = asset::mint_existing::(&stash, max_additional).unwrap(); + let _ = asset::mint_existing::(&stash, max_additional + asset::existential_deposit::()).unwrap(); whitelist_account!(stash); }: _(RawOrigin::Signed(stash), max_additional) From 32be80c03f3b0a22a7519208674054b5339d5b54 Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 3 Sep 2024 23:57:06 +0200 Subject: [PATCH 16/56] verify only for tests --- substrate/frame/offences/benchmarking/src/inner.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/substrate/frame/offences/benchmarking/src/inner.rs b/substrate/frame/offences/benchmarking/src/inner.rs index 73b300a4c441..4adc49c39c7f 100644 --- a/substrate/frame/offences/benchmarking/src/inner.rs +++ b/substrate/frame/offences/benchmarking/src/inner.rs @@ -203,6 +203,8 @@ benchmarks! { let _ = Offences::::report_offence(reporters, offence); } verify { + #[cfg(test)] + { // make sure that all slashes have been applied // deposit to reporter + reporter account endowed. assert_eq!(System::::read_events_for_pallet::>().len(), 2); @@ -212,6 +214,7 @@ benchmarks! { assert_eq!(System::::read_events_for_pallet::().len(), 1); // reporter new account assert_eq!(System::::read_events_for_pallet::>().len(), 1); + } } report_offence_babe { @@ -238,6 +241,8 @@ benchmarks! { let _ = Offences::::report_offence(reporters, offence); } verify { + #[cfg(test)] + { // make sure that all slashes have been applied // deposit to reporter + reporter account endowed. assert_eq!(System::::read_events_for_pallet::>().len(), 2); @@ -247,6 +252,7 @@ benchmarks! { assert_eq!(System::::read_events_for_pallet::().len(), 1); // reporter new account assert_eq!(System::::read_events_for_pallet::>().len(), 1); + } } impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); From e0fac32ed7b9a71be0e8ae2bf1d13768c9780793 Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 4 Sep 2024 16:22:14 +0200 Subject: [PATCH 17/56] hacky to pass tests for now --- substrate/frame/staking/src/asset.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 7a4c3a39d5a6..265fcd66eebd 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -99,7 +99,8 @@ pub fn kill_stake(who: &T::AccountId) -> DispatchResult { T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort) .map(|_| ())?; // dec provider that we incremented for a new stake. - let _ = frame_system::Pallet::::dec_providers(who).defensive(); + // fixme(ank4n): fails while slashing? Need to carefully examine consumer and provider changes. + let _ = frame_system::Pallet::::dec_providers(who); Ok(()) } From d74ebd6e27bcf7c6720af7e0a50e3904aa4fdec2 Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 4 Sep 2024 16:55:33 +0200 Subject: [PATCH 18/56] unused import --- substrate/frame/staking/src/asset.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 265fcd66eebd..679adc113587 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -24,7 +24,6 @@ use frame_support::traits::{ Balanced, Inspect as FunInspect, }, tokens::Precision, - Defensive, }; use sp_runtime::{traits::Zero, DispatchResult}; From c5a7730fe1f7a06b22910a483ae1711590232701 Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 4 Sep 2024 17:49:35 +0200 Subject: [PATCH 19/56] staking does not need to inc consumer anymore --- substrate/frame/staking/src/pallet/impls.rs | 5 ----- substrate/frame/staking/src/pallet/mod.rs | 2 -- 2 files changed, 7 deletions(-) diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 797aff003243..d2703801de0a 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -797,8 +797,6 @@ impl Pallet { Self::do_remove_validator(&stash); Self::do_remove_nominator(&stash); - frame_system::Pallet::::dec_consumers(&stash); - Ok(()) } @@ -1938,9 +1936,6 @@ 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, ()); diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index d36714206507..169cd5123b2f 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -1049,8 +1049,6 @@ pub mod pallet { return Err(Error::::InsufficientBond.into()) } - frame_system::Pallet::::inc_consumers(&stash).map_err(|_| Error::::BadState)?; - let stash_balance = asset::stakeable_balance::(&stash); let value = value.min(stash_balance); Self::deposit_event(Event::::Bonded { stash: stash.clone(), amount: value }); From dedecbcebbbf7d2475b0a96d853b3ed6d99c8b0e Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 4 Sep 2024 21:46:52 +0200 Subject: [PATCH 20/56] purge session key when trying to kill stash --- substrate/frame/staking/src/asset.rs | 15 ++++++++++++--- substrate/frame/staking/src/lib.rs | 12 +++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 679adc113587..8a1f0bbb1f49 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -27,7 +27,9 @@ use frame_support::traits::{ }; use sp_runtime::{traits::Zero, DispatchResult}; -use crate::{BalanceOf, Config, HoldReason, NegativeImbalanceOf, PositiveImbalanceOf}; +use crate::{ + BalanceOf, Config, HoldReason, NegativeImbalanceOf, PositiveImbalanceOf, SessionInterface, +}; /// Existential deposit for the chain. pub fn existential_deposit() -> BalanceOf { @@ -97,9 +99,16 @@ pub fn update_stake(who: &T::AccountId, amount: BalanceOf) -> Disp pub fn kill_stake(who: &T::AccountId) -> DispatchResult { T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort) .map(|_| ())?; + + // if can't dec provider, try cleaning up session keys first. + // FIXME(ank4n): may have to update bench. Also add failing test if non session consumers on + // stash. + if !frame_system::Pallet::::can_dec_provider(who) { + T::SessionInterface::purge_keys(who.clone())?; + } + // dec provider that we incremented for a new stake. - // fixme(ank4n): fails while slashing? Need to carefully examine consumer and provider changes. - let _ = frame_system::Pallet::::dec_providers(who); + let _ = frame_system::Pallet::::dec_providers(who)?; Ok(()) } diff --git a/substrate/frame/staking/src/lib.rs b/substrate/frame/staking/src/lib.rs index 73f08f9d0be3..aeaa334b66b3 100644 --- a/substrate/frame/staking/src/lib.rs +++ b/substrate/frame/staking/src/lib.rs @@ -318,11 +318,12 @@ use frame_support::{ weights::Weight, BoundedVec, CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, }; +use frame_system::RawOrigin; use scale_info::TypeInfo; use sp_runtime::{ curve::PiecewiseLinear, traits::{AtLeast32BitUnsigned, Convert, StaticLookup, Zero}, - Perbill, Perquintill, Rounding, RuntimeDebug, Saturating, + DispatchResult, Perbill, Perquintill, Rounding, RuntimeDebug, Saturating, }; use sp_staking::{ offence::{Offence, OffenceError, ReportOffence}, @@ -850,6 +851,8 @@ pub trait SessionInterface { fn validators() -> Vec; /// Prune historical session tries up to but not including the given index. fn prune_historical_up_to(up_to: SessionIndex); + /// Purge session key of the validator. + fn purge_keys(stash: AccountId) -> DispatchResult; } impl SessionInterface<::AccountId> for T @@ -877,6 +880,10 @@ where fn prune_historical_up_to(up_to: SessionIndex) { >::prune_up_to(up_to); } + + fn purge_keys(stash: ::AccountId) -> DispatchResult { + >::purge_keys(RawOrigin::Signed(stash.clone()).into()) + } } impl SessionInterface for () { @@ -889,6 +896,9 @@ impl SessionInterface for () { fn prune_historical_up_to(_: SessionIndex) { () } + fn purge_keys(stash: AccountId) -> DispatchResult { + Ok(()) + } } /// Handler for determining how much of a balance should be paid out on the current era. From bcdb7497c040aad352427f44dfa88852006b3041 Mon Sep 17 00:00:00 2001 From: Ankan Date: Thu, 5 Sep 2024 10:45:44 +0200 Subject: [PATCH 21/56] small updates --- substrate/frame/staking/src/asset.rs | 4 +++- substrate/frame/staking/src/lib.rs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 8a1f0bbb1f49..80a495e1a42b 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -100,10 +100,12 @@ pub fn kill_stake(who: &T::AccountId) -> DispatchResult { T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort) .map(|_| ())?; - // if can't dec provider, try cleaning up session keys first. // FIXME(ank4n): may have to update bench. Also add failing test if non session consumers on // stash. if !frame_system::Pallet::::can_dec_provider(who) { + // The session pallet keeps a consumer reference to validator stash which may block this + // pallet from clearing its provider reference. If the account cannot provide for itself + // (via enough free balance) to keep the session key, we should clean up the session keys. T::SessionInterface::purge_keys(who.clone())?; } diff --git a/substrate/frame/staking/src/lib.rs b/substrate/frame/staking/src/lib.rs index aeaa334b66b3..e6c01948a897 100644 --- a/substrate/frame/staking/src/lib.rs +++ b/substrate/frame/staking/src/lib.rs @@ -896,7 +896,7 @@ impl SessionInterface for () { fn prune_historical_up_to(_: SessionIndex) { () } - fn purge_keys(stash: AccountId) -> DispatchResult { + fn purge_keys(_stash: AccountId) -> DispatchResult { Ok(()) } } From 18928a422b6383bef9d3ccdf1184b7d4332967fe Mon Sep 17 00:00:00 2001 From: Ankan Date: Thu, 5 Sep 2024 11:36:30 +0200 Subject: [PATCH 22/56] kill stake is fallible --- substrate/frame/delegated-staking/src/lib.rs | 2 +- .../test-transfer-stake/src/lib.rs | 6 +++--- substrate/frame/staking/src/pallet/impls.rs | 16 +++++++--------- substrate/frame/staking/src/pallet/mod.rs | 2 ++ substrate/frame/staking/src/tests.rs | 8 ++++---- substrate/primitives/staking/src/lib.rs | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/substrate/frame/delegated-staking/src/lib.rs b/substrate/frame/delegated-staking/src/lib.rs index 7b8d14b0a611..dbb5247436f8 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/nomination-pools/test-transfer-stake/src/lib.rs b/substrate/frame/nomination-pools/test-transfer-stake/src/lib.rs index 28e978bba0e5..8cd4f20d3459 100644 --- a/substrate/frame/nomination-pools/test-transfer-stake/src/lib.rs +++ b/substrate/frame/nomination-pools/test-transfer-stake/src/lib.rs @@ -200,13 +200,13 @@ fn destroy_pool_with_erroneous_consumer() { 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); + // expect consumers on pool account to be 1 (staking hold). + assert_eq!(frame_system::Pallet::::consumers(&POOL1_BONDED), 1); // 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); + assert_eq!(frame_system::Pallet::::consumers(&POOL1_BONDED), 2); // have the pool nominate. assert_ok!(Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3])); diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index d2703801de0a..cd627831f78b 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -34,13 +34,10 @@ use frame_support::{ }; use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin}; use pallet_session::historical; -use sp_runtime::{ - traits::{ - Bounded, CheckedAdd, CheckedSub, Convert, One, SaturatedConversion, Saturating, - StaticLookup, Zero, - }, - ArithmeticError, Perbill, Percent, -}; +use sp_runtime::{traits::{ + Bounded, CheckedAdd, CheckedSub, Convert, One, SaturatedConversion, Saturating, + StaticLookup, Zero, +}, ArithmeticError, Perbill, Percent, DispatchResult}; use sp_staking::{ currency_to_vote::CurrencyToVote, offence::{OffenceDetails, OnOffenceHandler}, @@ -1916,9 +1913,10 @@ impl StakingInterface for Pallet { } impl sp_staking::StakingUnchecked for Pallet { - fn migrate_to_virtual_staker(who: &Self::AccountId) { - let _ = asset::kill_stake::(who).defensive(); + fn migrate_to_virtual_staker(who: &Self::AccountId) -> DispatchResult { + asset::kill_stake::(who)?; VirtualStakers::::insert(who, ()); + Ok(()) } /// Virtually bonds `keyless_who` to `payee` with `value`. diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index 169cd5123b2f..584992db6d4a 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -956,6 +956,8 @@ pub mod pallet { NotEnoughFunds, /// Operation not allowed for virtual stakers. VirtualStakerNotAllowed, + /// Stash could not be reaped as other pallet might depend on it. + CannotReapStash, } #[pallet::hooks] diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index bfc674ec704e..e66a04fe7aae 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -7253,7 +7253,7 @@ mod staking_unchecked { assert_eq!(asset::staked::(&200), 1000); // migrate them to virtual staker - ::migrate_to_virtual_staker(&200); + assert_ok!(::migrate_to_virtual_staker(&200)); // payee needs to be updated to a non-stash account. assert_ok!(::set_payee(&200, &201)); @@ -7280,7 +7280,7 @@ mod staking_unchecked { // 101 is a nominator for 11 assert_eq!(initial_exposure.others.first().unwrap().who, 101); // make 101 a virtual nominator - ::migrate_to_virtual_staker(&101); + assert_ok!(::migrate_to_virtual_staker(&101)); // set payee different to self. assert_ok!(::set_payee(&101, &102)); @@ -7355,7 +7355,7 @@ mod staking_unchecked { // 101 is a nominator for 11 assert_eq!(initial_exposure.others.first().unwrap().who, 101); // make 101 a virtual nominator - ::migrate_to_virtual_staker(&101); + assert_ok!(::migrate_to_virtual_staker(&101)); // set payee different to self. assert_ok!(::set_payee(&101, &102)); @@ -7411,7 +7411,7 @@ mod staking_unchecked { // 333 is corrupted assert_eq!(Staking::inspect_bond_state(&333).unwrap(), LedgerIntegrityState::Corrupted); // migrate to virtual staker. - ::migrate_to_virtual_staker(&333); + assert_ok!(::migrate_to_virtual_staker(&333)); // recover the ledger won't work for virtual staker assert_noop!( diff --git a/substrate/primitives/staking/src/lib.rs b/substrate/primitives/staking/src/lib.rs index 5e94524816a0..22969479d30c 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); + fn migrate_to_virtual_staker(who: &Self::AccountId) -> DispatchResult; /// Book-keep a new bond for `keyless_who` without applying any locks (hence virtual). /// From 6a7001e143c046c4f144c1d35e0ef0be87f36084 Mon Sep 17 00:00:00 2001 From: Ankan Date: Thu, 5 Sep 2024 11:42:10 +0200 Subject: [PATCH 23/56] fail ledger kill if stake cannot be killed --- substrate/frame/staking/src/ledger.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substrate/frame/staking/src/ledger.rs b/substrate/frame/staking/src/ledger.rs index 0a91c6472d20..b2163fbef516 100644 --- a/substrate/frame/staking/src/ledger.rs +++ b/substrate/frame/staking/src/ledger.rs @@ -260,9 +260,9 @@ impl StakingLedger { >::remove(&stash); // kill virtual staker if it exists. - if >::take(&stash).is_none() { + if >::take(&ledger.stash).is_none() { // if not virtual staker, clear locks. - let _ = asset::kill_stake::(&ledger.stash).defensive(); + asset::kill_stake::(&ledger.stash).map_err(|_| Error::::CannotReapStash)?; } Ok(()) From ef54e9ab508d6515b9f67a4674df84002d5d8c69 Mon Sep 17 00:00:00 2001 From: Ankan Date: Thu, 5 Sep 2024 11:47:21 +0200 Subject: [PATCH 24/56] doc fixes --- substrate/frame/staking/src/pallet/impls.rs | 3 ++- substrate/frame/staking/src/pallet/mod.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index cd627831f78b..5a064664b1b5 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -1945,11 +1945,12 @@ 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); + let _ = asset::update_stake::(who, ledger.total).expect("funds must be transferred to stash"); VirtualStakers::::remove(who); } } diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index 584992db6d4a..7738188d0ec2 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -323,7 +323,7 @@ pub mod pallet { /// A reason for placing a hold on funds. #[pallet::composite_enum] pub enum HoldReason { - /// Funds held for stake delegation to another account. + /// Funds on stake by a nominator or a validator. #[codec(index = 0)] Staking, } From 45552096f62cc5965f222ff3c3adc48a425a21c0 Mon Sep 17 00:00:00 2001 From: Ankan Date: Thu, 5 Sep 2024 12:55:52 +0200 Subject: [PATCH 25/56] fmt --- substrate/frame/staking/src/pallet/impls.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 5a064664b1b5..73a457ea8bdd 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -34,10 +34,13 @@ use frame_support::{ }; use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin}; use pallet_session::historical; -use sp_runtime::{traits::{ - Bounded, CheckedAdd, CheckedSub, Convert, One, SaturatedConversion, Saturating, - StaticLookup, Zero, -}, ArithmeticError, Perbill, Percent, DispatchResult}; +use sp_runtime::{ + traits::{ + Bounded, CheckedAdd, CheckedSub, Convert, One, SaturatedConversion, Saturating, + StaticLookup, Zero, + }, + ArithmeticError, DispatchResult, Perbill, Percent, +}; use sp_staking::{ currency_to_vote::CurrencyToVote, offence::{OffenceDetails, OnOffenceHandler}, @@ -1950,7 +1953,8 @@ impl sp_staking::StakingUnchecked for Pallet { 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"); + let _ = asset::update_stake::(who, ledger.total) + .expect("funds must be transferred to stash"); VirtualStakers::::remove(who); } } From 684828abd6cdf889b2a12345bc6afed33ed30d7e Mon Sep 17 00:00:00 2001 From: Ankan Date: Thu, 5 Sep 2024 21:03:53 +0200 Subject: [PATCH 26/56] fix migrate test --- substrate/frame/delegated-staking/src/impls.rs | 2 -- substrate/frame/nomination-pools/benchmarking/src/inner.rs | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/substrate/frame/delegated-staking/src/impls.rs b/substrate/frame/delegated-staking/src/impls.rs index 4e6812dee249..a25efabca339 100644 --- a/substrate/frame/delegated-staking/src/impls.rs +++ b/substrate/frame/delegated-staking/src/impls.rs @@ -136,8 +136,6 @@ impl DelegationMigrator for Pallet { ); >::remove(&delegator); }); - - T::CoreStaking::migrate_to_direct_staker(&agent.get()); } } diff --git a/substrate/frame/nomination-pools/benchmarking/src/inner.rs b/substrate/frame/nomination-pools/benchmarking/src/inner.rs index 2a4559425111..b0c8f3655a50 100644 --- a/substrate/frame/nomination-pools/benchmarking/src/inner.rs +++ b/substrate/frame/nomination-pools/benchmarking/src/inner.rs @@ -41,7 +41,7 @@ use sp_runtime::{ traits::{Bounded, StaticLookup, Zero}, Perbill, }; -use sp_staking::EraIndex; +use sp_staking::{EraIndex, StakingUnchecked}; // `frame_benchmarking::benchmarks!` macro needs this use pallet_nomination_pools::Call; @@ -131,6 +131,8 @@ fn migrate_to_transfer_stake(pool_id: PoolId) { ) .expect("member should have enough balance to transfer"); }); + + pallet_staking::Pallet::::migrate_to_direct_staker(&pool_acc); } fn vote_to_balance( From 6d94601ddab5d5d571f8f09dac9f188aacf0ff13 Mon Sep 17 00:00:00 2001 From: Ankan Date: Fri, 6 Sep 2024 13:43:09 +0200 Subject: [PATCH 27/56] rename agent kill function --- substrate/frame/delegated-staking/src/impls.rs | 2 +- substrate/frame/nomination-pools/src/adapter.rs | 2 +- substrate/primitives/staking/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/substrate/frame/delegated-staking/src/impls.rs b/substrate/frame/delegated-staking/src/impls.rs index a25efabca339..a443df7b20f5 100644 --- a/substrate/frame/delegated-staking/src/impls.rs +++ b/substrate/frame/delegated-staking/src/impls.rs @@ -124,7 +124,7 @@ impl DelegationMigrator for Pallet { /// Only used for testing. #[cfg(feature = "runtime-benchmarks")] - fn migrate_to_direct_staker(agent: Agent) { + fn force_kill_agent(agent: Agent) { >::remove(agent.clone().get()); >::iter() .filter(|(_, delegation)| delegation.agent == agent.clone().get()) diff --git a/substrate/frame/nomination-pools/src/adapter.rs b/substrate/frame/nomination-pools/src/adapter.rs index bdd24ffc26e5..95694943271a 100644 --- a/substrate/frame/nomination-pools/src/adapter.rs +++ b/substrate/frame/nomination-pools/src/adapter.rs @@ -461,6 +461,6 @@ impl< #[cfg(feature = "runtime-benchmarks")] fn remove_as_agent(pool: Pool) { - Delegation::migrate_to_direct_staker(pool.into()) + Delegation::force_kill_agent(pool.into()) } } diff --git a/substrate/primitives/staking/src/lib.rs b/substrate/primitives/staking/src/lib.rs index 22969479d30c..8e23c6800a9d 100644 --- a/substrate/primitives/staking/src/lib.rs +++ b/substrate/primitives/staking/src/lib.rs @@ -619,7 +619,7 @@ pub trait DelegationMigrator { /// /// Also removed from [`StakingUnchecked`] as a Virtual Staker. Useful for testing. #[cfg(feature = "runtime-benchmarks")] - fn migrate_to_direct_staker(agent: Agent); + fn force_kill_agent(agent: Agent); } sp_core::generate_feature_enabled_macro!(runtime_benchmarks_enabled, feature = "runtime-benchmarks", $); From a3267afe2ff87dea85311209512d86dde331ab85 Mon Sep 17 00:00:00 2001 From: Ankan Date: Fri, 6 Sep 2024 13:51:46 +0200 Subject: [PATCH 28/56] small edits --- substrate/frame/staking/src/asset.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 80a495e1a42b..9d8c48c2d7d6 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -96,6 +96,9 @@ pub fn update_stake(who: &T::AccountId, amount: BalanceOf) -> Disp T::Currency::set_on_hold(&HoldReason::Staking.into(), who, amount) } +/// Release all staked amount to `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(|_| ())?; @@ -139,7 +142,7 @@ pub fn mint_existing( /// /// If value is below existential deposit, the account is not created. /// -/// This does not increase the total issuance. +/// Note: 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() } From dc4a9a4e1f14b1165cdd26b71553e370a8669871 Mon Sep 17 00:00:00 2001 From: Ankan Date: Fri, 6 Sep 2024 13:55:59 +0200 Subject: [PATCH 29/56] fmt --- .../frame/offences/benchmarking/src/inner.rs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/substrate/frame/offences/benchmarking/src/inner.rs b/substrate/frame/offences/benchmarking/src/inner.rs index 4adc49c39c7f..9836a6104374 100644 --- a/substrate/frame/offences/benchmarking/src/inner.rs +++ b/substrate/frame/offences/benchmarking/src/inner.rs @@ -205,15 +205,15 @@ benchmarks! { verify { #[cfg(test)] { - // 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 + Slash Reported - assert_eq!(System::::read_events_for_pallet::>().len(), 1 * (n + 1) as usize + 1); - // offence - assert_eq!(System::::read_events_for_pallet::().len(), 1); - // reporter new account - assert_eq!(System::::read_events_for_pallet::>().len(), 1); + // 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 + Slash Reported + assert_eq!(System::::read_events_for_pallet::>().len(), 1 * (n + 1) as usize + 1); + // offence + assert_eq!(System::::read_events_for_pallet::().len(), 1); + // reporter new account + assert_eq!(System::::read_events_for_pallet::>().len(), 1); } } @@ -243,15 +243,15 @@ benchmarks! { verify { #[cfg(test)] { - // 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 + Slash Reported - assert_eq!(System::::read_events_for_pallet::>().len(), 1 * (n + 1) as usize + 1); - // offence - assert_eq!(System::::read_events_for_pallet::().len(), 1); - // reporter new account - assert_eq!(System::::read_events_for_pallet::>().len(), 1); + // 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 + Slash Reported + assert_eq!(System::::read_events_for_pallet::>().len(), 1 * (n + 1) as usize + 1); + // offence + assert_eq!(System::::read_events_for_pallet::().len(), 1); + // reporter new account + assert_eq!(System::::read_events_for_pallet::>().len(), 1); } } From 9570a61841f9a388c916c917d2afa5ba97d1cd40 Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 10 Sep 2024 11:21:34 +0200 Subject: [PATCH 30/56] remove provider inc in pallet-delegated-staking --- substrate/frame/delegated-staking/src/tests.rs | 9 +++++---- substrate/frame/delegated-staking/src/types.rs | 6 ------ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/substrate/frame/delegated-staking/src/tests.rs b/substrate/frame/delegated-staking/src/tests.rs index b7b82a43771e..ccec495efd1e 100644 --- a/substrate/frame/delegated-staking/src/tests.rs +++ b/substrate/frame/delegated-staking/src/tests.rs @@ -671,6 +671,8 @@ mod staking_integration { )); assert_ok!(Staking::nominate(RuntimeOrigin::signed(agent), vec![GENESIS_VALIDATOR],)); let init_stake = Staking::stake(&agent).unwrap(); + // agent has an extra provider now added by CoreStaking. + assert_eq!(System::providers(&agent), 2); // 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. @@ -685,8 +687,9 @@ mod staking_integration { DelegatedStaking::generate_proxy_delegator(Agent::from(agent)).get(); assert_ok!(DelegatedStaking::migrate_to_agent(RawOrigin::Signed(agent).into(), 201)); - // after migration, funds are moved to proxy delegator, still a provider exists. - assert_eq!(System::providers(&agent), 1); + // after migration, no provider left since free balance is 0 and staking pallet released + // all funds. + assert_eq!(System::providers(&agent), 0); 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); @@ -798,8 +801,6 @@ 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 a78aa3f55906..14f49466f0e2 100644 --- a/substrate/frame/delegated-staking/src/types.rs +++ b/substrate/frame/delegated-staking/src/types.rs @@ -131,10 +131,6 @@ 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) } @@ -142,8 +138,6 @@ 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`. From 0e7e8d54970e90a4348fd537b2647161095f311a Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 11 Sep 2024 21:09:31 +0200 Subject: [PATCH 31/56] add migrate function to staking --- polkadot/runtime/westend/src/tests.rs | 28 +++++++++-------- substrate/frame/staking/src/pallet/impls.rs | 33 +++++++++++++++++++++ 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs index dc8103ab52c4..8f61943182d3 100644 --- a/polkadot/runtime/westend/src/tests.rs +++ b/polkadot/runtime/westend/src/tests.rs @@ -149,25 +149,27 @@ 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() }, - OnlineConfig { - transport, - state_snapshot: Some(state_snapshot), - pallets: vec![ - "staking".into(), - "system".into(), - "balances".into(), - "nomination-pools".into(), - "delegated-staking".into(), - ], - ..Default::default() - }, + online_config, ) } else { - Mode::Online(OnlineConfig { transport, ..Default::default() }) + Mode::Online(online_config) }) .build() .await diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 73a457ea8bdd..c25f16663900 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -1159,6 +1159,39 @@ impl Pallet { ) -> Exposure> { EraInfo::::get_full_exposure(era, account) } + + pub fn migrate_lock_to_hold(stash: &T::AccountId) -> DispatchResult + where + OldCurrency: frame_support::traits::InspectLockableCurrency, + BalanceOf: From, + { + // use frame_support::traits::InspectLockableCurrency; + let ledger = Self::ledger(Stash(stash.clone()))?; + + const LOCK_ID: frame_support::traits::LockIdentifier = *b"staking "; + let locked: BalanceOf = OldCurrency::balance_locked(LOCK_ID, stash).into(); + let max_hold = asset::stakeable_balance::(&stash); + if max_hold >= locked { + // this is great. easy job for us. + // just hold asset. + asset::update_stake::(&stash, locked)?; + } else { + let unsafe_withdraw = locked.saturating_sub(max_hold); + log::info!(target: "remote_test", "unsafe_withdraw: {:?} {:?}", stash, unsafe_withdraw); + + // we ignore if active is 0. This amount will get unlocked anyways in the future. + StakingLedger { + total: max_hold, + active: ledger.active.saturating_sub(unsafe_withdraw), + // we are not changing the stash, so we can keep the stash. + ..ledger + } + .update()?; + } + + frame_system::Pallet::::dec_consumers(&stash); + Ok(()) + } } impl Pallet { From 7fad8173b3d6c824133381c4f7a42a5f29104eec Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 11 Sep 2024 22:14:20 +0200 Subject: [PATCH 32/56] remote test --- polkadot/runtime/westend/src/tests.rs | 60 +++++++++++++++++++++ substrate/frame/staking/src/pallet/impls.rs | 11 ++-- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs index 8f61943182d3..e6f8eb55ac88 100644 --- a/polkadot/runtime/westend/src/tests.rs +++ b/polkadot/runtime/westend/src/tests.rs @@ -237,4 +237,64 @@ 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; + } + use frame_support::assert_ok; + sp_tracing::try_init_simple(); + + 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()], + ..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; + // iterate over all pools + pallet_staking::Ledger::::iter_values().for_each(|ledger| { + match pallet_staking::Pallet::::migrate_lock_to_hold::(&ledger.stash) { + Ok(_) => { + 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: {}", + success, + err, + ); + }); + } } diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index c25f16663900..574fb565063f 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -1165,9 +1165,13 @@ impl Pallet { OldCurrency: frame_support::traits::InspectLockableCurrency, BalanceOf: From, { - // use frame_support::traits::InspectLockableCurrency; - let ledger = Self::ledger(Stash(stash.clone()))?; + if Self::is_virtual_staker(stash) { + // we don't need to do anything for virtual stakers since their funds are not locked by + // this pallet. + return Ok(()) + } + let ledger = Self::ledger(Stash(stash.clone()))?; const LOCK_ID: frame_support::traits::LockIdentifier = *b"staking "; let locked: BalanceOf = OldCurrency::balance_locked(LOCK_ID, stash).into(); let max_hold = asset::stakeable_balance::(&stash); @@ -1176,8 +1180,9 @@ impl Pallet { // just hold asset. asset::update_stake::(&stash, locked)?; } else { + let ed = asset::existential_deposit::(); let unsafe_withdraw = locked.saturating_sub(max_hold); - log::info!(target: "remote_test", "unsafe_withdraw: {:?} {:?}", stash, unsafe_withdraw); + log::info!(target: "remote_test", "unsafe_withdraw from stash: {:?}, value {:?}, active {:?}", stash, unsafe_withdraw/ed, ledger.active/ed); // we ignore if active is 0. This amount will get unlocked anyways in the future. StakingLedger { From bb7b8a089f5c4b0e5d7ecf5450a25d8c3f0f82b2 Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 11 Sep 2024 22:14:44 +0200 Subject: [PATCH 33/56] fmt --- polkadot/runtime/westend/src/tests.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs index e6f8eb55ac88..c7a08f02bc8a 100644 --- a/polkadot/runtime/westend/src/tests.rs +++ b/polkadot/runtime/westend/src/tests.rs @@ -278,14 +278,16 @@ mod remote_tests { let mut err = 0; // iterate over all pools pallet_staking::Ledger::::iter_values().for_each(|ledger| { - match pallet_staking::Pallet::::migrate_lock_to_hold::(&ledger.stash) { + match pallet_staking::Pallet::::migrate_lock_to_hold::( + &ledger.stash, + ) { Ok(_) => { success += 1; - } + }, Err(e) => { log::error!(target: "remote_test", "Error migrating {:?}: {:?}", ledger.stash, e); err += 1; - } + }, } }); From 7bc708630c7606b341bb5a1f11814a5a98bafe67 Mon Sep 17 00:00:00 2001 From: Ankan Date: Fri, 13 Sep 2024 15:38:37 +0200 Subject: [PATCH 34/56] add OldCurrency to runtime configs --- polkadot/runtime/test-runtime/src/lib.rs | 1 + polkadot/runtime/westend/src/lib.rs | 1 + substrate/bin/node/runtime/src/lib.rs | 1 + substrate/frame/babe/src/mock.rs | 1 + substrate/frame/beefy/src/mock.rs | 1 + substrate/frame/delegated-staking/src/mock.rs | 1 + .../test-staking-e2e/src/mock.rs | 1 + substrate/frame/fast-unstake/src/mock.rs | 1 + substrate/frame/grandpa/src/mock.rs | 1 + .../frame/nomination-pools/benchmarking/src/mock.rs | 1 + .../nomination-pools/test-delegate-stake/src/mock.rs | 1 + .../nomination-pools/test-transfer-stake/src/mock.rs | 1 + substrate/frame/offences/benchmarking/src/mock.rs | 1 + substrate/frame/root-offences/src/mock.rs | 1 + substrate/frame/session/benchmarking/src/mock.rs | 1 + substrate/frame/staking/src/mock.rs | 1 + substrate/frame/staking/src/pallet/mod.rs | 12 ++++++++++-- 17 files changed, 26 insertions(+), 2 deletions(-) diff --git a/polkadot/runtime/test-runtime/src/lib.rs b/polkadot/runtime/test-runtime/src/lib.rs index 46e592ca77ca..d61a4929ffe0 100644 --- a/polkadot/runtime/test-runtime/src/lib.rs +++ b/polkadot/runtime/test-runtime/src/lib.rs @@ -344,6 +344,7 @@ 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; diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs index 46d5f15be34a..df3d088bc0c6 100644 --- a/polkadot/runtime/westend/src/lib.rs +++ b/polkadot/runtime/westend/src/lib.rs @@ -730,6 +730,7 @@ parameter_types! { } impl pallet_staking::Config for Runtime { + type OldCurrency = Balances; type Currency = Balances; type CurrencyBalance = Balance; type RuntimeHoldReason = RuntimeHoldReason; diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 5f8122822d8d..720d8bd475e8 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -666,6 +666,7 @@ impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig { } impl pallet_staking::Config for Runtime { + type OldCurrency = Balances; type Currency = Balances; type CurrencyBalance = Balance; type UnixTime = Timestamp; diff --git a/substrate/frame/babe/src/mock.rs b/substrate/frame/babe/src/mock.rs index 4e4052b2b566..4a173ecdc27f 100644 --- a/substrate/frame/babe/src/mock.rs +++ b/substrate/frame/babe/src/mock.rs @@ -148,6 +148,7 @@ 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 5c79d8f7d7d7..f3a3446691cd 100644 --- a/substrate/frame/beefy/src/mock.rs +++ b/substrate/frame/beefy/src/mock.rs @@ -226,6 +226,7 @@ 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/mock.rs b/substrate/frame/delegated-staking/src/mock.rs index 811d5739f4e9..875279864f7a 100644 --- a/substrate/frame/delegated-staking/src/mock.rs +++ b/substrate/frame/delegated-staking/src/mock.rs @@ -102,6 +102,7 @@ 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/election-provider-multi-phase/test-staking-e2e/src/mock.rs b/substrate/frame/election-provider-multi-phase/test-staking-e2e/src/mock.rs index f20e3983b09d..9e0b02a9275f 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 @@ -285,6 +285,7 @@ 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; diff --git a/substrate/frame/fast-unstake/src/mock.rs b/substrate/frame/fast-unstake/src/mock.rs index 757052e230a1..19f01ebcd13b 100644 --- a/substrate/frame/fast-unstake/src/mock.rs +++ b/substrate/frame/fast-unstake/src/mock.rs @@ -105,6 +105,7 @@ 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; diff --git a/substrate/frame/grandpa/src/mock.rs b/substrate/frame/grandpa/src/mock.rs index caac4107cfb7..e9374ada472a 100644 --- a/substrate/frame/grandpa/src/mock.rs +++ b/substrate/frame/grandpa/src/mock.rs @@ -152,6 +152,7 @@ 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/mock.rs b/substrate/frame/nomination-pools/benchmarking/src/mock.rs index 15d9e2c56031..7c09cf22ad51 100644 --- a/substrate/frame/nomination-pools/benchmarking/src/mock.rs +++ b/substrate/frame/nomination-pools/benchmarking/src/mock.rs @@ -78,6 +78,7 @@ 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/test-delegate-stake/src/mock.rs b/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs index d1bc4ef8ff28..8befa7838544 100644 --- a/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs +++ b/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs @@ -92,6 +92,7 @@ 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/src/mock.rs b/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs index d913c5fe6948..d1dcaec7c4d8 100644 --- a/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs +++ b/substrate/frame/nomination-pools/test-transfer-stake/src/mock.rs @@ -84,6 +84,7 @@ 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/offences/benchmarking/src/mock.rs b/substrate/frame/offences/benchmarking/src/mock.rs index e243ad0e718e..144f5086dbd3 100644 --- a/substrate/frame/offences/benchmarking/src/mock.rs +++ b/substrate/frame/offences/benchmarking/src/mock.rs @@ -126,6 +126,7 @@ 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 af073d7672cf..d7f41fe25467 100644 --- a/substrate/frame/root-offences/src/mock.rs +++ b/substrate/frame/root-offences/src/mock.rs @@ -126,6 +126,7 @@ 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; diff --git a/substrate/frame/session/benchmarking/src/mock.rs b/substrate/frame/session/benchmarking/src/mock.rs index 2aec58cceded..5611cbc786dd 100644 --- a/substrate/frame/session/benchmarking/src/mock.rs +++ b/substrate/frame/session/benchmarking/src/mock.rs @@ -131,6 +131,7 @@ 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/src/mock.rs b/substrate/frame/staking/src/mock.rs index 61602253d3a1..894a9b9747b9 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -263,6 +263,7 @@ 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; diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index 7738188d0ec2..083f2116aa95 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -29,8 +29,8 @@ use frame_support::{ hold::{Balanced as FunHoldBalanced, Mutate as FunHoldMutate}, Mutate as FunMutate, }, - Defensive, DefensiveSaturating, EnsureOrigin, EstimateNextNewSession, Get, OnUnbalanced, - UnixTime, + Defensive, DefensiveSaturating, EnsureOrigin, EstimateNextNewSession, Get, + InspectLockableCurrency, OnUnbalanced, UnixTime, }, weights::Weight, BoundedVec, @@ -92,6 +92,14 @@ 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< From 9ed47166ef59a450e1a7a58aae0a4b6745e206ee Mon Sep 17 00:00:00 2001 From: Ankan Date: Fri, 13 Sep 2024 16:50:00 +0200 Subject: [PATCH 35/56] add old currency to config --- polkadot/runtime/westend/src/tests.rs | 4 +- substrate/frame/staking/src/pallet/impls.rs | 48 ++++++++++++--------- substrate/frame/staking/src/pallet/mod.rs | 5 +++ 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs index c7a08f02bc8a..d68b0258692a 100644 --- a/polkadot/runtime/westend/src/tests.rs +++ b/polkadot/runtime/westend/src/tests.rs @@ -278,9 +278,7 @@ mod remote_tests { let mut err = 0; // iterate over all pools pallet_staking::Ledger::::iter_values().for_each(|ledger| { - match pallet_staking::Pallet::::migrate_lock_to_hold::( - &ledger.stash, - ) { + match pallet_staking::Pallet::::migrate_currency(&ledger.stash) { Ok(_) => { success += 1; }, diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 574fb565063f..24cacf3919b8 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -61,6 +61,7 @@ use super::pallet::*; #[cfg(feature = "try-runtime")] use frame_support::ensure; +use frame_support::traits::LockIdentifier; #[cfg(any(test, feature = "try-runtime"))] use sp_runtime::TryRuntimeError; @@ -1160,41 +1161,46 @@ impl Pallet { EraInfo::::get_full_exposure(era, account) } - pub fn migrate_lock_to_hold(stash: &T::AccountId) -> DispatchResult - where - OldCurrency: frame_support::traits::InspectLockableCurrency, - BalanceOf: From, - { - if Self::is_virtual_staker(stash) { - // we don't need to do anything for virtual stakers since their funds are not locked by - // this pallet. - return Ok(()) - } + pub fn migrate_currency(stash: &T::AccountId) -> DispatchResult { + use frame_support::traits::{InspectLockableCurrency, LockIdentifier, LockableCurrency}; + // we can't do anything for virtual stakers since their funds are not managed/held by + // this pallet. + ensure!(!Self::is_virtual_staker(stash), Error::::VirtualStakerNotAllowed); let ledger = Self::ledger(Stash(stash.clone()))?; - const LOCK_ID: frame_support::traits::LockIdentifier = *b"staking "; - let locked: BalanceOf = OldCurrency::balance_locked(LOCK_ID, stash).into(); + const LOCK_ID: LockIdentifier = *b"staking "; + let locked: BalanceOf = T::OldCurrency::balance_locked(LOCK_ID, stash).into(); + ensure!(!locked.is_zero(), Error::::AlreadyMigrated); + ensure!(ledger.total == locked, Error::::BadState); + let max_hold = asset::stakeable_balance::(&stash); - if max_hold >= locked { - // this is great. easy job for us. - // just hold asset. + let force_withdraw = if max_hold >= locked { + // this means we can replace all locked with stake. yay! asset::update_stake::(&stash, locked)?; + Zero::zero() } else { - let ed = asset::existential_deposit::(); - let unsafe_withdraw = locked.saturating_sub(max_hold); - log::info!(target: "remote_test", "unsafe_withdraw from stash: {:?}, value {:?}, active {:?}", stash, unsafe_withdraw/ed, ledger.active/ed); + // if we are here, it means we cannot hold all funds. We will do a force withdraw from + // ledger which will mean the stake of the user will abruptly reduce. + let force_withdraw = locked.saturating_sub(max_hold); + log::info!(target: "remote_test", "force_withdraw from stash: {:?}, value {:?}, active {:?}", stash, force_withdraw, ledger.active); - // we ignore if active is 0. This amount will get unlocked anyways in the future. + // 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(unsafe_withdraw), + active: ledger.active.saturating_sub(force_withdraw), // we are not changing the stash, so we can keep the stash. ..ledger } .update()?; - } + force_withdraw + }; + // We used to have an extra consumer before. Get rid of it. frame_system::Pallet::::dec_consumers(&stash); + + Self::deposit_event(Event::::CurrencyMigrated { stash: stash.clone(), force_withdraw }); + Ok(()) } } diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index 083f2116aa95..2421f3fcae8a 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -893,6 +893,9 @@ pub mod pallet { ForceEra { mode: Forcing }, /// Report of a controller batch deprecation. ControllerBatchDeprecated { failures: u32 }, + /// 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] @@ -966,6 +969,8 @@ pub mod pallet { 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] From c009a62fecd36bbcd23278af1367d1f68a8852e6 Mon Sep 17 00:00:00 2001 From: Ankan Date: Sun, 15 Sep 2024 20:05:10 +0200 Subject: [PATCH 36/56] ensure ledger update also updates holds --- substrate/frame/staking/Cargo.toml | 1 + substrate/frame/staking/src/lib.rs | 3 +- substrate/frame/staking/src/mock.rs | 13 +++- substrate/frame/staking/src/pallet/impls.rs | 11 +-- substrate/frame/staking/src/tests.rs | 85 ++++++++++++++++++++- 5 files changed, 105 insertions(+), 8 deletions(-) diff --git a/substrate/frame/staking/Cargo.toml b/substrate/frame/staking/Cargo.toml index a6a0ccd3b0a7..e0b6bab7b69b 100644 --- a/substrate/frame/staking/Cargo.toml +++ b/substrate/frame/staking/Cargo.toml @@ -50,6 +50,7 @@ substrate-test-utils = { workspace = true } frame-benchmarking = { workspace = true, default-features = true } frame-election-provider-support = { workspace = true, default-features = true } rand_chacha = { workspace = true, default-features = true } +frame-support = { features = ["experimental"], workspace = true, default-features = true } [features] default = ["std"] diff --git a/substrate/frame/staking/src/lib.rs b/substrate/frame/staking/src/lib.rs index e6c01948a897..179309cabd7a 100644 --- a/substrate/frame/staking/src/lib.rs +++ b/substrate/frame/staking/src/lib.rs @@ -313,7 +313,7 @@ use frame_support::{ defensive, defensive_assert, traits::{ tokens::fungible::{Credit, Debt}, - ConstU32, Defensive, DefensiveMax, DefensiveSaturating, Get, + ConstU32, Defensive, DefensiveMax, DefensiveSaturating, Get, LockIdentifier, }, weights::Weight, BoundedVec, CloneNoBound, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound, @@ -335,6 +335,7 @@ pub use weights::WeightInfo; pub use pallet::{pallet::*, UseNominatorsAndValidatorsMap, UseValidatorsMap}; +pub(crate) const STAKING_ID: LockIdentifier = *b"staking "; pub(crate) const LOG_TARGET: &str = "runtime::staking"; // syntactic sugar for logging. diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index 894a9b9747b9..a30792b938c3 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -25,7 +25,7 @@ use frame_election_provider_support::{ use frame_support::{ assert_ok, derive_impl, ord_parameter_types, parameter_types, traits::{ - ConstU64, EitherOfDiverse, FindAuthor, Get, Hooks, Imbalance, OnUnbalanced, + ConstU64, EitherOfDiverse, FindAuthor, Get, Hooks, Imbalance, LockIdentifier, OnUnbalanced, OneSessionHandler, }, weights::constants::RocksDbWeight, @@ -929,3 +929,14 @@ 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)) } + +pub(crate) fn migrate_to_old_currency(who: &AccountId) { + use frame_support::traits::LockableCurrency; + let staked = asset::staked::(who); + + // apply locks. + Balances::set_lock(STAKING_ID, who, staked, frame_support::traits::WithdrawReasons::all()); + + // remove holds. + asset::kill_stake::(who).expect("remove hold failed"); +} diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 24cacf3919b8..86358c13dcd4 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -54,6 +54,7 @@ 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}; @@ -1162,14 +1163,13 @@ impl Pallet { } pub fn migrate_currency(stash: &T::AccountId) -> DispatchResult { - use frame_support::traits::{InspectLockableCurrency, LockIdentifier, LockableCurrency}; + use frame_support::traits::{InspectLockableCurrency, LockableCurrency}; // we can't do anything for virtual stakers since their funds are not managed/held by // this pallet. ensure!(!Self::is_virtual_staker(stash), Error::::VirtualStakerNotAllowed); let ledger = Self::ledger(Stash(stash.clone()))?; - const LOCK_ID: LockIdentifier = *b"staking "; - let locked: BalanceOf = T::OldCurrency::balance_locked(LOCK_ID, stash).into(); + let locked: BalanceOf = T::OldCurrency::balance_locked(STAKING_ID, stash).into(); ensure!(!locked.is_zero(), Error::::AlreadyMigrated); ensure!(ledger.total == locked, Error::::BadState); @@ -1196,11 +1196,12 @@ impl Pallet { force_withdraw }; - // We used to have an extra consumer before. Get rid of it. + // remove lock + T::OldCurrency::remove_lock(STAKING_ID, &stash); + // 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(()) } } diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index e66a04fe7aae..105f70dd1622 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -26,8 +26,9 @@ 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::{Currency, Get, ReservableCurrency}, + traits::{Currency, Get, InspectLockableCurrency, ReservableCurrency}, }; use mock::*; @@ -8347,3 +8348,85 @@ mod byzantine_threshold_disabling_strategy { }); } } + +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 + 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_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(&alice)); + + // THEN hold is updated. + assert_eq!(asset::staked::(&alice), 1000); + assert_eq!( + ::stake(&alice), + Ok(Stake { total: 1000, active: 1000 }) + ); + + // locked balance is removed + assert_eq!(Balances::balance_locked(STAKING_ID, &alice), 0); + }); + } + + #[test] + fn migrate_removes_old_lock() {} + #[test] + fn cannot_hold_all_stake() {} + + #[test] + fn hold_includes_ed() { + // edge case bond extra with all free does not work + } +} From 17c4aa3f86016cc825cfe1267e7cba3d8908632d Mon Sep 17 00:00:00 2001 From: Ankan Date: Sun, 15 Sep 2024 21:42:26 +0200 Subject: [PATCH 37/56] new call to migrate currency --- polkadot/runtime/westend/src/tests.rs | 5 ++- substrate/frame/staking/src/mock.rs | 8 ++-- substrate/frame/staking/src/pallet/impls.rs | 4 +- substrate/frame/staking/src/pallet/mod.rs | 7 ++++ substrate/frame/staking/src/tests.rs | 45 +++++++++++++++++++-- 5 files changed, 59 insertions(+), 10 deletions(-) diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs index d68b0258692a..ae212e583586 100644 --- a/polkadot/runtime/westend/src/tests.rs +++ b/polkadot/runtime/westend/src/tests.rs @@ -278,7 +278,10 @@ mod remote_tests { let mut err = 0; // iterate over all pools pallet_staking::Ledger::::iter_values().for_each(|ledger| { - match pallet_staking::Pallet::::migrate_currency(&ledger.stash) { + match pallet_staking::Pallet::::migrate_currency( + RuntimeOrigin::signed(alice.clone()).into(), + &ledger.stash, + ) { Ok(_) => { success += 1; }, diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index a30792b938c3..f9ec75edf43f 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -25,7 +25,7 @@ use frame_election_provider_support::{ use frame_support::{ assert_ok, derive_impl, ord_parameter_types, parameter_types, traits::{ - ConstU64, EitherOfDiverse, FindAuthor, Get, Hooks, Imbalance, LockIdentifier, OnUnbalanced, + ConstU64, EitherOfDiverse, FindAuthor, Get, Hooks, Imbalance, OnUnbalanced, OneSessionHandler, }, weights::constants::RocksDbWeight, @@ -934,9 +934,11 @@ pub(crate) fn migrate_to_old_currency(who: &AccountId) { use frame_support::traits::LockableCurrency; let staked = asset::staked::(who); - // apply locks. + // apply locks (this also adds a consumer). Balances::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 explicitly increment consumer. + System::inc_consumers(who).expect("increment consumer failed"); } diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 86358c13dcd4..4a4e5430aad7 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -62,7 +62,6 @@ use super::pallet::*; #[cfg(feature = "try-runtime")] use frame_support::ensure; -use frame_support::traits::LockIdentifier; #[cfg(any(test, feature = "try-runtime"))] use sp_runtime::TryRuntimeError; @@ -1162,7 +1161,7 @@ impl Pallet { EraInfo::::get_full_exposure(era, account) } - pub fn migrate_currency(stash: &T::AccountId) -> DispatchResult { + pub(super) fn do_migrate_currency(stash: &T::AccountId) -> DispatchResult { use frame_support::traits::{InspectLockableCurrency, LockableCurrency}; // we can't do anything for virtual stakers since their funds are not managed/held by @@ -1198,6 +1197,7 @@ impl Pallet { // remove lock T::OldCurrency::remove_lock(STAKING_ID, &stash); + // Get rid of the extra consumer we used to have with OldCurrency. frame_system::Pallet::::dec_consumers(&stash); diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index 2421f3fcae8a..3186d163a6f5 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -2180,6 +2180,13 @@ pub mod pallet { ); Ok(()) } + + #[pallet::call_index(30)] + #[pallet::weight(Weight::zero())] + pub fn migrate_currency(origin: OriginFor, stash: T::AccountId) -> DispatchResult { + let _ = ensure_signed(origin)?; + Self::do_migrate_currency(&stash) + } } } diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 105f70dd1622..1d09f20142f0 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -8406,7 +8406,7 @@ mod hold_migration { }); // WHEN alice currency is migrated. - assert_ok!(Staking::migrate_currency(&alice)); + assert_ok!(Staking::migrate_currency(RuntimeOrigin::signed(1), alice)); // THEN hold is updated. assert_eq!(asset::staked::(&alice), 1000); @@ -8421,12 +8421,49 @@ mod hold_migration { } #[test] - fn migrate_removes_old_lock() {} + 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]); + 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 + // ensure consumer count stays same. + assert_eq!(System::consumers(&alice), pre_migrate_consumer); + // 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 }] + ); + }); + } #[test] - fn cannot_hold_all_stake() {} + fn cannot_hold_all_stake() { + ExtBuilder::default().has_stakers(true).build_and_execute(|| { + // check force withdraw + }); + } #[test] fn hold_includes_ed() { - // edge case bond extra with all free does not work + ExtBuilder::default().has_stakers(true).build_and_execute(|| { + // edge case bond extra with all free does not work + }); } } From c4af869432d4cf57ffa0f9afba1961626ed67bd6 Mon Sep 17 00:00:00 2001 From: Ankan Date: Sun, 15 Sep 2024 21:58:56 +0200 Subject: [PATCH 38/56] force withdraw test --- substrate/frame/staking/src/tests.rs | 46 +++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 1d09f20142f0..87bd8b371287 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -8455,15 +8455,47 @@ mod hold_migration { } #[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(|| { - // check force withdraw - }); - } + // GIVEN alice who is a nominator with old currency. + let alice = 300; + let stake = 1000; + bond_nominator(alice, stake, vec![11]); + 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 }) + ); - #[test] - fn hold_includes_ed() { - ExtBuilder::default().has_stakers(true).build_and_execute(|| { - // edge case bond extra with all free does not work + // She has extra reserved amount which would prevent us from holding all stake. + let expected_force_withdraw = 200; + assert_ok!(Balances::reserve(&alice, expected_force_withdraw)); + + // 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 }] + ); }); } } From e1f1d42669a9b11b946fb3d42943674b388c1986 Mon Sep 17 00:00:00 2001 From: Ankan Date: Sun, 15 Sep 2024 21:59:16 +0200 Subject: [PATCH 39/56] fmt --- substrate/frame/staking/src/tests.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 87bd8b371287..0cbaacbedb9c 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -8494,7 +8494,10 @@ mod hold_migration { // ensure events are emitted. assert_eq!( staking_events_since_last_call(), - vec![Event::CurrencyMigrated { stash: alice, force_withdraw: expected_force_withdraw }] + vec![Event::CurrencyMigrated { + stash: alice, + force_withdraw: expected_force_withdraw + }] ); }); } From b57660d75c3112f391e0f40390d1625716620079 Mon Sep 17 00:00:00 2001 From: Ankan Date: Sun, 15 Sep 2024 23:53:27 +0200 Subject: [PATCH 40/56] add reap stash fail test --- substrate/frame/staking/src/asset.rs | 3 +- substrate/frame/staking/src/ledger.rs | 5 +-- substrate/frame/staking/src/pallet/mod.rs | 11 +++++-- substrate/frame/staking/src/tests.rs | 38 ++++++++++++++++++++++- 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 71da4f5f4c1d..5034ea15ea43 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -80,7 +80,8 @@ pub fn set_stakeable_balance(who: &T::AccountId, value: BalanceOf) let _ = T::Currency::set_balance(who, Zero::zero()); } - assert_eq!(total_balance::(who), value); + // ensure new stakeable balance same as desired `value`. + assert_eq!(stakeable_balance::(who), value); } /// Update `amount` at stake for `who`. diff --git a/substrate/frame/staking/src/ledger.rs b/substrate/frame/staking/src/ledger.rs index b2163fbef516..947050f10183 100644 --- a/substrate/frame/staking/src/ledger.rs +++ b/substrate/frame/staking/src/ledger.rs @@ -251,7 +251,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) -> Result<(), Error> { + pub(crate) fn kill(stash: &T::AccountId) -> DispatchResult { let controller = >::get(stash).ok_or(Error::::NotStash)?; >::get(&controller).ok_or(Error::::NotController).map(|ledger| { @@ -262,7 +262,7 @@ impl StakingLedger { // kill virtual staker if it exists. if >::take(&ledger.stash).is_none() { // if not virtual staker, clear locks. - asset::kill_stake::(&ledger.stash).map_err(|_| Error::::CannotReapStash)?; + asset::kill_stake::(&ledger.stash)?; } Ok(()) @@ -270,6 +270,7 @@ impl StakingLedger { } } +use sp_runtime::DispatchResult; #[cfg(test)] use { crate::UnlockChunk, diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index 3186d163a6f5..afacce6bb53e 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -2182,10 +2182,17 @@ pub mod pallet { } #[pallet::call_index(30)] + // FIXME(ank4n): Bench #[pallet::weight(Weight::zero())] - pub fn migrate_currency(origin: OriginFor, stash: T::AccountId) -> DispatchResult { + pub fn migrate_currency( + origin: OriginFor, + stash: T::AccountId, + ) -> DispatchResultWithPostInfo { let _ = ensure_signed(origin)?; - Self::do_migrate_currency(&stash) + Self::do_migrate_currency(&stash)?; + + // Refund the transaction fee. + Ok(Pays::No.into()) } } } diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 0cbaacbedb9c..785be1097486 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -26,7 +26,7 @@ use frame_election_provider_support::{ use frame_support::{ assert_noop, assert_ok, assert_storage_noop, dispatch::{extract_actual_weight, GetDispatchInfo, WithPostDispatchInfo}, - hypothetically, + hypothetically, hypothetically_ok, pallet_prelude::*, traits::{Currency, Get, InspectLockableCurrency, ReservableCurrency}, }; @@ -1940,6 +1940,42 @@ fn reap_stash_works() { }); } +#[test] +fn reap_stash_fails_if_extra_consumer() { + ExtBuilder::default() + .existential_deposit(10) + .balance_factor(10) + .build_and_execute(|| { + // given + assert_eq!(asset::staked::(&11), 10 * 1000); + assert_eq!(Staking::bonded(&11), Some(11)); + + // When ledger goes below ED + let mut ledger = Staking::ledger(11.into()).unwrap(); + ledger.slash(ledger.total, 10, 1); + assert_ok!(ledger.update()); + // make stake balance as zero. + asset::set_stakeable_balance::(&11, 0); + assert_eq!(asset::staked::(&11), 0); + + // reap stash would work without the extra consumer. + hypothetically_ok!(Staking::reap_stash(RuntimeOrigin::signed(20), 11, 0)); + + // mock stash has an extra consumer from another pallet in the runtime. + System::inc_consumers(&11).expect("stash has a provider so this should not fail"); + + // This would prevent the pallet to decrement provider from reaping the stash. + assert_noop!( + Staking::reap_stash(RuntimeOrigin::signed(20), 11, 0), + DispatchError::ConsumerRemaining + ); + + // Once the extra consumer is removed, the pallet can reap the stash. + System::dec_consumers(&11); + assert_ok!(Staking::reap_stash(RuntimeOrigin::signed(20), 11, 0)); + }); +} + #[test] fn reap_stash_works_with_existential_deposit_zero() { ExtBuilder::default() From dc55b979e1182db09bb730dbb15beb6338ea0fc4 Mon Sep 17 00:00:00 2001 From: Ankan Date: Mon, 16 Sep 2024 00:00:36 +0200 Subject: [PATCH 41/56] split stakeable into staked and free to stake --- substrate/frame/staking/src/asset.rs | 13 ++++++++++--- substrate/frame/staking/src/pallet/impls.rs | 9 ++------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 5034ea15ea43..0bf70dab6407 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -25,7 +25,7 @@ use frame_support::traits::{ }, tokens::Precision, }; -use sp_runtime::{traits::Zero, DispatchResult}; +use sp_runtime::{traits::Zero, DispatchResult, Saturating}; use crate::{ BalanceOf, Config, HoldReason, NegativeImbalanceOf, PositiveImbalanceOf, SessionInterface, @@ -50,16 +50,23 @@ 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 { - T::Currency::balance(who) + T::Currency::balance_on_hold(&HoldReason::Staking.into(), who) + free_to_stake::(who).saturating_add(staked::(who)) } /// Balance of `who` that is currently at stake. /// -/// The staked amount is locked and cannot be transferred out of `who`s account. +/// The staked amount is on hold 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 { + T::Currency::balance(who) +} + /// Set balance that can be staked for `who`. /// /// `Value` must be greater than already staked plus existential deposit for free balance. diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 4a4e5430aad7..9cc7576ae7fa 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -36,8 +36,7 @@ use frame_system::{pallet_prelude::BlockNumberFor, RawOrigin}; use pallet_session::historical; use sp_runtime::{ traits::{ - Bounded, CheckedAdd, CheckedSub, Convert, One, SaturatedConversion, Saturating, - StaticLookup, Zero, + Bounded, CheckedAdd, Convert, One, SaturatedConversion, Saturating, StaticLookup, Zero, }, ArithmeticError, DispatchResult, Perbill, Percent, }; @@ -164,11 +163,7 @@ impl Pallet { additional } else { // additional amount or actual balance of stash whichever is lower. - additional.min( - asset::stakeable_balance::(stash) - .checked_sub(&ledger.total) - .ok_or(ArithmeticError::Overflow)?, - ) + additional.min(asset::free_to_stake::(stash)) }; ledger.total = ledger.total.checked_add(&extra).ok_or(ArithmeticError::Overflow)?; From 591945df7cfdc34b92838ccc7cc02bd08d565ce6 Mon Sep 17 00:00:00 2001 From: Ankan Date: Mon, 16 Sep 2024 01:07:21 +0200 Subject: [PATCH 42/56] refactor remote test migration --- polkadot/runtime/westend/src/tests.rs | 15 ++++++++++++--- substrate/frame/staking/src/pallet/impls.rs | 1 - 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs index ae212e583586..53e85cebe620 100644 --- a/polkadot/runtime/westend/src/tests.rs +++ b/polkadot/runtime/westend/src/tests.rs @@ -276,13 +276,21 @@ mod remote_tests { let mut success = 0; let mut err = 0; + let mut force_withdraw_acc = 0; // iterate over all pools - pallet_staking::Ledger::::iter_values().for_each(|ledger| { + pallet_staking::Ledger::::iter().for_each(|(ctrl, ledger)| { match pallet_staking::Pallet::::migrate_currency( RuntimeOrigin::signed(alice.clone()).into(), - &ledger.stash, + 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) => { @@ -294,9 +302,10 @@ mod remote_tests { log::info!( target: "remote_test", - "Migration stats: success: {}, err: {}", + "Migration stats: success: {}, err: {}, total force withdrawn stake: {}", success, err, + force_withdraw_acc ); }); } diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 9cc7576ae7fa..a399c8ac0015 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -1176,7 +1176,6 @@ impl Pallet { // if we are here, it means we cannot hold all funds. We will do a force withdraw from // ledger which will mean the stake of the user will abruptly reduce. let force_withdraw = locked.saturating_sub(max_hold); - log::info!(target: "remote_test", "force_withdraw from stash: {:?}, value {:?}, active {:?}", stash, force_withdraw, ledger.active); // 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. From a1ccab713d9c7ea03b91418b7f45b306622df34b Mon Sep 17 00:00:00 2001 From: Ankan Date: Mon, 16 Sep 2024 22:32:44 +0200 Subject: [PATCH 43/56] add bench for migrate currency --- .../westend/src/weights/pallet_staking.rs | 4 ++++ substrate/frame/staking/src/asset.rs | 5 ++--- substrate/frame/staking/src/benchmarking.rs | 12 ++++++++++++ substrate/frame/staking/src/mock.rs | 13 ------------- substrate/frame/staking/src/pallet/mod.rs | 5 ++--- substrate/frame/staking/src/testing_utils.rs | 18 ++++++++++++++++++ substrate/frame/staking/src/tests.rs | 6 +++--- substrate/frame/staking/src/weights.rs | 9 +++++++++ 8 files changed, 50 insertions(+), 22 deletions(-) diff --git a/polkadot/runtime/westend/src/weights/pallet_staking.rs b/polkadot/runtime/westend/src/weights/pallet_staking.rs index 393fa0b37176..b3443f7c6cd2 100644 --- a/polkadot/runtime/westend/src/weights/pallet_staking.rs +++ b/polkadot/runtime/westend/src/weights/pallet_staking.rs @@ -826,4 +826,8 @@ impl pallet_staking::WeightInfo for WeightInfo { .saturating_add(T::DbWeight::get().reads(5)) .saturating_add(T::DbWeight::get().writes(4)) } + fn migrate_currency() -> Weight { + // will be auto-generated + Default::default() + } } diff --git a/substrate/frame/staking/src/asset.rs b/substrate/frame/staking/src/asset.rs index 0bf70dab6407..847bfbc2db6c 100644 --- a/substrate/frame/staking/src/asset.rs +++ b/substrate/frame/staking/src/asset.rs @@ -111,12 +111,11 @@ pub fn kill_stake(who: &T::AccountId) -> DispatchResult { T::Currency::release_all(&HoldReason::Staking.into(), who, Precision::BestEffort) .map(|_| ())?; - // FIXME(ank4n): may have to update bench. Also add failing test if non session consumers on - // stash. if !frame_system::Pallet::::can_dec_provider(who) { // The session pallet keeps a consumer reference to validator stash which may block this // pallet from clearing its provider reference. If the account cannot provide for itself - // (via enough free balance) to keep the session key, we should clean up the session keys. + // (via enough free balance) to keep the session key, we try to clean up the session keys. + // If the extra consumer comes from somewhere else, reap stash would fail. T::SessionInterface::purge_keys(who.clone())?; } diff --git a/substrate/frame/staking/src/benchmarking.rs b/substrate/frame/staking/src/benchmarking.rs index 97a76932f1ba..33f282bdeeec 100644 --- a/substrate/frame/staking/src/benchmarking.rs +++ b/substrate/frame/staking/src/benchmarking.rs @@ -961,6 +961,18 @@ benchmarks! { assert_eq!(Staking::::inspect_bond_state(&stash), Ok(LedgerIntegrityState::Ok)); } + migrate_currency { + 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); + }: _(RawOrigin::Signed(stash.clone()), stash.clone()) + verify { + assert_eq!(asset::staked::(&stash), stake); + } + impl_benchmark_test_suite!( Staking, crate::mock::ExtBuilder::default().has_stakers(true), diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index f9ec75edf43f..894a9b9747b9 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -929,16 +929,3 @@ 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)) } - -pub(crate) fn migrate_to_old_currency(who: &AccountId) { - use frame_support::traits::LockableCurrency; - let staked = asset::staked::(who); - - // apply locks (this also adds a consumer). - Balances::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 explicitly increment consumer. - System::inc_consumers(who).expect("increment consumer failed"); -} diff --git a/substrate/frame/staking/src/pallet/mod.rs b/substrate/frame/staking/src/pallet/mod.rs index afacce6bb53e..b091eee595ca 100644 --- a/substrate/frame/staking/src/pallet/mod.rs +++ b/substrate/frame/staking/src/pallet/mod.rs @@ -2182,8 +2182,7 @@ pub mod pallet { } #[pallet::call_index(30)] - // FIXME(ank4n): Bench - #[pallet::weight(Weight::zero())] + #[pallet::weight(T::WeightInfo::migrate_currency())] pub fn migrate_currency( origin: OriginFor, stash: T::AccountId, @@ -2191,7 +2190,7 @@ pub mod pallet { let _ = ensure_signed(origin)?; Self::do_migrate_currency(&stash)?; - // Refund the transaction fee. + // 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 efd4a40f1ab4..ee28849f8c33 100644 --- a/substrate/frame/staking/src/testing_utils.rs +++ b/substrate/frame/staking/src/testing_utils.rs @@ -238,3 +238,21 @@ pub fn create_validators_with_nominators_for_era( pub fn current_era() -> EraIndex { >::current_era().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 explicitly increment 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 785be1097486..3a1693eacf90 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -8398,7 +8398,7 @@ mod hold_migration { assert_eq!(asset::staked::(&alice), 1000); assert_eq!(Balances::balance_locked(STAKING_ID, &alice), 0); // migrate alice currency to legacy locks - migrate_to_old_currency(&alice); + 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); @@ -8462,7 +8462,7 @@ mod hold_migration { // GIVEN alice who is a nominator with old currency let alice = 300; bond_nominator(alice, 1000, vec![11]); - migrate_to_old_currency(&alice); + 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); @@ -8498,7 +8498,7 @@ mod hold_migration { let alice = 300; let stake = 1000; bond_nominator(alice, stake, vec![11]); - migrate_to_old_currency(&alice); + 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. diff --git a/substrate/frame/staking/src/weights.rs b/substrate/frame/staking/src/weights.rs index cd4e7f973ce3..04a7f3ab167c 100644 --- a/substrate/frame/staking/src/weights.rs +++ b/substrate/frame/staking/src/weights.rs @@ -83,6 +83,7 @@ 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. @@ -834,6 +835,10 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } + fn migrate_currency() -> Weight { + // will be auto-generated + Default::default() + } } // For backwards compatibility and tests. @@ -1584,4 +1589,8 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } + fn migrate_currency() -> Weight { + // will be auto-generated + Default::default() + } } From 8c59b582ee103b6262b413e2bc2ab068e0696304 Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 17 Sep 2024 12:56:33 +0200 Subject: [PATCH 44/56] fix try states --- substrate/frame/staking/src/pallet/impls.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index a399c8ac0015..cd223c319ff3 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, Len, OnUnbalanced, - TryCollect, UnixTime, + Defensive, DefensiveSaturating, EstimateNextNewSession, Get, Imbalance, + InspectLockableCurrency, Len, LockableCurrency, OnUnbalanced, TryCollect, UnixTime, }, weights::Weight, }; @@ -96,10 +96,12 @@ impl Pallet { pub(crate) fn inspect_bond_state( stash: &T::AccountId, ) -> Result> { - let lock = asset::staked::(&stash); + // 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 controller = >::get(stash).ok_or_else(|| { - if lock == Zero::zero() { + if hold_or_lock == Zero::zero() { Error::::NotStash } else { Error::::BadState @@ -111,7 +113,7 @@ impl Pallet { if ledger.stash != *stash { Ok(LedgerIntegrityState::Corrupted) } else { - if lock != ledger.total { + if hold_or_lock != ledger.total { Ok(LedgerIntegrityState::LockCorrupted) } else { Ok(LedgerIntegrityState::Ok) @@ -1157,8 +1159,6 @@ impl Pallet { } pub(super) fn do_migrate_currency(stash: &T::AccountId) -> DispatchResult { - use frame_support::traits::{InspectLockableCurrency, LockableCurrency}; - // we can't do anything for virtual stakers since their funds are not managed/held by // this pallet. ensure!(!Self::is_virtual_staker(stash), Error::::VirtualStakerNotAllowed); @@ -2130,7 +2130,7 @@ impl Pallet { if VirtualStakers::::contains_key(stash.clone()) { ensure!( asset::staked::(&stash) == Zero::zero(), - "virtual stakers should not have any locked balance" + "virtual stakers should not have any staked balance" ); ensure!( >::get(stash.clone()).unwrap() == stash.clone(), @@ -2154,7 +2154,7 @@ impl Pallet { } else { ensure!( Self::inspect_bond_state(&stash) == Ok(LedgerIntegrityState::Ok), - "bond, ledger and/or staking lock inconsistent for a bonded stash." + "bond, ledger and/or staking hold inconsistent for a bonded stash." ); } From 36bb12e3fb92c3b4e7687f329d30196cd54193ac Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 17 Sep 2024 13:22:24 +0200 Subject: [PATCH 45/56] prdoc --- prdoc/pr_5501.prdoc | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 prdoc/pr_5501.prdoc diff --git a/prdoc/pr_5501.prdoc b/prdoc/pr_5501.prdoc new file mode 100644 index 000000000000..82ac554bbbf8 --- /dev/null +++ b/prdoc/pr_5501.prdoc @@ -0,0 +1,27 @@ +# 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. + +crates: + - name: westend-runtime + bump: minor + - name: kitchensink-runtime + bump: minor + - name: pallet-delegated-staking + bump: patch + - name: pallet-nomination-pools + bump: patch + - name: frame-support + bump: patch + - name: pallet-treasury + bump: minor + - name: sp-staking + bump: minor From c06e60bfa69bee13c8f9c32619574b0cc7b42c74 Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 17 Sep 2024 13:23:53 +0200 Subject: [PATCH 46/56] clippy fix --- polkadot/runtime/westend/src/tests.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/polkadot/runtime/westend/src/tests.rs b/polkadot/runtime/westend/src/tests.rs index 53e85cebe620..6f2e36c68e3b 100644 --- a/polkadot/runtime/westend/src/tests.rs +++ b/polkadot/runtime/westend/src/tests.rs @@ -244,7 +244,6 @@ mod remote_tests { if var("RUN_MIGRATION_TESTS").is_err() { return; } - use frame_support::assert_ok; sp_tracing::try_init_simple(); let transport: Transport = var("WS").unwrap_or("ws://127.0.0.1:9900".to_string()).into(); From 5c29547f260ef8a8fb9907e4877cf52e70dd4a94 Mon Sep 17 00:00:00 2001 From: Ankan Date: Tue, 17 Sep 2024 13:28:50 +0200 Subject: [PATCH 47/56] improve tests --- substrate/frame/staking/src/tests.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 3a1693eacf90..6d5cca4f3984 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -8511,6 +8511,12 @@ mod hold_migration { let expected_force_withdraw = 200; assert_ok!(Balances::reserve(&alice, expected_force_withdraw)); + // 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(); @@ -8535,6 +8541,9 @@ mod hold_migration { force_withdraw: expected_force_withdraw }] ); + + // unbond works after migration. + assert_ok!(Staking::unbond(RuntimeOrigin::signed(alice), 100)); }); } } From f07061bdd5643dce485c7c0db52f42e863a47c2d Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Tue, 17 Sep 2024 13:44:40 +0000 Subject: [PATCH 48/56] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=dev --target_dir=substrate --pallet=pallet_staking --- substrate/frame/staking/src/weights.rs | 758 +++++++++++++------------ 1 file changed, 397 insertions(+), 361 deletions(-) diff --git a/substrate/frame/staking/src/weights.rs b/substrate/frame/staking/src/weights.rs index 04a7f3ab167c..b03fa4ce594f 100644 --- a/substrate/frame/staking/src/weights.rs +++ b/substrate/frame/staking/src/weights.rs @@ -18,27 +18,25 @@ //! Autogenerated weights for `pallet_staking` //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 -//! DATE: 2024-04-09, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-09-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-anb7yjbi-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-obbyq9g6-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 -// --output=./substrate/frame/staking/src/weights.rs +// --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 // --template=./substrate/.maintain/frame-weight-template.hbs #![cfg_attr(rustfmt, rustfmt_skip)] @@ -93,18 +91,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::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: `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: `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: `1042` - // Estimated: `4764` - // Minimum execution time: 46_504_000 picoseconds. - Weight::from_parts(48_459_000, 4764) + // Measured: `1068` + // Estimated: `4556` + // Minimum execution time: 71_854_000 picoseconds. + Weight::from_parts(73_408_000, 4556) .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(4_u64)) } @@ -112,20 +110,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: `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::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: `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: `1990` + // Measured: `2049` // Estimated: `8877` - // Minimum execution time: 90_475_000 picoseconds. - Weight::from_parts(93_619_000, 8877) + // Minimum execution time: 127_442_000 picoseconds. + Weight::from_parts(130_845_000, 8877) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } @@ -139,22 +137,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: `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::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: `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: `2195` + // Measured: `2151` // Estimated: `8877` - // Minimum execution time: 99_335_000 picoseconds. - Weight::from_parts(101_440_000, 8877) + // Minimum execution time: 105_259_000 picoseconds. + Weight::from_parts(107_112_000, 8877) .saturating_add(T::DbWeight::get().reads(12_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)) + .saturating_add(T::DbWeight::get().writes(6_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -162,21 +160,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: `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::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: `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: `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())) + // 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())) .saturating_add(T::DbWeight::get().reads(6_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -188,10 +186,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: `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::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: `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) @@ -211,14 +209,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: `2196 + s * (4 ±0)` + // Measured: `2255 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // 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())) + // 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())) .saturating_add(T::DbWeight::get().reads(13_u64)) - .saturating_add(T::DbWeight::get().writes(11_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())) } @@ -246,10 +244,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: `1372` + // Measured: `1438` // Estimated: `4556` - // Minimum execution time: 56_291_000 picoseconds. - Weight::from_parts(58_372_000, 4556) + // Minimum execution time: 68_826_000 picoseconds. + Weight::from_parts(71_261_000, 4556) .saturating_add(T::DbWeight::get().reads(11_u64)) .saturating_add(T::DbWeight::get().writes(5_u64)) } @@ -262,12 +260,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `k` is `[1, 128]`. fn kick(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1815 + k * (572 ±0)` + // Measured: `1848 + k * (572 ±0)` // Estimated: `4556 + k * (3033 ±0)` - // 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())) + // 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())) .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()))) @@ -298,12 +296,12 @@ impl WeightInfo for SubstrateWeight { /// The range of component `n` is `[1, 16]`. fn nominate(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1866 + n * (102 ±0)` + // Measured: `1932 + n * (102 ±0)` // Estimated: `6248 + n * (2520 ±0)` - // 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())) + // 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())) .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)) @@ -327,10 +325,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: `1816` + // Measured: `1882` // Estimated: `6248` - // Minimum execution time: 60_088_000 picoseconds. - Weight::from_parts(62_471_000, 6248) + // Minimum execution time: 73_939_000 picoseconds. + Weight::from_parts(75_639_000, 6248) .saturating_add(T::DbWeight::get().reads(9_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -342,10 +340,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: `902` + // Measured: `935` // Estimated: `4556` - // Minimum execution time: 19_777_000 picoseconds. - Weight::from_parts(20_690_000, 4556) + // Minimum execution time: 24_592_000 picoseconds. + Weight::from_parts(25_092_000, 4556) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -357,10 +355,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: `969` + // Measured: `1002` // Estimated: `4556` - // Minimum execution time: 23_705_000 picoseconds. - Weight::from_parts(24_409_000, 4556) + // Minimum execution time: 29_735_000 picoseconds. + Weight::from_parts(30_546_000, 4556) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -370,10 +368,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: `902` + // Measured: `935` // Estimated: `8122` - // Minimum execution time: 23_479_000 picoseconds. - Weight::from_parts(24_502_000, 8122) + // Minimum execution time: 28_728_000 picoseconds. + Weight::from_parts(29_709_000, 8122) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } @@ -383,8 +381,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_675_000 picoseconds. - Weight::from_parts(2_802_000, 0) + // Minimum execution time: 2_519_000 picoseconds. + Weight::from_parts(2_673_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -393,8 +391,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_067_000 picoseconds. - Weight::from_parts(7_413_000, 0) + // Minimum execution time: 8_050_000 picoseconds. + Weight::from_parts(8_268_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -403,8 +401,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_977_000 picoseconds. - Weight::from_parts(7_353_000, 0) + // Minimum execution time: 8_131_000 picoseconds. + Weight::from_parts(8_349_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -413,8 +411,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_071_000 picoseconds. - Weight::from_parts(7_463_000, 0) + // Minimum execution time: 8_104_000 picoseconds. + Weight::from_parts(8_317_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::Invulnerables` (r:0 w:1) @@ -424,10 +422,10 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // 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())) + // 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())) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Staking::Ledger` (r:11800 w:11800) @@ -439,12 +437,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: `1746 + i * (229 ±0)` + // Measured: `1779 + i * (229 ±0)` // Estimated: `990 + i * (7132 ±0)` - // 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())) + // 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())) .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())) @@ -455,10 +453,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: `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::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: `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) @@ -480,14 +478,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: `2196 + s * (4 ±0)` + // Measured: `2255 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // 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())) + // 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())) .saturating_add(T::DbWeight::get().reads(13_u64)) - .saturating_add(T::DbWeight::get().writes(12_u64)) + .saturating_add(T::DbWeight::get().writes(13_u64)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -496,12 +494,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: `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())) + // 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())) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -519,12 +517,10 @@ 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: `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::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: `Staking::ErasStakersPaged` (r:1 w:0) /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::ErasRewardPoints` (r:1 w:0) @@ -533,29 +529,31 @@ 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: `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())) + // 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())) .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, 3774).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 3566).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: `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::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: `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) @@ -563,25 +561,25 @@ impl WeightInfo for SubstrateWeight { /// The range of component `l` is `[1, 32]`. fn rebond(l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1991 + l * (7 ±0)` + // Measured: `1947 + l * (7 ±0)` // Estimated: `8877` - // 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())) + // 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())) .saturating_add(T::DbWeight::get().reads(9_u64)) - .saturating_add(T::DbWeight::get().writes(7_u64)) + .saturating_add(T::DbWeight::get().writes(6_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::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: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, 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) @@ -601,14 +599,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: `2196 + s * (4 ±0)` + // Measured: `2255 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // 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())) + // 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())) .saturating_add(T::DbWeight::get().reads(12_u64)) - .saturating_add(T::DbWeight::get().writes(11_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())) } @@ -652,12 +650,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: 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())) + // 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())) .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()))) @@ -686,14 +684,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: `3175 + n * (911 ±0) + v * (395 ±0)` + // Measured: `3241 + n * (911 ±0) + v * (395 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // 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())) + // 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())) .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()))) @@ -708,12 +706,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: `979 + v * (50 ±0)` + // Measured: `1012 + v * (50 ±0)` // Estimated: `3510 + v * (2520 ±0)` - // 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())) + // 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())) .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())) @@ -736,8 +734,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_753_000 picoseconds. - Weight::from_parts(6_529_000, 0) + // Minimum execution time: 4_748_000 picoseconds. + Weight::from_parts(5_052_000, 0) .saturating_add(T::DbWeight::get().writes(7_u64)) } /// Storage: `Staking::MinCommission` (r:0 w:1) @@ -758,8 +756,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_212_000 picoseconds. - Weight::from_parts(5_451_000, 0) + // Minimum execution time: 4_316_000 picoseconds. + Weight::from_parts(4_526_000, 0) .saturating_add(T::DbWeight::get().writes(7_u64)) } /// Storage: `Staking::Bonded` (r:1 w:0) @@ -786,10 +784,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: `1939` + // Measured: `2005` // Estimated: `6248` - // Minimum execution time: 73_000_000 picoseconds. - Weight::from_parts(75_184_000, 6248) + // Minimum execution time: 87_374_000 picoseconds. + Weight::from_parts(89_848_000, 6248) .saturating_add(T::DbWeight::get().reads(12_u64)) .saturating_add(T::DbWeight::get().writes(6_u64)) } @@ -799,10 +797,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: `691` + // Measured: `724` // Estimated: `3510` - // Minimum execution time: 13_056_000 picoseconds. - Weight::from_parts(13_517_000, 3510) + // Minimum execution time: 15_529_000 picoseconds. + Weight::from_parts(16_094_000, 3510) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -812,32 +810,51 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_201_000 picoseconds. - Weight::from_parts(3_442_000, 0) + // Minimum execution time: 2_533_000 picoseconds. + Weight::from_parts(2_817_000, 0) .saturating_add(T::DbWeight::get().writes(1_u64)) } - /// 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) + /// 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) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, 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: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn restore_ledger() -> Weight { // Proof Size summary in bytes: - // Measured: `1047` + // Measured: `1110` // Estimated: `4764` - // 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)) + // 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 { - // will be auto-generated - Default::default() + // Proof Size summary in bytes: + // Measured: `1246` + // 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)) } } @@ -847,18 +864,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::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: `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: `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: `1042` - // Estimated: `4764` - // Minimum execution time: 46_504_000 picoseconds. - Weight::from_parts(48_459_000, 4764) + // Measured: `1068` + // Estimated: `4556` + // Minimum execution time: 71_854_000 picoseconds. + Weight::from_parts(73_408_000, 4556) .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(4_u64)) } @@ -866,20 +883,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: `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::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: `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: `1990` + // Measured: `2049` // Estimated: `8877` - // Minimum execution time: 90_475_000 picoseconds. - Weight::from_parts(93_619_000, 8877) + // Minimum execution time: 127_442_000 picoseconds. + Weight::from_parts(130_845_000, 8877) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } @@ -893,22 +910,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: `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::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: `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: `2195` + // Measured: `2151` // Estimated: `8877` - // Minimum execution time: 99_335_000 picoseconds. - Weight::from_parts(101_440_000, 8877) + // Minimum execution time: 105_259_000 picoseconds. + Weight::from_parts(107_112_000, 8877) .saturating_add(RocksDbWeight::get().reads(12_u64)) - .saturating_add(RocksDbWeight::get().writes(7_u64)) + .saturating_add(RocksDbWeight::get().writes(6_u64)) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -916,21 +933,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: `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::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: `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: `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())) + // 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())) .saturating_add(RocksDbWeight::get().reads(6_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -942,10 +959,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: `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::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: `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) @@ -965,14 +982,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: `2196 + s * (4 ±0)` + // Measured: `2255 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // 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())) + // 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())) .saturating_add(RocksDbWeight::get().reads(13_u64)) - .saturating_add(RocksDbWeight::get().writes(11_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())) } @@ -1000,10 +1017,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: `1372` + // Measured: `1438` // Estimated: `4556` - // Minimum execution time: 56_291_000 picoseconds. - Weight::from_parts(58_372_000, 4556) + // Minimum execution time: 68_826_000 picoseconds. + Weight::from_parts(71_261_000, 4556) .saturating_add(RocksDbWeight::get().reads(11_u64)) .saturating_add(RocksDbWeight::get().writes(5_u64)) } @@ -1016,12 +1033,12 @@ impl WeightInfo for () { /// The range of component `k` is `[1, 128]`. fn kick(k: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1815 + k * (572 ±0)` + // Measured: `1848 + k * (572 ±0)` // Estimated: `4556 + k * (3033 ±0)` - // 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())) + // 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())) .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()))) @@ -1052,12 +1069,12 @@ impl WeightInfo for () { /// The range of component `n` is `[1, 16]`. fn nominate(n: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1866 + n * (102 ±0)` + // Measured: `1932 + n * (102 ±0)` // Estimated: `6248 + n * (2520 ±0)` - // 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())) + // 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())) .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)) @@ -1081,10 +1098,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: `1816` + // Measured: `1882` // Estimated: `6248` - // Minimum execution time: 60_088_000 picoseconds. - Weight::from_parts(62_471_000, 6248) + // Minimum execution time: 73_939_000 picoseconds. + Weight::from_parts(75_639_000, 6248) .saturating_add(RocksDbWeight::get().reads(9_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -1096,10 +1113,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: `902` + // Measured: `935` // Estimated: `4556` - // Minimum execution time: 19_777_000 picoseconds. - Weight::from_parts(20_690_000, 4556) + // Minimum execution time: 24_592_000 picoseconds. + Weight::from_parts(25_092_000, 4556) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1111,10 +1128,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: `969` + // Measured: `1002` // Estimated: `4556` - // Minimum execution time: 23_705_000 picoseconds. - Weight::from_parts(24_409_000, 4556) + // Minimum execution time: 29_735_000 picoseconds. + Weight::from_parts(30_546_000, 4556) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1124,10 +1141,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: `902` + // Measured: `935` // Estimated: `8122` - // Minimum execution time: 23_479_000 picoseconds. - Weight::from_parts(24_502_000, 8122) + // Minimum execution time: 28_728_000 picoseconds. + Weight::from_parts(29_709_000, 8122) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } @@ -1137,8 +1154,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_675_000 picoseconds. - Weight::from_parts(2_802_000, 0) + // Minimum execution time: 2_519_000 picoseconds. + Weight::from_parts(2_673_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1147,8 +1164,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_067_000 picoseconds. - Weight::from_parts(7_413_000, 0) + // Minimum execution time: 8_050_000 picoseconds. + Weight::from_parts(8_268_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1157,8 +1174,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 6_977_000 picoseconds. - Weight::from_parts(7_353_000, 0) + // Minimum execution time: 8_131_000 picoseconds. + Weight::from_parts(8_349_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::ForceEra` (r:0 w:1) @@ -1167,8 +1184,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_071_000 picoseconds. - Weight::from_parts(7_463_000, 0) + // Minimum execution time: 8_104_000 picoseconds. + Weight::from_parts(8_317_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::Invulnerables` (r:0 w:1) @@ -1178,10 +1195,10 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // 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())) + // 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())) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Staking::Ledger` (r:11800 w:11800) @@ -1193,12 +1210,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: `1746 + i * (229 ±0)` + // Measured: `1779 + i * (229 ±0)` // Estimated: `990 + i * (7132 ±0)` - // 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())) + // 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())) .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())) @@ -1209,10 +1226,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: `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::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: `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) @@ -1234,14 +1251,14 @@ impl WeightInfo for () { /// The range of component `s` is `[0, 100]`. fn force_unstake(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2196 + s * (4 ±0)` + // Measured: `2255 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // 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())) + // 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())) .saturating_add(RocksDbWeight::get().reads(13_u64)) - .saturating_add(RocksDbWeight::get().writes(12_u64)) + .saturating_add(RocksDbWeight::get().writes(13_u64)) .saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -1250,12 +1267,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: `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())) + // 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())) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1273,12 +1290,10 @@ 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: `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::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: `Staking::ErasStakersPaged` (r:1 w:0) /// Proof: `Staking::ErasStakersPaged` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Storage: `Staking::ErasRewardPoints` (r:1 w:0) @@ -1287,29 +1302,31 @@ 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: `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())) + // 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())) .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, 3774).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 3566).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: `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::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: `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) @@ -1317,25 +1334,25 @@ impl WeightInfo for () { /// The range of component `l` is `[1, 32]`. fn rebond(l: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `1991 + l * (7 ±0)` + // Measured: `1947 + l * (7 ±0)` // Estimated: `8877` - // 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())) + // 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())) .saturating_add(RocksDbWeight::get().reads(9_u64)) - .saturating_add(RocksDbWeight::get().writes(7_u64)) + .saturating_add(RocksDbWeight::get().writes(6_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::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: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, 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) @@ -1355,14 +1372,14 @@ impl WeightInfo for () { /// The range of component `s` is `[1, 100]`. fn reap_stash(s: u32, ) -> Weight { // Proof Size summary in bytes: - // Measured: `2196 + s * (4 ±0)` + // Measured: `2255 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // 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())) + // 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())) .saturating_add(RocksDbWeight::get().reads(12_u64)) - .saturating_add(RocksDbWeight::get().writes(11_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())) } @@ -1406,12 +1423,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: 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())) + // 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())) .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()))) @@ -1440,14 +1457,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: `3175 + n * (911 ±0) + v * (395 ±0)` + // Measured: `3241 + n * (911 ±0) + v * (395 ±0)` // Estimated: `512390 + n * (3566 ±0) + v * (3566 ±0)` - // 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())) + // 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())) .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()))) @@ -1462,12 +1479,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: `979 + v * (50 ±0)` + // Measured: `1012 + v * (50 ±0)` // Estimated: `3510 + v * (2520 ±0)` - // 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())) + // 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())) .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())) @@ -1490,8 +1507,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_753_000 picoseconds. - Weight::from_parts(6_529_000, 0) + // Minimum execution time: 4_748_000 picoseconds. + Weight::from_parts(5_052_000, 0) .saturating_add(RocksDbWeight::get().writes(7_u64)) } /// Storage: `Staking::MinCommission` (r:0 w:1) @@ -1512,8 +1529,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 5_212_000 picoseconds. - Weight::from_parts(5_451_000, 0) + // Minimum execution time: 4_316_000 picoseconds. + Weight::from_parts(4_526_000, 0) .saturating_add(RocksDbWeight::get().writes(7_u64)) } /// Storage: `Staking::Bonded` (r:1 w:0) @@ -1540,10 +1557,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: `1939` + // Measured: `2005` // Estimated: `6248` - // Minimum execution time: 73_000_000 picoseconds. - Weight::from_parts(75_184_000, 6248) + // Minimum execution time: 87_374_000 picoseconds. + Weight::from_parts(89_848_000, 6248) .saturating_add(RocksDbWeight::get().reads(12_u64)) .saturating_add(RocksDbWeight::get().writes(6_u64)) } @@ -1553,10 +1570,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: `691` + // Measured: `724` // Estimated: `3510` - // Minimum execution time: 13_056_000 picoseconds. - Weight::from_parts(13_517_000, 3510) + // Minimum execution time: 15_529_000 picoseconds. + Weight::from_parts(16_094_000, 3510) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -1566,31 +1583,50 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_201_000 picoseconds. - Weight::from_parts(3_442_000, 0) + // Minimum execution time: 2_533_000 picoseconds. + Weight::from_parts(2_817_000, 0) .saturating_add(RocksDbWeight::get().writes(1_u64)) } - /// 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) + /// 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) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, 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: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn restore_ledger() -> Weight { // Proof Size summary in bytes: - // Measured: `1047` + // Measured: `1110` // Estimated: `4764` - // 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)) + // 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 { - // will be auto-generated - Default::default() + // Proof Size summary in bytes: + // Measured: `1246` + // 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)) } } From da0a7c31f8c15f54601f81b061911aa2ce789a99 Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Tue, 17 Sep 2024 15:10:17 +0000 Subject: [PATCH 49/56] ".git/.scripts/commands/bench/bench.sh" --subcommand=pallet --runtime=westend --target_dir=polkadot --pallet=pallet_staking --- .../westend/src/weights/pallet_staking.rs | 388 +++++++++--------- 1 file changed, 205 insertions(+), 183 deletions(-) diff --git a/polkadot/runtime/westend/src/weights/pallet_staking.rs b/polkadot/runtime/westend/src/weights/pallet_staking.rs index b3443f7c6cd2..f1e7f5ba1576 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-03-27, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2024-09-17, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `runner-h2rr8wx7-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! HOSTNAME: `runner-obbyq9g6-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::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: `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: `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: `1009` - // Estimated: `4764` - // Minimum execution time: 40_585_000 picoseconds. - Weight::from_parts(41_800_000, 0) - .saturating_add(Weight::from_parts(0, 4764)) + // 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)) .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: `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::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: `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: `1921` + // Measured: `1947` // Estimated: `8877` - // Minimum execution time: 81_809_000 picoseconds. - Weight::from_parts(84_387_000, 0) + // Minimum execution time: 125_203_000 picoseconds. + Weight::from_parts(128_088_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: `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::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: `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: `2128` + // Measured: `2051` // Estimated: `8877` - // Minimum execution time: 89_419_000 picoseconds. - Weight::from_parts(91_237_000, 0) + // Minimum execution time: 101_991_000 picoseconds. + Weight::from_parts(104_567_000, 0) .saturating_add(Weight::from_parts(0, 8877)) .saturating_add(T::DbWeight::get().reads(12)) - .saturating_add(T::DbWeight::get().writes(7)) + .saturating_add(T::DbWeight::get().writes(6)) } /// Storage: `Staking::Ledger` (r:1 w:1) /// Proof: `Staking::Ledger` (`max_values`: None, `max_size`: Some(1091), added: 3566, mode: `MaxEncodedLen`) @@ -124,23 +124,25 @@ 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: `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::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: `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: `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)) + // 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)) .saturating_add(T::DbWeight::get().writes(2)) } /// Storage: `Staking::Ledger` (r:1 w:1) @@ -151,10 +153,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: `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::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: `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) @@ -174,15 +176,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: `2127 + s * (4 ±0)` + // Measured: `2153 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 82_762_000 picoseconds. - Weight::from_parts(91_035_077, 0) + // Minimum execution time: 121_962_000 picoseconds. + Weight::from_parts(131_000_151, 0) .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 3_771 - .saturating_add(Weight::from_parts(1_217_871, 0).saturating_mul(s.into())) + // Standard Error: 3_846 + .saturating_add(Weight::from_parts(1_277_843, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(13)) - .saturating_add(T::DbWeight::get().writes(11)) + .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())) } @@ -210,10 +212,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: `1301` + // Measured: `1334` // Estimated: `4556` - // Minimum execution time: 50_555_000 picoseconds. - Weight::from_parts(52_052_000, 0) + // Minimum execution time: 66_450_000 picoseconds. + Weight::from_parts(68_302_000, 0) .saturating_add(Weight::from_parts(0, 4556)) .saturating_add(T::DbWeight::get().reads(11)) .saturating_add(T::DbWeight::get().writes(5)) @@ -227,13 +229,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: `1778 + k * (572 ±0)` + // Measured: `1811 + k * (572 ±0)` // Estimated: `4556 + k * (3033 ±0)` - // Minimum execution time: 35_037_000 picoseconds. - Weight::from_parts(35_081_878, 0) + // Minimum execution time: 43_875_000 picoseconds. + Weight::from_parts(47_332_240, 0) .saturating_add(Weight::from_parts(0, 4556)) - // Standard Error: 5_473 - .saturating_add(Weight::from_parts(6_667_924, 0).saturating_mul(k.into())) + // Standard Error: 6_530 + .saturating_add(Weight::from_parts(7_398_001, 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()))) @@ -264,13 +266,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: `1797 + n * (102 ±0)` + // Measured: `1830 + n * (102 ±0)` // Estimated: `6248 + n * (2520 ±0)` - // Minimum execution time: 62_098_000 picoseconds. - Weight::from_parts(60_154_061, 0) + // Minimum execution time: 80_640_000 picoseconds. + Weight::from_parts(78_801_092, 0) .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 19_257 - .saturating_add(Weight::from_parts(3_839_855, 0).saturating_mul(n.into())) + // Standard Error: 22_249 + .saturating_add(Weight::from_parts(4_996_344, 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)) @@ -294,10 +296,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: `1747` + // Measured: `1780` // Estimated: `6248` - // Minimum execution time: 54_993_000 picoseconds. - Weight::from_parts(56_698_000, 0) + // Minimum execution time: 71_494_000 picoseconds. + Weight::from_parts(73_487_000, 0) .saturating_add(Weight::from_parts(0, 6248)) .saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().writes(6)) @@ -310,10 +312,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: `865` + // Measured: `898` // Estimated: `4556` - // Minimum execution time: 18_100_000 picoseconds. - Weight::from_parts(18_547_000, 0) + // Minimum execution time: 24_310_000 picoseconds. + Weight::from_parts(24_676_000, 0) .saturating_add(Weight::from_parts(0, 4556)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -326,10 +328,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: `932` + // Measured: `965` // Estimated: `4556` - // Minimum execution time: 23_428_000 picoseconds. - Weight::from_parts(24_080_000, 0) + // Minimum execution time: 31_348_000 picoseconds. + Weight::from_parts(32_384_000, 0) .saturating_add(Weight::from_parts(0, 4556)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(1)) @@ -340,10 +342,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: `865` + // Measured: `898` // Estimated: `8122` - // Minimum execution time: 21_159_000 picoseconds. - Weight::from_parts(21_706_000, 0) + // Minimum execution time: 27_537_000 picoseconds. + Weight::from_parts(28_714_000, 0) .saturating_add(Weight::from_parts(0, 8122)) .saturating_add(T::DbWeight::get().reads(3)) .saturating_add(T::DbWeight::get().writes(3)) @@ -354,8 +356,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_910_000 picoseconds. - Weight::from_parts(2_003_000, 0) + // Minimum execution time: 2_362_000 picoseconds. + Weight::from_parts(2_518_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -365,8 +367,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_076_000 picoseconds. - Weight::from_parts(7_349_000, 0) + // Minimum execution time: 7_752_000 picoseconds. + Weight::from_parts(8_105_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -376,8 +378,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_067_000 picoseconds. - Weight::from_parts(7_389_000, 0) + // Minimum execution time: 7_868_000 picoseconds. + Weight::from_parts(8_175_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -387,8 +389,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 7_148_000 picoseconds. - Weight::from_parts(7_446_000, 0) + // Minimum execution time: 7_945_000 picoseconds. + Weight::from_parts(8_203_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -399,11 +401,11 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 2_025_000 picoseconds. - Weight::from_parts(2_229_953, 0) + // Minimum execution time: 2_458_000 picoseconds. + Weight::from_parts(2_815_664, 0) .saturating_add(Weight::from_parts(0, 0)) // Standard Error: 67 - .saturating_add(Weight::from_parts(11_785, 0).saturating_mul(v.into())) + .saturating_add(Weight::from_parts(12_287, 0).saturating_mul(v.into())) .saturating_add(T::DbWeight::get().writes(1)) } /// Storage: `Staking::Ledger` (r:1502 w:1502) @@ -415,13 +417,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: `680 + i * (227 ±0)` + // Measured: `713 + i * (227 ±0)` // Estimated: `990 + i * (7132 ±0)` - // Minimum execution time: 4_321_000 picoseconds. - Weight::from_parts(4_407_000, 0) + // Minimum execution time: 4_976_000 picoseconds. + Weight::from_parts(5_102_000, 0) .saturating_add(Weight::from_parts(0, 990)) - // Standard Error: 37_239 - .saturating_add(Weight::from_parts(21_300_598, 0).saturating_mul(i.into())) + // Standard Error: 36_458 + .saturating_add(Weight::from_parts(25_359_275, 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())) @@ -432,10 +434,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: `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::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: `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) @@ -457,15 +459,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: `2127 + s * (4 ±0)` + // Measured: `2153 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 78_908_000 picoseconds. - Weight::from_parts(84_886_373, 0) + // Minimum execution time: 116_776_000 picoseconds. + Weight::from_parts(125_460_389, 0) .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 3_376 - .saturating_add(Weight::from_parts(1_217_850, 0).saturating_mul(s.into())) + // Standard Error: 3_095 + .saturating_add(Weight::from_parts(1_300_502, 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(13)) .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(s.into()))) .saturating_add(Weight::from_parts(0, 4).saturating_mul(s.into())) } @@ -474,13 +476,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: `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())) + // 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())) .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } @@ -498,12 +500,10 @@ 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: `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::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: `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,30 +512,32 @@ 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: `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())) + // 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())) .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, 3774).saturating_mul(n.into())) + .saturating_add(Weight::from_parts(0, 3566).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: `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::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: `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) @@ -543,26 +545,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: `1922 + l * (5 ±0)` + // Measured: `1845 + l * (5 ±0)` // Estimated: `8877` - // Minimum execution time: 79_136_000 picoseconds. - Weight::from_parts(82_129_497, 0) + // Minimum execution time: 89_307_000 picoseconds. + Weight::from_parts(92_902_634, 0) .saturating_add(Weight::from_parts(0, 8877)) - // Standard Error: 3_867 - .saturating_add(Weight::from_parts(75_156, 0).saturating_mul(l.into())) + // Standard Error: 4_446 + .saturating_add(Weight::from_parts(73_546, 0).saturating_mul(l.into())) .saturating_add(T::DbWeight::get().reads(9)) - .saturating_add(T::DbWeight::get().writes(7)) + .saturating_add(T::DbWeight::get().writes(6)) } + /// 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::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: `Balances::Holds` (r:1 w:1) + /// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(103), added: 2578, 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) @@ -582,15 +584,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: `2127 + s * (4 ±0)` + // Measured: `2153 + s * (4 ±0)` // Estimated: `6248 + s * (4 ±0)` - // Minimum execution time: 89_375_000 picoseconds. - Weight::from_parts(91_224_907, 0) + // Minimum execution time: 130_544_000 picoseconds. + Weight::from_parts(133_260_598, 0) .saturating_add(Weight::from_parts(0, 6248)) - // Standard Error: 3_424 - .saturating_add(Weight::from_parts(1_219_542, 0).saturating_mul(s.into())) + // Standard Error: 3_545 + .saturating_add(Weight::from_parts(1_313_348, 0).saturating_mul(s.into())) .saturating_add(T::DbWeight::get().reads(12)) - .saturating_add(T::DbWeight::get().writes(11)) + .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())) } @@ -633,14 +635,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 ±0)` - // Minimum execution time: 520_905_000 picoseconds. - Weight::from_parts(523_771_000, 0) + // Estimated: `456136 + n * (3566 ±4) + v * (3566 ±40)` + // Minimum execution time: 654_756_000 picoseconds. + Weight::from_parts(658_861_000, 0) .saturating_add(Weight::from_parts(0, 456136)) - // 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())) + // 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())) .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()))) @@ -669,15 +671,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: `3108 + n * (907 ±0) + v * (391 ±0)` + // Measured: `3141 + n * (907 ±0) + v * (391 ±0)` // Estimated: `456136 + n * (3566 ±0) + v * (3566 ±0)` - // Minimum execution time: 36_848_619_000 picoseconds. - Weight::from_parts(37_362_442_000, 0) + // Minimum execution time: 42_790_195_000 picoseconds. + Weight::from_parts(42_954_437_000, 0) .saturating_add(Weight::from_parts(0, 456136)) - // 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())) + // 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())) .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()))) @@ -692,13 +694,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: `946 + v * (50 ±0)` + // Measured: `979 + v * (50 ±0)` // Estimated: `3510 + v * (2520 ±0)` - // Minimum execution time: 2_512_817_000 picoseconds. - Weight::from_parts(119_401_374, 0) + // Minimum execution time: 2_851_801_000 picoseconds. + Weight::from_parts(4_477_533, 0) .saturating_add(Weight::from_parts(0, 3510)) - // Standard Error: 8_463 - .saturating_add(Weight::from_parts(4_860_364, 0).saturating_mul(v.into())) + // Standard Error: 8_644 + .saturating_add(Weight::from_parts(5_811_682, 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())) @@ -721,8 +723,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_686_000 picoseconds. - Weight::from_parts(3_881_000, 0) + // Minimum execution time: 4_250_000 picoseconds. + Weight::from_parts(4_472_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(7)) } @@ -744,8 +746,8 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 3_143_000 picoseconds. - Weight::from_parts(3_424_000, 0) + // Minimum execution time: 3_986_000 picoseconds. + Weight::from_parts(4_144_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(7)) } @@ -773,10 +775,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: `1870` + // Measured: `1903` // Estimated: `6248` - // Minimum execution time: 66_946_000 picoseconds. - Weight::from_parts(69_382_000, 0) + // Minimum execution time: 87_291_000 picoseconds. + Weight::from_parts(89_344_000, 0) .saturating_add(Weight::from_parts(0, 6248)) .saturating_add(T::DbWeight::get().reads(12)) .saturating_add(T::DbWeight::get().writes(6)) @@ -787,10 +789,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: `658` + // Measured: `691` // Estimated: `3510` - // Minimum execution time: 11_278_000 picoseconds. - Weight::from_parts(11_603_000, 0) + // Minimum execution time: 16_113_000 picoseconds. + Weight::from_parts(16_593_000, 0) .saturating_add(Weight::from_parts(0, 3510)) .saturating_add(T::DbWeight::get().reads(2)) .saturating_add(T::DbWeight::get().writes(1)) @@ -801,33 +803,53 @@ impl pallet_staking::WeightInfo for WeightInfo { // Proof Size summary in bytes: // Measured: `0` // Estimated: `0` - // Minimum execution time: 1_963_000 picoseconds. - Weight::from_parts(2_077_000, 0) + // Minimum execution time: 2_433_000 picoseconds. + Weight::from_parts(2_561_000, 0) .saturating_add(Weight::from_parts(0, 0)) .saturating_add(T::DbWeight::get().writes(1)) } - /// 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) + /// 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) + /// Proof: `Balances::Locks` (`max_values`: None, `max_size`: Some(1299), added: 3774, 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: `Balances::Freezes` (r:1 w:0) - /// Proof: `Balances::Freezes` (`max_values`: None, `max_size`: Some(67), added: 2542, mode: `MaxEncodedLen`) fn restore_ledger() -> Weight { // Proof Size summary in bytes: - // Measured: `1014` + // Measured: `1040` // Estimated: `4764` - // Minimum execution time: 40_258_000 picoseconds. - Weight::from_parts(41_210_000, 0) + // 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(5)) - .saturating_add(T::DbWeight::get().writes(4)) + .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 { - // will be auto-generated - Default::default() + // Proof Size summary in bytes: + // Measured: `1209` + // Estimated: `4764` + // Minimum execution time: 91_790_000 picoseconds. + Weight::from_parts(92_991_000, 0) + .saturating_add(Weight::from_parts(0, 4764)) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(2)) } } From b3352dd41dddbc7e349d8b56df1e9a4ee8c62c2b Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 18 Sep 2024 14:30:16 +0200 Subject: [PATCH 50/56] comment about ignoring resolve err --- substrate/frame/treasury/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/substrate/frame/treasury/src/lib.rs b/substrate/frame/treasury/src/lib.rs index fd948d82e0ba..6617e796c8cb 100644 --- a/substrate/frame/treasury/src/lib.rs +++ b/substrate/frame/treasury/src/lib.rs @@ -995,6 +995,7 @@ impl OnUnbalanced> for FungibleComp use frame_support::traits::fungible::Balanced; let numeric_amount = credit.peek(); + // can't do much if following errors since the calling function is infallible. let _ = T::Currency::resolve(&Pallet::::account_id(), credit); Pallet::::deposit_event(Event::Deposit { value: numeric_amount }); From f0d2d148c641596d2b51fb59ee400f75a51ca15a Mon Sep 17 00:00:00 2001 From: Ankan Date: Wed, 18 Sep 2024 14:34:48 +0200 Subject: [PATCH 51/56] total balance for ED --- substrate/frame/support/src/traits/tokens/fungible/regular.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/substrate/frame/support/src/traits/tokens/fungible/regular.rs b/substrate/frame/support/src/traits/tokens/fungible/regular.rs index 29f907ce2654..836602219fff 100644 --- a/substrate/frame/support/src/traits/tokens/fungible/regular.rs +++ b/substrate/frame/support/src/traits/tokens/fungible/regular.rs @@ -213,8 +213,8 @@ pub trait Unbalanced: Inspect { } else { old_balance.checked_add(&amount).ok_or(ArithmeticError::Overflow)? }; - // FIXME(ank4n): add test for this case - // look at total balance to ensure ED is respected + + // look at total balance to ensure ED is respected. let new_total_balance = amount.saturating_add(Self::total_balance(who)); if new_total_balance < Self::minimum_balance() { // Attempt to increase from 0 to below minimum -> stays at zero. From 3ca1081bb56f1c15c8dbea61925e9e0f633466b4 Mon Sep 17 00:00:00 2001 From: Ankan Date: Thu, 19 Sep 2024 12:22:38 +0200 Subject: [PATCH 52/56] ensure ti is updated at reward --- substrate/frame/staking/src/tests.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 6d5cca4f3984..3c2233cea736 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -361,8 +361,16 @@ 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, @@ -402,6 +410,7 @@ 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), From 7a16988e726a9a29d51b70a2e5e44185fb94e0d2 Mon Sep 17 00:00:00 2001 From: Ankan Date: Thu, 19 Sep 2024 12:31:07 +0200 Subject: [PATCH 53/56] make slash resolve to treasury defensive --- substrate/frame/treasury/src/lib.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/substrate/frame/treasury/src/lib.rs b/substrate/frame/treasury/src/lib.rs index 6617e796c8cb..b4c1a02a1970 100644 --- a/substrate/frame/treasury/src/lib.rs +++ b/substrate/frame/treasury/src/lib.rs @@ -96,8 +96,8 @@ use frame_support::{ dispatch::{DispatchResult, DispatchResultWithPostInfo}, ensure, print, traits::{ - fungible::Credit, tokens::Pay, Currency, ExistenceRequirement::KeepAlive, Get, Imbalance, - OnUnbalanced, ReservableCurrency, WithdrawReasons, + fungible::Credit, tokens::Pay, Currency, Defensive, ExistenceRequirement::KeepAlive, Get, + Imbalance, OnUnbalanced, ReservableCurrency, WithdrawReasons, }, weights::Weight, BoundedVec, PalletId, @@ -995,8 +995,7 @@ impl OnUnbalanced> for FungibleComp use frame_support::traits::fungible::Balanced; let numeric_amount = credit.peek(); - // can't do much if following errors since the calling function is infallible. - let _ = T::Currency::resolve(&Pallet::::account_id(), credit); + let _ = T::Currency::resolve(&Pallet::::account_id(), credit).defensive(); Pallet::::deposit_event(Event::Deposit { value: numeric_amount }); } From d67069a5f11f17fe2fc248c31010b06a8c6eb171 Mon Sep 17 00:00:00 2001 From: Ankan Date: Fri, 20 Sep 2024 18:37:53 +0200 Subject: [PATCH 54/56] migrate virtual stakers code --- substrate/frame/staking/src/pallet/impls.rs | 34 +++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index cd223c319ff3..fc7a7aa66c17 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -1159,8 +1159,38 @@ impl Pallet { } pub(super) fn do_migrate_currency(stash: &T::AccountId) -> DispatchResult { - // we can't do anything for virtual stakers since their funds are not managed/held by - // this pallet. + if Self::is_virtual_staker(stash) { + // 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(()) + } + ensure!(!Self::is_virtual_staker(stash), Error::::VirtualStakerNotAllowed); let ledger = Self::ledger(Stash(stash.clone()))?; let locked: BalanceOf = T::OldCurrency::balance_locked(STAKING_ID, stash).into(); From 39f520ba320c94b6ac1d773ec92631f515e5b9b3 Mon Sep 17 00:00:00 2001 From: Ankan Date: Fri, 20 Sep 2024 19:14:44 +0200 Subject: [PATCH 55/56] add test for migration of virtual stakers --- substrate/frame/staking/src/mock.rs | 4 ---- substrate/frame/staking/src/tests.rs | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index 894a9b9747b9..048735030e02 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -602,10 +602,6 @@ 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)); diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index 3c2233cea736..bc5664b2a14e 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -8554,5 +8554,27 @@ mod hold_migration { // 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"); + + // 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)); + }); + } } } From 0f01445db1973097cc6cb4ebf5a3973d91f62d6f Mon Sep 17 00:00:00 2001 From: Ankan Date: Fri, 20 Sep 2024 19:26:47 +0200 Subject: [PATCH 56/56] add more cases to virtual staker migration --- substrate/frame/staking/src/tests.rs | 48 +++++++++++++++++++++------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/substrate/frame/staking/src/tests.rs b/substrate/frame/staking/src/tests.rs index bc5664b2a14e..5be4ba6d0c94 100644 --- a/substrate/frame/staking/src/tests.rs +++ b/substrate/frame/staking/src/tests.rs @@ -8554,19 +8554,21 @@ mod hold_migration { // 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]); + #[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"); + // 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)); @@ -8575,6 +8577,30 @@ mod hold_migration { assert_eq!(System::providers(&200), 0); assert!(!System::account_exists(&200)); }); - } + + 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); + }); } }