mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 18:27:56 +00:00
Lazy reaping (#4895)
* Squash and rebase from gav-lazy-reaping * Bump version * Bump runtime again * Docs. * Remove old functions * Update frame/balances/src/lib.rs Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com> * Update frame/contracts/src/lib.rs Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com> * Warnings * Bump runtime version * Update frame/democracy/src/lib.rs Co-Authored-By: Shawn Tabrizi <shawntabrizi@gmail.com> * Update frame/system/src/lib.rs * Clean up OnReapAccount * Use frame_support debug * Bump spec * Renames and fix * Fix * Fix rename * Fix * Increase time for test Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: Benjamin Kampmann <ben.kampmann@googlemail.com>
This commit is contained in:
@@ -259,6 +259,7 @@ use codec::{HasCompact, Encode, Decode};
|
||||
use frame_support::{
|
||||
decl_module, decl_event, decl_storage, ensure, decl_error,
|
||||
weights::SimpleDispatchInfo,
|
||||
dispatch::DispatchResult,
|
||||
traits::{
|
||||
Currency, LockIdentifier, LockableCurrency,
|
||||
WithdrawReasons, OnUnbalanced, Imbalance, Get, Time
|
||||
@@ -282,7 +283,6 @@ use sp_runtime::{Serialize, Deserialize};
|
||||
use frame_system::{self as system, ensure_signed, ensure_root};
|
||||
|
||||
use sp_phragmen::ExtendedBalance;
|
||||
use frame_support::traits::OnReapAccount;
|
||||
|
||||
const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4;
|
||||
const MAX_NOMINATIONS: usize = 16;
|
||||
@@ -831,6 +831,8 @@ decl_error! {
|
||||
NoMoreChunks,
|
||||
/// Can not rebond without unlocking chunks.
|
||||
NoUnlockChunk,
|
||||
/// Attempting to target a stash that still has funds.
|
||||
FundedTarget,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -900,6 +902,8 @@ decl_module! {
|
||||
<Bonded<T>>::insert(&stash, &controller);
|
||||
<Payee<T>>::insert(&stash, payee);
|
||||
|
||||
system::Module::<T>::inc_ref(&stash);
|
||||
|
||||
let stash_balance = T::Currency::free_balance(&stash);
|
||||
let value = value.min(stash_balance);
|
||||
let item = StakingLedger { stash, total: value, active: value, unlocking: vec![] };
|
||||
@@ -1013,10 +1017,10 @@ decl_module! {
|
||||
// portion to fall below existential deposit + will have no more unlocking chunks
|
||||
// left. We can now safely remove this.
|
||||
let stash = ledger.stash;
|
||||
// remove all staking-related information.
|
||||
Self::kill_stash(&stash)?;
|
||||
// remove the lock.
|
||||
T::Currency::remove_lock(STAKING_ID, &stash);
|
||||
// remove all staking-related information.
|
||||
Self::kill_stash(&stash);
|
||||
} else {
|
||||
// This was the consequence of a partial unbond. just update the ledger and move on.
|
||||
Self::update_ledger(&controller, &ledger);
|
||||
@@ -1187,10 +1191,11 @@ decl_module! {
|
||||
fn force_unstake(origin, stash: T::AccountId) {
|
||||
ensure_root(origin)?;
|
||||
|
||||
// remove all staking-related information.
|
||||
Self::kill_stash(&stash)?;
|
||||
|
||||
// remove the lock.
|
||||
T::Currency::remove_lock(STAKING_ID, &stash);
|
||||
// remove all staking-related information.
|
||||
Self::kill_stash(&stash);
|
||||
}
|
||||
|
||||
/// Force there to be a new era at the end of sessions indefinitely.
|
||||
@@ -1254,9 +1259,22 @@ decl_module! {
|
||||
);
|
||||
|
||||
let ledger = ledger.rebond(value);
|
||||
|
||||
Self::update_ledger(&controller, &ledger);
|
||||
}
|
||||
|
||||
/// Remove all data structure concerning a staker/stash once its balance is zero.
|
||||
/// This is essentially equivalent to `withdraw_unbonded` except it can be called by anyone
|
||||
/// and the target `stash` must have no funds left.
|
||||
///
|
||||
/// This can be called from any origin.
|
||||
///
|
||||
/// - `stash`: The stash account to reap. Its balance must be zero.
|
||||
fn reap_stash(_origin, stash: T::AccountId) {
|
||||
Self::ensure_storage_upgraded();
|
||||
ensure!(T::Currency::total_balance(&stash).is_zero(), Error::<T>::FundedTarget);
|
||||
Self::kill_stash(&stash)?;
|
||||
T::Currency::remove_lock(STAKING_ID, &stash);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1585,18 +1603,22 @@ impl<T: Trait> Module<T> {
|
||||
///
|
||||
/// Assumes storage is upgraded before calling.
|
||||
///
|
||||
/// This is called :
|
||||
/// - Immediately when an account's balance falls below existential deposit.
|
||||
/// This is called:
|
||||
/// - after a `withdraw_unbond()` call that frees all of a stash's bonded balance.
|
||||
fn kill_stash(stash: &T::AccountId) {
|
||||
if let Some(controller) = <Bonded<T>>::take(stash) {
|
||||
<Ledger<T>>::remove(&controller);
|
||||
}
|
||||
/// - through `reap_stash()` if the balance has fallen to zero (through slashing).
|
||||
fn kill_stash(stash: &T::AccountId) -> DispatchResult {
|
||||
let controller = Bonded::<T>::take(stash).ok_or(Error::<T>::NotStash)?;
|
||||
<Ledger<T>>::remove(&controller);
|
||||
|
||||
<Payee<T>>::remove(stash);
|
||||
<Validators<T>>::remove(stash);
|
||||
<Nominators<T>>::remove(stash);
|
||||
|
||||
slashing::clear_stash_metadata::<T>(stash);
|
||||
|
||||
system::Module::<T>::dec_ref(stash);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add reward points to validators using their stash account ID.
|
||||
@@ -1676,13 +1698,6 @@ impl<T: Trait> SessionManager<T::AccountId, Exposure<T::AccountId, BalanceOf<T>>
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> OnReapAccount<T::AccountId> for Module<T> {
|
||||
fn on_reap_account(stash: &T::AccountId) {
|
||||
Self::ensure_storage_upgraded();
|
||||
Self::kill_stash(stash);
|
||||
}
|
||||
}
|
||||
|
||||
/// Add reward points to block authors:
|
||||
/// * 20 points to the block producer for producing a (non-uncle) block in the relay chain,
|
||||
/// * 2 points to the block producer for each reference to a previously unreferenced uncle, and
|
||||
|
||||
@@ -140,12 +140,12 @@ impl frame_system::Trait for Test {
|
||||
type ModuleToIndex = ();
|
||||
type AccountData = pallet_balances::AccountData<u64>;
|
||||
type OnNewAccount = ();
|
||||
type OnReapAccount = (Balances, Staking, Session);
|
||||
type OnKilledAccount = ();
|
||||
}
|
||||
impl pallet_balances::Trait for Test {
|
||||
type Balance = Balance;
|
||||
type Event = ();
|
||||
type DustRemoval = ();
|
||||
type Event = ();
|
||||
type ExistentialDeposit = ExistentialDeposit;
|
||||
type AccountStore = System;
|
||||
}
|
||||
@@ -156,13 +156,13 @@ parameter_types! {
|
||||
pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(25);
|
||||
}
|
||||
impl pallet_session::Trait for Test {
|
||||
type SessionManager = pallet_session::historical::NoteHistoricalRoot<Test, Staking>;
|
||||
type Keys = UintAuthorityId;
|
||||
type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
|
||||
type SessionHandler = TestSessionHandler;
|
||||
type Event = ();
|
||||
type ValidatorId = AccountId;
|
||||
type ValidatorIdOf = crate::StashOf<Test>;
|
||||
type ShouldEndSession = pallet_session::PeriodicSessions<Period, Offset>;
|
||||
type SessionManager = pallet_session::historical::NoteHistoricalRoot<Test, Staking>;
|
||||
type SessionHandler = TestSessionHandler;
|
||||
type Keys = UintAuthorityId;
|
||||
type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
|
||||
}
|
||||
|
||||
@@ -300,22 +300,22 @@ impl ExtBuilder {
|
||||
|
||||
let _ = pallet_balances::GenesisConfig::<Test>{
|
||||
balances: vec![
|
||||
(1, 10 * balance_factor),
|
||||
(2, 20 * balance_factor),
|
||||
(3, 300 * balance_factor),
|
||||
(4, 400 * balance_factor),
|
||||
(10, balance_factor),
|
||||
(11, balance_factor * 1000),
|
||||
(20, balance_factor),
|
||||
(21, balance_factor * 2000),
|
||||
(30, balance_factor),
|
||||
(31, balance_factor * 2000),
|
||||
(40, balance_factor),
|
||||
(41, balance_factor * 2000),
|
||||
(100, 2000 * balance_factor),
|
||||
(101, 2000 * balance_factor),
|
||||
// This allow us to have a total_payout different from 0.
|
||||
(999, 1_000_000_000_000),
|
||||
(1, 10 * balance_factor),
|
||||
(2, 20 * balance_factor),
|
||||
(3, 300 * balance_factor),
|
||||
(4, 400 * balance_factor),
|
||||
(10, balance_factor),
|
||||
(11, balance_factor * 1000),
|
||||
(20, balance_factor),
|
||||
(21, balance_factor * 2000),
|
||||
(30, balance_factor),
|
||||
(31, balance_factor * 2000),
|
||||
(40, balance_factor),
|
||||
(41, balance_factor * 2000),
|
||||
(100, 2000 * balance_factor),
|
||||
(101, 2000 * balance_factor),
|
||||
// This allow us to have a total_payout different from 0.
|
||||
(999, 1_000_000_000_000),
|
||||
],
|
||||
}.assimilate_storage(&mut storage);
|
||||
|
||||
@@ -346,7 +346,7 @@ impl ExtBuilder {
|
||||
}.assimilate_storage(&mut storage);
|
||||
|
||||
let _ = pallet_session::GenesisConfig::<Test> {
|
||||
keys: validators.iter().map(|x| (*x, UintAuthorityId(*x))).collect(),
|
||||
keys: validators.iter().map(|x| (*x, *x, UintAuthorityId(*x))).collect(),
|
||||
}.assimilate_storage(&mut storage);
|
||||
|
||||
let mut ext = sp_io::TestExternalities::from(storage);
|
||||
|
||||
@@ -1456,6 +1456,9 @@ fn on_free_balance_zero_stash_removes_validator() {
|
||||
// Check total balance of stash
|
||||
assert_eq!(Balances::total_balance(&11), 0);
|
||||
|
||||
// Reap the stash
|
||||
assert_ok!(Staking::reap_stash(Origin::NONE, 11));
|
||||
|
||||
// Check storage items do not exist
|
||||
assert!(!<Ledger<Test>>::contains_key(&10));
|
||||
assert!(!<Bonded<Test>>::contains_key(&11));
|
||||
@@ -1509,6 +1512,9 @@ fn on_free_balance_zero_stash_removes_nominator() {
|
||||
// Check total balance of stash
|
||||
assert_eq!(Balances::total_balance(&11), 0);
|
||||
|
||||
// Reap the stash
|
||||
assert_ok!(Staking::reap_stash(Origin::NONE, 11));
|
||||
|
||||
// Check storage items do not exist
|
||||
assert!(!<Ledger<Test>>::contains_key(&10));
|
||||
assert!(!<Bonded<Test>>::contains_key(&11));
|
||||
@@ -2303,6 +2309,10 @@ fn garbage_collection_after_slashing() {
|
||||
// so we don't test those here.
|
||||
|
||||
assert_eq!(Balances::free_balance(11), 0);
|
||||
assert_eq!(Balances::total_balance(&11), 0);
|
||||
|
||||
assert_ok!(Staking::reap_stash(Origin::NONE, 11));
|
||||
|
||||
assert!(<Staking as crate::Store>::SlashingSpans::get(&11).is_none());
|
||||
assert_eq!(<Staking as crate::Store>::SpanSlash::get(&(11, 0)).amount_slashed(), &0);
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user