Allow nomination pools to chill + fix dismantle scenario (#11426)

* make pool roles optional

* undo lock file changes?

* add migration

* add the ability for pools to chill themselves

* boilerplate of tests

* somewhat stable, but I think I found another bug as well

* Fix it all

* Add more more sophisticated test + capture one more bug.

* Update frame/staking/src/lib.rs

* reduce the diff a little bit

* add some test for the slashing bug

* cleanup

* fix lock file?

* Fix

* fmt

* Update frame/nomination-pools/src/lib.rs

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Update frame/nomination-pools/src/lib.rs

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Update frame/nomination-pools/src/lib.rs

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Update frame/nomination-pools/src/mock.rs

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>

* Fix build

* fix some fishy tests..

* add one last integrity check for MinCreateBond

* remove bad assertion -- needs to be dealt with later

* nits

* fix tests and add benchmarks for chill

* remove stuff

* fix benchmarks

* cargo run --quiet --profile=production  --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark pallet --chain=dev --steps=50 --repeat=20 --pallet=pallet_nomination_pools --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/nomination-pools/src/weights.rs --template=./.maintain/frame-weight-template.hbs

* remove defensive

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
Co-authored-by: Parity Bot <admin@parity.io>
This commit is contained in:
Kian Paimani
2022-06-13 22:07:36 +01:00
committed by GitHub
parent 19684de7d8
commit ad1d171601
18 changed files with 1434 additions and 635 deletions
+123 -30
View File
@@ -447,21 +447,27 @@ impl<T: Config> PoolMember<T> {
.fold(BalanceOf::<T>::zero(), |acc, (_, v)| acc.saturating_add(*v))
}
/// Try and unbond `points` from self, with the given target unbonding era.
/// Try and unbond `points_dissolved` from self, and in return mint `points_issued` into the
/// corresponding `era`'s unlock schedule.
///
/// In the absence of slashing, these two points are always the same. In the presence of
/// slashing, the value of points in different pools varies.
///
/// Returns `Ok(())` and updates `unbonding_eras` and `points` if success, `Err(_)` otherwise.
fn try_unbond(
&mut self,
points: BalanceOf<T>,
points_dissolved: BalanceOf<T>,
points_issued: BalanceOf<T>,
unbonding_era: EraIndex,
) -> Result<(), Error<T>> {
if let Some(new_points) = self.points.checked_sub(&points) {
if let Some(new_points) = self.points.checked_sub(&points_dissolved) {
match self.unbonding_eras.get_mut(&unbonding_era) {
Some(already_unbonding_points) =>
*already_unbonding_points = already_unbonding_points.saturating_add(points),
*already_unbonding_points =
already_unbonding_points.saturating_add(points_issued),
None => self
.unbonding_eras
.try_insert(unbonding_era, points)
.try_insert(unbonding_era, points_issued)
.map(|old| {
if old.is_some() {
defensive!("value checked to not exist in the map; qed");
@@ -721,9 +727,13 @@ impl<T: Config> BondedPool<T> {
}
fn is_destroying_and_only_depositor(&self, alleged_depositor_points: BalanceOf<T>) -> bool {
// NOTE: if we add `&& self.member_counter == 1`, then this becomes even more strict and
// ensures that there are no unbonding members hanging around either.
self.is_destroying() && self.points == alleged_depositor_points
// we need to ensure that `self.member_counter == 1` as well, because the depositor's
// initial `MinCreateBond` (or more) is what guarantees that the ledger of the pool does not
// get killed in the staking system, and that it does not fall below `MinimumNominatorBond`,
// which could prevent other non-depositor members from fully leaving. Thus, all members
// must withdraw, then depositor can unbond, and finally withdraw after waiting another
// cycle.
self.is_destroying() && self.points == alleged_depositor_points && self.member_counter == 1
}
/// Whether or not the pool is ok to be in `PoolSate::Open`. If this returns an `Err`, then the
@@ -984,10 +994,14 @@ impl<T: Config> UnbondPool<T> {
Pallet::<T>::point_to_balance(self.balance, self.points, points)
}
/// Issue points and update the balance given `new_balance`.
fn issue(&mut self, new_funds: BalanceOf<T>) {
self.points = self.points.saturating_add(self.balance_to_point(new_funds));
/// Issue the equivalent points of `new_funds` into self.
///
/// Returns the actual amounts of points issued.
fn issue(&mut self, new_funds: BalanceOf<T>) -> BalanceOf<T> {
let new_points = self.balance_to_point(new_funds);
self.points = self.points.saturating_add(new_points);
self.balance = self.balance.saturating_add(new_funds);
new_points
}
/// Dissolve some points from the unbonding pool, reducing the balance of the pool
@@ -1150,6 +1164,9 @@ pub mod pallet {
///
/// This is the amount that the depositor must put as their initial stake in the pool, as an
/// indication of "skin in the game".
///
/// This is the value that will always exist in the staking ledger of the pool bonded account
/// while all other accounts leave.
#[pallet::storage]
pub type MinCreateBond<T: Config> = StorageValue<_, BalanceOf<T>, ValueQuery>;
@@ -1256,9 +1273,34 @@ pub mod pallet {
/// A payout has been made to a member.
PaidOut { member: T::AccountId, pool_id: PoolId, payout: BalanceOf<T> },
/// A member has unbonded from their pool.
Unbonded { member: T::AccountId, pool_id: PoolId, amount: BalanceOf<T> },
///
/// - `balance` is the corresponding balance of the number of points that has been
/// requested to be unbonded (the argument of the `unbond` transaction) from the bonded
/// pool.
/// - `points` is the number of points that are issued as a result of `balance` being
/// dissolved into the corresponding unbonding pool.
///
/// In the absence of slashing, these values will match. In the presence of slashing, the
/// number of points that are issued in the unbonding pool will be less than the amount
/// requested to be unbonded.
Unbonded {
member: T::AccountId,
pool_id: PoolId,
balance: BalanceOf<T>,
points: BalanceOf<T>,
},
/// A member has withdrawn from their pool.
Withdrawn { member: T::AccountId, pool_id: PoolId, amount: BalanceOf<T> },
///
/// The given number of `points` have been dissolved in return of `balance`.
///
/// Similar to `Unbonded` event, in the absence of slashing, the ratio of point to balance
/// will be 1.
Withdrawn {
member: T::AccountId,
pool_id: PoolId,
balance: BalanceOf<T>,
points: BalanceOf<T>,
},
/// A pool has been destroyed.
Destroyed { pool_id: PoolId },
/// The state of a pool has changed
@@ -1274,6 +1316,10 @@ pub mod pallet {
state_toggler: Option<T::AccountId>,
nominator: Option<T::AccountId>,
},
/// The active balance of pool `pool_id` has been slashed to `balance`.
PoolSlashed { pool_id: PoolId, balance: BalanceOf<T> },
/// The unbond pool at `era` of pool `pool_id` has been slashed to `balance`.
UnbondingPoolSlashed { pool_id: PoolId, era: EraIndex, balance: BalanceOf<T> },
}
#[pallet::error]
@@ -1290,10 +1336,6 @@ pub mod pallet {
/// An account is already delegating in another pool. An account may only belong to one
/// pool at a time.
AccountBelongsToOtherPool,
/// The pool has insufficient balance to bond as a nominator.
InsufficientBond,
/// The member is already unbonding in this era.
AlreadyUnbonding,
/// The member is fully unbonded (and thus cannot access the bonded and reward pool
/// anymore to, for example, collect rewards).
FullyUnbonding,
@@ -1346,6 +1388,9 @@ pub mod pallet {
RewardPoolNotFound,
/// A sub pool does not exist.
SubPoolsNotFound,
/// The bonded account should only be killed by the staking system when the depositor is
/// withdrawing
BondedStashKilledPrematurely,
}
impl<T> From<DefensiveError> for Error<T> {
@@ -1477,7 +1522,7 @@ pub mod pallet {
/// Unbond up to `unbonding_points` of the `member_account`'s funds from the pool. It
/// implicitly collects the rewards one last time, since not doing so would mean some
/// rewards would go forfeited.
/// rewards would be forfeited.
///
/// Under certain conditions, this call can be dispatched permissionlessly (i.e. by any
/// account).
@@ -1528,9 +1573,6 @@ pub mod pallet {
let current_era = T::StakingInterface::current_era();
let unbond_era = T::StakingInterface::bonding_duration().saturating_add(current_era);
// Try and unbond in the member map.
member.try_unbond(unbonding_points, unbond_era)?;
// Unbond in the actual underlying nominator.
let unbonding_balance = bonded_pool.dissolve(unbonding_points);
T::StakingInterface::unbond(bonded_pool.bonded_account(), unbonding_balance)?;
@@ -1553,17 +1595,21 @@ pub mod pallet {
})?;
}
sub_pools
let points_unbonded = sub_pools
.with_era
.get_mut(&unbond_era)
// The above check ensures the pool exists.
.defensive_ok_or::<Error<T>>(DefensiveError::PoolNotFound.into())?
.issue(unbonding_balance);
// Try and unbond in the member map.
member.try_unbond(unbonding_points, points_unbonded, unbond_era)?;
Self::deposit_event(Event::<T>::Unbonded {
member: member_account.clone(),
pool_id: member.pool_id,
amount: unbonding_balance,
points: points_unbonded,
balance: unbonding_balance,
});
// Now that we know everything has worked write the items to storage.
@@ -1644,14 +1690,23 @@ pub mod pallet {
// Before calculate the `balance_to_unbond`, with call withdraw unbonded to ensure the
// `transferrable_balance` is correct.
T::StakingInterface::withdraw_unbonded(
let stash_killed = T::StakingInterface::withdraw_unbonded(
bonded_pool.bonded_account(),
num_slashing_spans,
)?;
// defensive-only: the depositor puts enough funds into the stash so that it will only
// be destroyed when they are leaving.
ensure!(
!stash_killed || caller == bonded_pool.roles.depositor,
Error::<T>::Defensive(DefensiveError::BondedStashKilledPrematurely)
);
let mut sum_unlocked_points: BalanceOf<T> = Zero::zero();
let balance_to_unbond = withdrawn_points
.iter()
.fold(BalanceOf::<T>::zero(), |accumulator, (era, unlocked_points)| {
sum_unlocked_points = sum_unlocked_points.saturating_add(*unlocked_points);
if let Some(era_pool) = sub_pools.with_era.get_mut(&era) {
let balance_to_unbond = era_pool.dissolve(*unlocked_points);
if era_pool.points.is_zero() {
@@ -1684,7 +1739,8 @@ pub mod pallet {
Self::deposit_event(Event::<T>::Withdrawn {
member: member_account.clone(),
pool_id: member.pool_id,
amount: balance_to_unbond,
points: sum_unlocked_points,
balance: balance_to_unbond,
});
let post_info_weight = if member.total_points().is_zero() {
@@ -1811,6 +1867,13 @@ pub mod pallet {
Ok(())
}
/// Nominate on behalf of the pool.
///
/// The dispatch origin of this call must be signed by the pool nominator or the pool
/// root role.
///
/// This directly forward the call to the staking pallet, on behalf of the pool bonded
/// account.
#[pallet::weight(T::WeightInfo::nominate(validators.len() as u32))]
pub fn nominate(
origin: OriginFor<T>,
@@ -1820,10 +1883,13 @@ pub mod pallet {
let who = ensure_signed(origin)?;
let bonded_pool = BondedPool::<T>::get(pool_id).ok_or(Error::<T>::PoolNotFound)?;
ensure!(bonded_pool.can_nominate(&who), Error::<T>::NotNominator);
T::StakingInterface::nominate(bonded_pool.bonded_account(), validators)?;
Ok(())
T::StakingInterface::nominate(bonded_pool.bonded_account(), validators)
}
/// Set a new state for the pool.
///
/// The dispatch origin of this call must be signed by the state toggler, or the root role
/// of the pool.
#[pallet::weight(T::WeightInfo::set_state())]
pub fn set_state(
origin: OriginFor<T>,
@@ -1850,6 +1916,10 @@ pub mod pallet {
Ok(())
}
/// Set a new metadata for the pool.
///
/// The dispatch origin of this call must be signed by the state toggler, or the root role
/// of the pool.
#[pallet::weight(T::WeightInfo::set_metadata(metadata.len() as u32))]
pub fn set_metadata(
origin: OriginFor<T>,
@@ -1961,6 +2031,21 @@ pub mod pallet {
bonded_pool.put();
Ok(())
}
/// Chill on behalf of the pool.
///
/// The dispatch origin of this call must be signed by the pool nominator or the pool
/// root role, same as [`Pallet::nominate`].
///
/// This directly forward the call to the staking pallet, on behalf of the pool bonded
/// account.
#[pallet::weight(T::WeightInfo::chill())]
pub fn chill(origin: OriginFor<T>, pool_id: PoolId) -> DispatchResult {
let who = ensure_signed(origin)?;
let bonded_pool = BondedPool::<T>::get(pool_id).ok_or(Error::<T>::PoolNotFound)?;
ensure!(bonded_pool.can_nominate(&who), Error::<T>::NotNominator);
T::StakingInterface::chill(bonded_pool.bonded_account())
}
}
#[pallet::hooks]
@@ -2175,6 +2260,7 @@ impl<T: Config> Pallet<T> {
if reward_pool.total_earnings == BalanceOf::<T>::max_value() {
bonded_pool.set_state(PoolState::Destroying);
};
member.reward_pool_total_earnings = reward_pool.total_earnings;
reward_pool.points = current_points.saturating_sub(member_virtual_points);
reward_pool.balance = reward_pool.balance.saturating_sub(member_payout);
@@ -2355,19 +2441,26 @@ impl<T: Config> OnStakerSlash<T::AccountId, BalanceOf<T>> for Pallet<T> {
pool_account: &T::AccountId,
// Bonded balance is always read directly from staking, therefore we need not update
// anything here.
_slashed_bonded: BalanceOf<T>,
slashed_bonded: BalanceOf<T>,
slashed_unlocking: &BTreeMap<EraIndex, BalanceOf<T>>,
) {
if let Some(pool_id) = ReversePoolIdLookup::<T>::get(pool_account).defensive() {
if let Some(pool_id) = ReversePoolIdLookup::<T>::get(pool_account) {
let mut sub_pools = match SubPoolsStorage::<T>::get(pool_id).defensive() {
Some(sub_pools) => sub_pools,
None => return,
};
for (era, slashed_balance) in slashed_unlocking.iter() {
if let Some(pool) = sub_pools.with_era.get_mut(era) {
pool.balance = *slashed_balance
pool.balance = *slashed_balance;
Self::deposit_event(Event::<T>::UnbondingPoolSlashed {
era: *era,
pool_id,
balance: *slashed_balance,
});
}
}
Self::deposit_event(Event::<T>::PoolSlashed { pool_id, balance: slashed_bonded });
SubPoolsStorage::<T>::insert(pool_id, sub_pools);
}
}
+47 -19
View File
@@ -2,7 +2,6 @@ use super::*;
use crate::{self as pools};
use frame_support::{assert_ok, parameter_types, PalletId};
use frame_system::RawOrigin;
use std::collections::HashMap;
pub type AccountId = u128;
pub type Balance = u128;
@@ -20,17 +19,19 @@ pub fn default_reward_account() -> AccountId {
parameter_types! {
pub static CurrentEra: EraIndex = 0;
pub static BondingDuration: EraIndex = 3;
static BondedBalanceMap: HashMap<AccountId, Balance> = Default::default();
static UnbondingBalanceMap: HashMap<AccountId, Balance> = Default::default();
pub storage BondedBalanceMap: BTreeMap<AccountId, Balance> = Default::default();
pub storage UnbondingBalanceMap: BTreeMap<AccountId, Balance> = Default::default();
#[derive(Clone, PartialEq)]
pub static MaxUnbonding: u32 = 8;
pub static Nominations: Vec<AccountId> = vec![];
pub storage Nominations: Option<Vec<AccountId>> = None;
}
pub struct StakingMock;
impl StakingMock {
pub(crate) fn set_bonded_balance(who: AccountId, bonded: Balance) {
BONDED_BALANCE_MAP.with(|m| m.borrow_mut().insert(who, bonded));
let mut x = BondedBalanceMap::get();
x.insert(who, bonded);
BondedBalanceMap::set(&x)
}
}
@@ -66,22 +67,33 @@ impl sp_staking::StakingInterface for StakingMock {
}
fn bond_extra(who: Self::AccountId, extra: Self::Balance) -> DispatchResult {
BONDED_BALANCE_MAP.with(|m| *m.borrow_mut().get_mut(&who).unwrap() += extra);
let mut x = BondedBalanceMap::get();
x.get_mut(&who).map(|v| *v += extra);
BondedBalanceMap::set(&x);
Ok(())
}
fn unbond(who: Self::AccountId, amount: Self::Balance) -> DispatchResult {
BONDED_BALANCE_MAP.with(|m| *m.borrow_mut().get_mut(&who).unwrap() -= amount);
UNBONDING_BALANCE_MAP
.with(|m| *m.borrow_mut().entry(who).or_insert(Self::Balance::zero()) += amount);
let mut x = BondedBalanceMap::get();
*x.get_mut(&who).unwrap() = x.get_mut(&who).unwrap().saturating_sub(amount);
BondedBalanceMap::set(&x);
let mut y = UnbondingBalanceMap::get();
*y.entry(who).or_insert(Self::Balance::zero()) += amount;
UnbondingBalanceMap::set(&y);
Ok(())
}
fn withdraw_unbonded(who: Self::AccountId, _: u32) -> Result<u64, DispatchError> {
// Simulates removing unlocking chunks and only having the bonded balance locked
let _maybe_new_free = UNBONDING_BALANCE_MAP.with(|m| m.borrow_mut().remove(&who));
fn chill(_: Self::AccountId) -> sp_runtime::DispatchResult {
Ok(())
}
Ok(100)
fn withdraw_unbonded(who: Self::AccountId, _: u32) -> Result<bool, DispatchError> {
// Simulates removing unlocking chunks and only having the bonded balance locked
let mut x = UnbondingBalanceMap::get();
x.remove(&who);
UnbondingBalanceMap::set(&x);
Ok(UnbondingBalanceMap::get().is_empty() && BondedBalanceMap::get().is_empty())
}
fn bond(
@@ -95,9 +107,13 @@ impl sp_staking::StakingInterface for StakingMock {
}
fn nominate(_: Self::AccountId, nominations: Vec<Self::AccountId>) -> DispatchResult {
Nominations::set(nominations);
Nominations::set(&Some(nominations));
Ok(())
}
fn nominations(_: Self::AccountId) -> Option<Vec<Self::AccountId>> {
Nominations::get()
}
}
impl frame_system::Config for Runtime {
@@ -162,7 +178,6 @@ parameter_types! {
pub static MaxMetadataLen: u32 = 2;
pub static CheckLevel: u8 = 255;
pub const PoolsPalletId: PalletId = PalletId(*b"py/nopls");
pub const MinPointsToBalance: u32 = 10;
}
impl pools::Config for Runtime {
type Event = Event;
@@ -175,7 +190,7 @@ impl pools::Config for Runtime {
type PalletId = PoolsPalletId;
type MaxMetadataLen = MaxMetadataLen;
type MaxUnbonding = MaxUnbonding;
type MinPointsToBalance = MinPointsToBalance;
type MinPointsToBalance = frame_support::traits::ConstU32<10>;
}
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
@@ -265,7 +280,8 @@ pub(crate) fn unsafe_set_state(pool_id: PoolId, state: PoolState) -> Result<(),
}
parameter_types! {
static ObservedEvents: usize = 0;
static PoolsEvents: usize = 0;
static BalancesEvents: usize = 0;
}
/// All events of this pallet.
@@ -275,8 +291,20 @@ pub(crate) fn pool_events_since_last_call() -> Vec<super::Event<Runtime>> {
.map(|r| r.event)
.filter_map(|e| if let Event::Pools(inner) = e { Some(inner) } else { None })
.collect::<Vec<_>>();
let already_seen = ObservedEvents::get();
ObservedEvents::set(events.len());
let already_seen = PoolsEvents::get();
PoolsEvents::set(events.len());
events.into_iter().skip(already_seen).collect()
}
/// All events of the `Balances` pallet.
pub(crate) fn balances_events_since_last_call() -> Vec<pallet_balances::Event<Runtime>> {
let events = System::events()
.into_iter()
.map(|r| r.event)
.filter_map(|e| if let Event::Balances(inner) = e { Some(inner) } else { None })
.collect::<Vec<_>>();
let already_seen = BalancesEvents::get();
BalancesEvents::set(events.len());
events.into_iter().skip(already_seen).collect()
}
File diff suppressed because it is too large Load Diff
+86 -47
View File
@@ -18,11 +18,12 @@
//! Autogenerated weights for pallet_nomination_pools
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
//! DATE: 2022-05-23, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2022-06-10, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! HOSTNAME: `bm3`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz`
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024
// Executed Command:
// ./target/production/substrate
// target/production/substrate
// benchmark
// pallet
// --chain=dev
@@ -32,8 +33,9 @@
// --extrinsic=*
// --execution=wasm
// --wasm-execution=compiled
// --template=./.maintain/frame-weight-template.hbs
// --heap-pages=4096
// --output=./frame/nomination-pools/src/weights.rs
// --template=./.maintain/frame-weight-template.hbs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
@@ -58,6 +60,7 @@ pub trait WeightInfo {
fn set_metadata(n: u32, ) -> Weight;
fn set_configs() -> Weight;
fn update_roles() -> Weight;
fn chill() -> Weight;
}
/// Weights for pallet_nomination_pools using the Substrate node and recommended hardware.
@@ -77,7 +80,7 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: BagsList ListNodes (r:3 w:3)
// Storage: BagsList ListBags (r:2 w:2)
fn join() -> Weight {
(129_124_000 as Weight)
(124_508_000 as Weight)
.saturating_add(T::DbWeight::get().reads(17 as Weight))
.saturating_add(T::DbWeight::get().writes(11 as Weight))
}
@@ -91,7 +94,7 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: BagsList ListNodes (r:3 w:3)
// Storage: BagsList ListBags (r:2 w:2)
fn bond_extra_transfer() -> Weight {
(118_193_000 as Weight)
(115_185_000 as Weight)
.saturating_add(T::DbWeight::get().reads(13 as Weight))
.saturating_add(T::DbWeight::get().writes(12 as Weight))
}
@@ -102,19 +105,19 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: Staking Ledger (r:1 w:1)
// Storage: Staking Bonded (r:1 w:0)
// Storage: Balances Locks (r:1 w:1)
// Storage: BagsList ListNodes (r:2 w:2)
// Storage: BagsList ListNodes (r:3 w:3)
// Storage: BagsList ListBags (r:2 w:2)
fn bond_extra_reward() -> Weight {
(132_390_000 as Weight)
.saturating_add(T::DbWeight::get().reads(13 as Weight))
.saturating_add(T::DbWeight::get().writes(12 as Weight))
(132_723_000 as Weight)
.saturating_add(T::DbWeight::get().reads(14 as Weight))
.saturating_add(T::DbWeight::get().writes(13 as Weight))
}
// Storage: NominationPools PoolMembers (r:1 w:1)
// Storage: NominationPools BondedPools (r:1 w:1)
// Storage: NominationPools RewardPools (r:1 w:1)
// Storage: System Account (r:1 w:1)
fn claim_payout() -> Weight {
(54_743_000 as Weight)
(52_498_000 as Weight)
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(4 as Weight))
}
@@ -133,7 +136,7 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: NominationPools SubPoolsStorage (r:1 w:1)
// Storage: NominationPools CounterForSubPoolsStorage (r:1 w:1)
fn unbond() -> Weight {
(124_684_000 as Weight)
(121_645_000 as Weight)
.saturating_add(T::DbWeight::get().reads(18 as Weight))
.saturating_add(T::DbWeight::get().writes(13 as Weight))
}
@@ -141,10 +144,11 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: Staking Ledger (r:1 w:1)
// Storage: Staking CurrentEra (r:1 w:0)
// Storage: Balances Locks (r:1 w:1)
/// The range of component `s` is `[0, 100]`.
fn pool_withdraw_unbonded(s: u32, ) -> Weight {
(44_259_000 as Weight)
(43_320_000 as Weight)
// Standard Error: 0
.saturating_add((51_000 as Weight).saturating_mul(s as Weight))
.saturating_add((49_000 as Weight).saturating_mul(s as Weight))
.saturating_add(T::DbWeight::get().reads(4 as Weight))
.saturating_add(T::DbWeight::get().writes(2 as Weight))
}
@@ -156,10 +160,11 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: Balances Locks (r:1 w:1)
// Storage: System Account (r:1 w:1)
// Storage: NominationPools CounterForPoolMembers (r:1 w:1)
/// The range of component `s` is `[0, 100]`.
fn withdraw_unbonded_update(s: u32, ) -> Weight {
(84_854_000 as Weight)
// Standard Error: 0
.saturating_add((56_000 as Weight).saturating_mul(s as Weight))
(83_195_000 as Weight)
// Standard Error: 5_000
.saturating_add((57_000 as Weight).saturating_mul(s as Weight))
.saturating_add(T::DbWeight::get().reads(8 as Weight))
.saturating_add(T::DbWeight::get().writes(7 as Weight))
}
@@ -182,8 +187,9 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: NominationPools CounterForSubPoolsStorage (r:1 w:1)
// Storage: NominationPools CounterForBondedPools (r:1 w:1)
// Storage: Staking Payee (r:0 w:1)
/// The range of component `s` is `[0, 100]`.
fn withdraw_unbonded_kill(_s: u32, ) -> Weight {
(146_992_000 as Weight)
(143_495_000 as Weight)
.saturating_add(T::DbWeight::get().reads(19 as Weight))
.saturating_add(T::DbWeight::get().writes(16 as Weight))
}
@@ -210,7 +216,7 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: NominationPools BondedPools (r:1 w:1)
// Storage: Staking Payee (r:0 w:1)
fn create() -> Weight {
(138_099_000 as Weight)
(127_998_000 as Weight)
.saturating_add(T::DbWeight::get().reads(22 as Weight))
.saturating_add(T::DbWeight::get().writes(15 as Weight))
}
@@ -226,10 +232,11 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: BagsList ListBags (r:1 w:1)
// Storage: BagsList CounterForListNodes (r:1 w:1)
// Storage: Staking CounterForNominators (r:1 w:1)
/// The range of component `n` is `[1, 16]`.
fn nominate(n: u32, ) -> Weight {
(50_964_000 as Weight)
// Standard Error: 11_000
.saturating_add((2_333_000 as Weight).saturating_mul(n as Weight))
(49_929_000 as Weight)
// Standard Error: 16_000
.saturating_add((2_319_000 as Weight).saturating_mul(n as Weight))
.saturating_add(T::DbWeight::get().reads(12 as Weight))
.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(n as Weight)))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
@@ -237,15 +244,16 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: NominationPools BondedPools (r:1 w:1)
// Storage: Staking Ledger (r:1 w:0)
fn set_state() -> Weight {
(27_196_000 as Weight)
(27_399_000 as Weight)
.saturating_add(T::DbWeight::get().reads(2 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
// Storage: NominationPools BondedPools (r:1 w:0)
// Storage: NominationPools Metadata (r:1 w:1)
// Storage: NominationPools CounterForMetadata (r:1 w:1)
/// The range of component `n` is `[1, 256]`.
fn set_metadata(n: u32, ) -> Weight {
(15_056_000 as Weight)
(14_813_000 as Weight)
// Standard Error: 0
.saturating_add((1_000 as Weight).saturating_mul(n as Weight))
.saturating_add(T::DbWeight::get().reads(3 as Weight))
@@ -257,15 +265,28 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Storage: NominationPools MinCreateBond (r:0 w:1)
// Storage: NominationPools MaxPools (r:0 w:1)
fn set_configs() -> Weight {
(6_294_000 as Weight)
(6_115_000 as Weight)
.saturating_add(T::DbWeight::get().writes(5 as Weight))
}
// Storage: NominationPools BondedPools (r:1 w:1)
fn update_roles() -> Weight {
(22_444_000 as Weight)
(22_546_000 as Weight)
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
// Storage: NominationPools BondedPools (r:1 w:0)
// Storage: Staking Ledger (r:1 w:0)
// Storage: Staking Validators (r:1 w:0)
// Storage: Staking Nominators (r:1 w:1)
// Storage: Staking CounterForNominators (r:1 w:1)
// Storage: BagsList ListNodes (r:1 w:1)
// Storage: BagsList ListBags (r:1 w:1)
// Storage: BagsList CounterForListNodes (r:1 w:1)
fn chill() -> Weight {
(48_243_000 as Weight)
.saturating_add(T::DbWeight::get().reads(8 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
}
}
// For backwards compatibility and tests
@@ -284,7 +305,7 @@ impl WeightInfo for () {
// Storage: BagsList ListNodes (r:3 w:3)
// Storage: BagsList ListBags (r:2 w:2)
fn join() -> Weight {
(129_124_000 as Weight)
(124_508_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(17 as Weight))
.saturating_add(RocksDbWeight::get().writes(11 as Weight))
}
@@ -298,7 +319,7 @@ impl WeightInfo for () {
// Storage: BagsList ListNodes (r:3 w:3)
// Storage: BagsList ListBags (r:2 w:2)
fn bond_extra_transfer() -> Weight {
(118_193_000 as Weight)
(115_185_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(13 as Weight))
.saturating_add(RocksDbWeight::get().writes(12 as Weight))
}
@@ -309,19 +330,19 @@ impl WeightInfo for () {
// Storage: Staking Ledger (r:1 w:1)
// Storage: Staking Bonded (r:1 w:0)
// Storage: Balances Locks (r:1 w:1)
// Storage: BagsList ListNodes (r:2 w:2)
// Storage: BagsList ListNodes (r:3 w:3)
// Storage: BagsList ListBags (r:2 w:2)
fn bond_extra_reward() -> Weight {
(132_390_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(13 as Weight))
.saturating_add(RocksDbWeight::get().writes(12 as Weight))
(132_723_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(14 as Weight))
.saturating_add(RocksDbWeight::get().writes(13 as Weight))
}
// Storage: NominationPools PoolMembers (r:1 w:1)
// Storage: NominationPools BondedPools (r:1 w:1)
// Storage: NominationPools RewardPools (r:1 w:1)
// Storage: System Account (r:1 w:1)
fn claim_payout() -> Weight {
(54_743_000 as Weight)
(52_498_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
}
@@ -340,7 +361,7 @@ impl WeightInfo for () {
// Storage: NominationPools SubPoolsStorage (r:1 w:1)
// Storage: NominationPools CounterForSubPoolsStorage (r:1 w:1)
fn unbond() -> Weight {
(124_684_000 as Weight)
(121_645_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(18 as Weight))
.saturating_add(RocksDbWeight::get().writes(13 as Weight))
}
@@ -348,10 +369,11 @@ impl WeightInfo for () {
// Storage: Staking Ledger (r:1 w:1)
// Storage: Staking CurrentEra (r:1 w:0)
// Storage: Balances Locks (r:1 w:1)
/// The range of component `s` is `[0, 100]`.
fn pool_withdraw_unbonded(s: u32, ) -> Weight {
(44_259_000 as Weight)
(43_320_000 as Weight)
// Standard Error: 0
.saturating_add((51_000 as Weight).saturating_mul(s as Weight))
.saturating_add((49_000 as Weight).saturating_mul(s as Weight))
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
}
@@ -363,10 +385,11 @@ impl WeightInfo for () {
// Storage: Balances Locks (r:1 w:1)
// Storage: System Account (r:1 w:1)
// Storage: NominationPools CounterForPoolMembers (r:1 w:1)
/// The range of component `s` is `[0, 100]`.
fn withdraw_unbonded_update(s: u32, ) -> Weight {
(84_854_000 as Weight)
// Standard Error: 0
.saturating_add((56_000 as Weight).saturating_mul(s as Weight))
(83_195_000 as Weight)
// Standard Error: 5_000
.saturating_add((57_000 as Weight).saturating_mul(s as Weight))
.saturating_add(RocksDbWeight::get().reads(8 as Weight))
.saturating_add(RocksDbWeight::get().writes(7 as Weight))
}
@@ -389,8 +412,9 @@ impl WeightInfo for () {
// Storage: NominationPools CounterForSubPoolsStorage (r:1 w:1)
// Storage: NominationPools CounterForBondedPools (r:1 w:1)
// Storage: Staking Payee (r:0 w:1)
/// The range of component `s` is `[0, 100]`.
fn withdraw_unbonded_kill(_s: u32, ) -> Weight {
(146_992_000 as Weight)
(143_495_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(19 as Weight))
.saturating_add(RocksDbWeight::get().writes(16 as Weight))
}
@@ -417,7 +441,7 @@ impl WeightInfo for () {
// Storage: NominationPools BondedPools (r:1 w:1)
// Storage: Staking Payee (r:0 w:1)
fn create() -> Weight {
(138_099_000 as Weight)
(127_998_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(22 as Weight))
.saturating_add(RocksDbWeight::get().writes(15 as Weight))
}
@@ -433,10 +457,11 @@ impl WeightInfo for () {
// Storage: BagsList ListBags (r:1 w:1)
// Storage: BagsList CounterForListNodes (r:1 w:1)
// Storage: Staking CounterForNominators (r:1 w:1)
/// The range of component `n` is `[1, 16]`.
fn nominate(n: u32, ) -> Weight {
(50_964_000 as Weight)
// Standard Error: 11_000
.saturating_add((2_333_000 as Weight).saturating_mul(n as Weight))
(49_929_000 as Weight)
// Standard Error: 16_000
.saturating_add((2_319_000 as Weight).saturating_mul(n as Weight))
.saturating_add(RocksDbWeight::get().reads(12 as Weight))
.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(n as Weight)))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
@@ -444,15 +469,16 @@ impl WeightInfo for () {
// Storage: NominationPools BondedPools (r:1 w:1)
// Storage: Staking Ledger (r:1 w:0)
fn set_state() -> Weight {
(27_196_000 as Weight)
(27_399_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
// Storage: NominationPools BondedPools (r:1 w:0)
// Storage: NominationPools Metadata (r:1 w:1)
// Storage: NominationPools CounterForMetadata (r:1 w:1)
/// The range of component `n` is `[1, 256]`.
fn set_metadata(n: u32, ) -> Weight {
(15_056_000 as Weight)
(14_813_000 as Weight)
// Standard Error: 0
.saturating_add((1_000 as Weight).saturating_mul(n as Weight))
.saturating_add(RocksDbWeight::get().reads(3 as Weight))
@@ -464,13 +490,26 @@ impl WeightInfo for () {
// Storage: NominationPools MinCreateBond (r:0 w:1)
// Storage: NominationPools MaxPools (r:0 w:1)
fn set_configs() -> Weight {
(6_294_000 as Weight)
(6_115_000 as Weight)
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
}
// Storage: NominationPools BondedPools (r:1 w:1)
fn update_roles() -> Weight {
(22_444_000 as Weight)
(22_546_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
// Storage: NominationPools BondedPools (r:1 w:0)
// Storage: Staking Ledger (r:1 w:0)
// Storage: Staking Validators (r:1 w:0)
// Storage: Staking Nominators (r:1 w:1)
// Storage: Staking CounterForNominators (r:1 w:1)
// Storage: BagsList ListNodes (r:1 w:1)
// Storage: BagsList ListBags (r:1 w:1)
// Storage: BagsList CounterForListNodes (r:1 w:1)
fn chill() -> Weight {
(48_243_000 as Weight)
.saturating_add(RocksDbWeight::get().reads(8 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
}
}