mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-16 19:01:02 +00:00
Automatic withdraw_unbonded upon unbond (#12582)
* Prevents max unbonding chunk slots from being filled when unbonding in the staking pallet * hardcode num_slashing to unlock chunks automatically * refactor withdraw logic to do_withdraw; idiomatic rust improvements * a * callable unbond() to return a DispatchWithPostInfo to dynamically update the consumed weight * refunds overpaid fees when unbond with withdraw * fetches real slashing spans before withdrawal call * nits * addresses PR comments * Adds more testing * fixes doc comments * Fixes weight refunding logic for fn unbond * generalizes to return used weight or dispatch error * Update frame/staking/src/pallet/mod.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/staking/src/pallet/mod.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Addresses PR comments * Add comment to speculative num spans * adds missing add_slashing_spans in withdraw_unbonded_kill benchmarks * ".git/.scripts/bench-bot.sh" pallet dev pallet_staking * fix publish Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Co-authored-by: command-bot <>
This commit is contained in:
@@ -92,6 +92,45 @@ impl<T: Config> Pallet<T> {
|
||||
Self::slashable_balance_of_vote_weight(who, issuance)
|
||||
}
|
||||
|
||||
pub(super) fn do_withdraw_unbonded(
|
||||
controller: &T::AccountId,
|
||||
num_slashing_spans: u32,
|
||||
) -> Result<Weight, DispatchError> {
|
||||
let mut ledger = Self::ledger(&controller).ok_or(Error::<T>::NotController)?;
|
||||
let (stash, old_total) = (ledger.stash.clone(), ledger.total);
|
||||
if let Some(current_era) = Self::current_era() {
|
||||
ledger = ledger.consolidate_unlocked(current_era)
|
||||
}
|
||||
|
||||
let used_weight =
|
||||
if ledger.unlocking.is_empty() && ledger.active < T::Currency::minimum_balance() {
|
||||
// This account must have called `unbond()` with some value that caused the active
|
||||
// portion to fall below existential deposit + will have no more unlocking chunks
|
||||
// left. We can now safely remove all staking-related information.
|
||||
Self::kill_stash(&stash, num_slashing_spans)?;
|
||||
// Remove the lock.
|
||||
T::Currency::remove_lock(STAKING_ID, &stash);
|
||||
|
||||
T::WeightInfo::withdraw_unbonded_kill(num_slashing_spans)
|
||||
} else {
|
||||
// This was the consequence of a partial unbond. just update the ledger and move on.
|
||||
Self::update_ledger(&controller, &ledger);
|
||||
|
||||
// This is only an update, so we use less overall weight.
|
||||
T::WeightInfo::withdraw_unbonded_update(num_slashing_spans)
|
||||
};
|
||||
|
||||
// `old_total` should never be less than the new total because
|
||||
// `consolidate_unlocked` strictly subtracts balance.
|
||||
if ledger.total < old_total {
|
||||
// Already checked that this won't overflow by entry condition.
|
||||
let value = old_total - ledger.total;
|
||||
Self::deposit_event(Event::<T>::Withdrawn { stash, amount: value });
|
||||
}
|
||||
|
||||
Ok(used_weight)
|
||||
}
|
||||
|
||||
pub(super) fn do_payout_stakers(
|
||||
validator_stash: T::AccountId,
|
||||
era: EraIndex,
|
||||
@@ -1568,6 +1607,8 @@ impl<T: Config> StakingInterface for Pallet<T> {
|
||||
fn unbond(who: &Self::AccountId, value: Self::Balance) -> DispatchResult {
|
||||
let ctrl = Self::bonded(who).ok_or(Error::<T>::NotStash)?;
|
||||
Self::unbond(RawOrigin::Signed(ctrl).into(), value)
|
||||
.map_err(|with_post| with_post.error)
|
||||
.map(|_| ())
|
||||
}
|
||||
|
||||
fn chill(who: &Self::AccountId) -> DispatchResult {
|
||||
|
||||
Reference in New Issue
Block a user