mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-17 21:51:06 +00:00
Only maintain at most 1 UnlockChunk per era (#10670)
* Only maintain at most 1 `UnlockChunk` per era * Bound `unlocking` * Run cargo +nightly-2021-10-29 fmt * Make benchmarks stuff compile * Update frame/staking/src/lib.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Remove DerefMut; Implement neccesary methods directly * Doc comments for new BoundedVec methods * Fix benchmarks * wip bonded_vec macro * Correct rust doc * Apply suggestions from code review Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update staking::Config impls * Add MaxUnlockingChunks to more places * Use defensive saturating add * FMT Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
@@ -928,7 +928,7 @@ impl<T: Config> ElectionDataProvider for Pallet<T> {
|
||||
stash: voter.clone(),
|
||||
active: stake,
|
||||
total: stake,
|
||||
unlocking: vec![],
|
||||
unlocking: Default::default(),
|
||||
claimed_rewards: vec![],
|
||||
},
|
||||
);
|
||||
@@ -946,7 +946,7 @@ impl<T: Config> ElectionDataProvider for Pallet<T> {
|
||||
stash: target.clone(),
|
||||
active: stake,
|
||||
total: stake,
|
||||
unlocking: vec![],
|
||||
unlocking: Default::default(),
|
||||
claimed_rewards: vec![],
|
||||
},
|
||||
);
|
||||
@@ -983,7 +983,7 @@ impl<T: Config> ElectionDataProvider for Pallet<T> {
|
||||
stash: v.clone(),
|
||||
active: stake,
|
||||
total: stake,
|
||||
unlocking: vec![],
|
||||
unlocking: Default::default(),
|
||||
claimed_rewards: vec![],
|
||||
},
|
||||
);
|
||||
@@ -1004,7 +1004,7 @@ impl<T: Config> ElectionDataProvider for Pallet<T> {
|
||||
stash: v.clone(),
|
||||
active: stake,
|
||||
total: stake,
|
||||
unlocking: vec![],
|
||||
unlocking: Default::default(),
|
||||
claimed_rewards: vec![],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -21,8 +21,8 @@ use frame_election_provider_support::SortedListProvider;
|
||||
use frame_support::{
|
||||
pallet_prelude::*,
|
||||
traits::{
|
||||
Currency, CurrencyToVote, EnsureOrigin, EstimateNextNewSession, Get, LockIdentifier,
|
||||
LockableCurrency, OnUnbalanced, UnixTime,
|
||||
Currency, CurrencyToVote, DefensiveSaturating, EnsureOrigin, EstimateNextNewSession, Get,
|
||||
LockIdentifier, LockableCurrency, OnUnbalanced, UnixTime,
|
||||
},
|
||||
weights::Weight,
|
||||
};
|
||||
@@ -40,12 +40,11 @@ pub use impls::*;
|
||||
|
||||
use crate::{
|
||||
log, slashing, weights::WeightInfo, ActiveEraInfo, BalanceOf, EraPayout, EraRewardPoints,
|
||||
Exposure, Forcing, NegativeImbalanceOf, Nominations, PositiveImbalanceOf, Releases,
|
||||
RewardDestination, SessionInterface, StakingLedger, UnappliedSlash, UnlockChunk,
|
||||
Exposure, Forcing, MaxUnlockingChunks, NegativeImbalanceOf, Nominations, PositiveImbalanceOf,
|
||||
Releases, RewardDestination, SessionInterface, StakingLedger, UnappliedSlash, UnlockChunk,
|
||||
ValidatorPrefs,
|
||||
};
|
||||
|
||||
pub const MAX_UNLOCKING_CHUNKS: usize = 32;
|
||||
const STAKING_ID: LockIdentifier = *b"staking ";
|
||||
|
||||
#[frame_support::pallet]
|
||||
@@ -157,6 +156,10 @@ pub mod pallet {
|
||||
/// the bags-list is not desired, [`impls::UseNominatorsMap`] is likely the desired option.
|
||||
type SortedListProvider: SortedListProvider<Self::AccountId>;
|
||||
|
||||
/// The maximum number of `unlocking` chunks a [`StakingLedger`] can have. Effectively
|
||||
/// determines how many unique eras a staker may be unbonding in.
|
||||
type MaxUnlockingChunks: Get<u32>;
|
||||
|
||||
/// Some parameters of the benchmarking.
|
||||
type BenchmarkingConfig: BenchmarkingConfig;
|
||||
|
||||
@@ -772,7 +775,7 @@ pub mod pallet {
|
||||
stash,
|
||||
total: value,
|
||||
active: value,
|
||||
unlocking: vec![],
|
||||
unlocking: Default::default(),
|
||||
claimed_rewards: (last_reward_era..current_era).collect(),
|
||||
};
|
||||
Self::update_ledger(&controller, &item);
|
||||
@@ -837,7 +840,7 @@ pub mod pallet {
|
||||
/// Once the unlock period is done, you can call `withdraw_unbonded` to actually move
|
||||
/// the funds out of management ready for transfer.
|
||||
///
|
||||
/// No more than a limited number of unlocking chunks (see `MAX_UNLOCKING_CHUNKS`)
|
||||
/// No more than a limited number of unlocking chunks (see `MaxUnlockingChunks`)
|
||||
/// can co-exists at the same time. In that case, [`Call::withdraw_unbonded`] need
|
||||
/// to be called first to remove some of the chunks (if possible).
|
||||
///
|
||||
@@ -854,7 +857,10 @@ pub mod pallet {
|
||||
) -> DispatchResult {
|
||||
let controller = ensure_signed(origin)?;
|
||||
let mut ledger = Self::ledger(&controller).ok_or(Error::<T>::NotController)?;
|
||||
ensure!(ledger.unlocking.len() < MAX_UNLOCKING_CHUNKS, Error::<T>::NoMoreChunks,);
|
||||
ensure!(
|
||||
ledger.unlocking.len() < MaxUnlockingChunks::get() as usize,
|
||||
Error::<T>::NoMoreChunks,
|
||||
);
|
||||
|
||||
let mut value = value.min(ledger.active);
|
||||
|
||||
@@ -881,7 +887,19 @@ pub mod pallet {
|
||||
|
||||
// Note: in case there is no current era it is fine to bond one era more.
|
||||
let era = Self::current_era().unwrap_or(0) + T::BondingDuration::get();
|
||||
ledger.unlocking.push(UnlockChunk { value, era });
|
||||
if let Some(mut chunk) =
|
||||
ledger.unlocking.last_mut().filter(|chunk| chunk.era == era)
|
||||
{
|
||||
// To keep the chunk count down, we only keep one chunk per era. Since
|
||||
// `unlocking` is a FiFo queue, if a chunk exists for `era` we know that it will
|
||||
// be the last one.
|
||||
chunk.value = chunk.value.defensive_saturating_add(value)
|
||||
} else {
|
||||
ledger
|
||||
.unlocking
|
||||
.try_push(UnlockChunk { value, era })
|
||||
.map_err(|_| Error::<T>::NoMoreChunks)?;
|
||||
};
|
||||
// NOTE: ledger must be updated prior to calling `Self::weight_of`.
|
||||
Self::update_ledger(&controller, &ledger);
|
||||
|
||||
@@ -1348,10 +1366,10 @@ pub mod pallet {
|
||||
///
|
||||
/// # <weight>
|
||||
/// - Time complexity: O(L), where L is unlocking chunks
|
||||
/// - Bounded by `MAX_UNLOCKING_CHUNKS`.
|
||||
/// - Bounded by `MaxUnlockingChunks`.
|
||||
/// - Storage changes: Can't increase storage, only decrease it.
|
||||
/// # </weight>
|
||||
#[pallet::weight(T::WeightInfo::rebond(MAX_UNLOCKING_CHUNKS as u32))]
|
||||
#[pallet::weight(T::WeightInfo::rebond(MaxUnlockingChunks::get() as u32))]
|
||||
pub fn rebond(
|
||||
origin: OriginFor<T>,
|
||||
#[pallet::compact] value: BalanceOf<T>,
|
||||
|
||||
Reference in New Issue
Block a user