mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 13:01:07 +00:00
[Enhancement] Remove optional Pool subscription from fast-unstake (#12344)
* [Enhancement] Remove optional Pool subscription from fast-unstake * remove nomination-pools pallet dependency * fixes * more fixes * more fixes * more fixes
This commit is contained in:
Generated
-1
@@ -5729,7 +5729,6 @@ dependencies = [
|
||||
"frame-system",
|
||||
"log",
|
||||
"pallet-balances",
|
||||
"pallet-nomination-pools",
|
||||
"pallet-staking",
|
||||
"pallet-staking-reward-curve",
|
||||
"pallet-timestamp",
|
||||
|
||||
@@ -28,7 +28,6 @@ sp-staking = { default-features = false, path = "../../primitives/staking" }
|
||||
pallet-balances = { default-features = false, path = "../balances" }
|
||||
pallet-timestamp = { default-features = false, path = "../timestamp" }
|
||||
pallet-staking = { default-features = false, path = "../staking" }
|
||||
pallet-nomination-pools = { default-features = false, path = "../nomination-pools" }
|
||||
frame-election-provider-support = { default-features = false, path = "../election-provider-support" }
|
||||
|
||||
frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, path = "../benchmarking" }
|
||||
@@ -55,7 +54,6 @@ std = [
|
||||
"sp-std/std",
|
||||
|
||||
"pallet-staking/std",
|
||||
"pallet-nomination-pools/std",
|
||||
"pallet-balances/std",
|
||||
"pallet-timestamp/std",
|
||||
"frame-election-provider-support/std",
|
||||
|
||||
@@ -26,7 +26,6 @@ use frame_support::{
|
||||
traits::{Currency, EnsureOrigin, Get, Hooks},
|
||||
};
|
||||
use frame_system::RawOrigin;
|
||||
use pallet_nomination_pools::{Pallet as Pools, PoolId};
|
||||
use pallet_staking::Pallet as Staking;
|
||||
use sp_runtime::traits::{StaticLookup, Zero};
|
||||
use sp_staking::EraIndex;
|
||||
@@ -76,25 +75,6 @@ pub(crate) fn fast_unstake_events<T: Config>() -> Vec<crate::Event<T>> {
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn setup_pool<T: Config>() -> PoolId {
|
||||
let depositor = frame_benchmarking::account::<T::AccountId>("depositor_42", 0, USER_SEED);
|
||||
let depositor_lookup = l::<T>(depositor.clone());
|
||||
|
||||
let stake = Pools::<T>::depositor_min_bond();
|
||||
CurrencyOf::<T>::make_free_balance_be(&depositor, stake * 10u32.into());
|
||||
|
||||
Pools::<T>::create(
|
||||
RawOrigin::Signed(depositor.clone()).into(),
|
||||
stake,
|
||||
depositor_lookup.clone(),
|
||||
depositor_lookup.clone(),
|
||||
depositor_lookup,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
pallet_nomination_pools::LastPoolId::<T>::get()
|
||||
}
|
||||
|
||||
fn setup_staking<T: Config>(v: u32, until: EraIndex) {
|
||||
let ed = CurrencyOf::<T>::minimum_balance();
|
||||
|
||||
@@ -131,10 +111,8 @@ benchmarks! {
|
||||
// on_idle, we we don't check anyone, but fully unbond and move them to another pool.
|
||||
on_idle_unstake {
|
||||
let who = create_unexposed_nominator::<T>();
|
||||
let pool_id = setup_pool::<T>();
|
||||
assert_ok!(FastUnstake::<T>::register_fast_unstake(
|
||||
RawOrigin::Signed(who.clone()).into(),
|
||||
Some(pool_id)
|
||||
));
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
|
||||
@@ -143,7 +121,7 @@ benchmarks! {
|
||||
on_idle_full_block::<T>();
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: who.clone(), checked: vec![0].try_into().unwrap(), maybe_pool_id: Some(pool_id) })
|
||||
Some(UnstakeRequest { stash: who.clone(), checked: vec![0].try_into().unwrap() })
|
||||
);
|
||||
}
|
||||
: {
|
||||
@@ -172,7 +150,6 @@ benchmarks! {
|
||||
let who = create_unexposed_nominator::<T>();
|
||||
assert_ok!(FastUnstake::<T>::register_fast_unstake(
|
||||
RawOrigin::Signed(who.clone()).into(),
|
||||
None,
|
||||
));
|
||||
|
||||
// no one is queued thus far.
|
||||
@@ -185,7 +162,7 @@ benchmarks! {
|
||||
let checked: frame_support::BoundedVec<_, _> = (1..=u).rev().collect::<Vec<EraIndex>>().try_into().unwrap();
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: who.clone(), checked, maybe_pool_id: None })
|
||||
Some(UnstakeRequest { stash: who.clone(), checked })
|
||||
);
|
||||
assert!(matches!(
|
||||
fast_unstake_events::<T>().last(),
|
||||
@@ -199,7 +176,7 @@ benchmarks! {
|
||||
assert_eq!(Queue::<T>::count(), 0);
|
||||
|
||||
}
|
||||
:_(RawOrigin::Signed(who.clone()), None)
|
||||
:_(RawOrigin::Signed(who.clone()))
|
||||
verify {
|
||||
assert_eq!(Queue::<T>::count(), 1);
|
||||
}
|
||||
@@ -208,7 +185,6 @@ benchmarks! {
|
||||
let who = create_unexposed_nominator::<T>();
|
||||
assert_ok!(FastUnstake::<T>::register_fast_unstake(
|
||||
RawOrigin::Signed(who.clone()).into(),
|
||||
None
|
||||
));
|
||||
assert_eq!(Queue::<T>::count(), 1);
|
||||
whitelist_account!(who);
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
//!
|
||||
//! If a nominator is not exposed in any `ErasStakers` (i.e. "has not actively backed any
|
||||
//! validators in the last `BondingDuration` days"), then they can register themselves in this
|
||||
//! pallet, unstake faster than having to wait an entire bonding duration, and potentially move
|
||||
//! into a nomination pool.
|
||||
//! pallet, unstake faster than having to wait an entire bonding duration.
|
||||
//!
|
||||
//! Appearing in the exposure of a validator means being exposed equal to that validator from the
|
||||
//! point of view of the staking system. This usually means earning rewards with the validator, and
|
||||
@@ -43,8 +42,7 @@
|
||||
//! to prevent them from accidentally exposing themselves behind a validator etc.
|
||||
//!
|
||||
//! Once processed, if successful, no additional fee for the checking process is taken, and the
|
||||
//! staker is instantly unbonded. Optionally, if they have asked to join a pool, their *entire*
|
||||
//! stake is joined into their pool of choice.
|
||||
//! staker is instantly unbonded.
|
||||
//!
|
||||
//! If unsuccessful, meaning that the staker was exposed sometime in the last `BondingDuration` eras
|
||||
//! they will end up being slashed for the amount of wasted work they have inflicted on the chian.
|
||||
@@ -85,7 +83,6 @@ pub mod pallet {
|
||||
use frame_election_provider_support::ElectionProvider;
|
||||
use frame_support::pallet_prelude::*;
|
||||
use frame_system::{pallet_prelude::*, RawOrigin};
|
||||
use pallet_nomination_pools::PoolId;
|
||||
use pallet_staking::Pallet as Staking;
|
||||
use sp_runtime::{
|
||||
traits::{Saturating, Zero},
|
||||
@@ -109,12 +106,7 @@ pub mod pallet {
|
||||
pub struct Pallet<T>(_);
|
||||
|
||||
#[pallet::config]
|
||||
pub trait Config:
|
||||
frame_system::Config
|
||||
+ pallet_staking::Config<
|
||||
CurrencyBalance = <Self as pallet_nomination_pools::Config>::CurrencyBalance,
|
||||
> + pallet_nomination_pools::Config
|
||||
{
|
||||
pub trait Config: frame_system::Config + pallet_staking::Config {
|
||||
/// The overarching event type.
|
||||
type RuntimeEvent: From<Event<Self>>
|
||||
+ IsType<<Self as frame_system::Config>::RuntimeEvent>
|
||||
@@ -139,10 +131,9 @@ pub mod pallet {
|
||||
|
||||
/// The map of all accounts wishing to be unstaked.
|
||||
///
|
||||
/// Points the `AccountId` wishing to unstake to the optional `PoolId` they wish to join
|
||||
/// thereafter.
|
||||
/// Keeps track of `AccountId` wishing to unstake.
|
||||
#[pallet::storage]
|
||||
pub type Queue<T: Config> = CountedStorageMap<_, Twox64Concat, T::AccountId, Option<PoolId>>;
|
||||
pub type Queue<T: Config> = CountedStorageMap<_, Twox64Concat, T::AccountId, ()>;
|
||||
|
||||
/// Number of eras to check per block.
|
||||
///
|
||||
@@ -158,7 +149,7 @@ pub mod pallet {
|
||||
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
||||
pub enum Event<T: Config> {
|
||||
/// A staker was unstaked.
|
||||
Unstaked { stash: T::AccountId, maybe_pool_id: Option<PoolId>, result: DispatchResult },
|
||||
Unstaked { stash: T::AccountId, result: DispatchResult },
|
||||
/// A staker was slashed for requesting fast-unstake whilst being exposed.
|
||||
Slashed { stash: T::AccountId, amount: BalanceOf<T> },
|
||||
/// A staker was partially checked for the given eras, but the process did not finish.
|
||||
@@ -213,16 +204,13 @@ pub mod pallet {
|
||||
/// they are guaranteed to remain eligible, because the call will chill them as well.
|
||||
///
|
||||
/// If the check works, the entire staking data is removed, i.e. the stash is fully
|
||||
/// unstaked, and they potentially join a pool with their entire bonded stake.
|
||||
/// unstaked.
|
||||
///
|
||||
/// If the check fails, the stash remains chilled and waiting for being unbonded as in with
|
||||
/// the normal staking system, but they lose part of their unbonding chunks due to consuming
|
||||
/// the chain's resources.
|
||||
#[pallet::weight(<T as Config>::WeightInfo::register_fast_unstake())]
|
||||
pub fn register_fast_unstake(
|
||||
origin: OriginFor<T>,
|
||||
maybe_pool_id: Option<PoolId>,
|
||||
) -> DispatchResult {
|
||||
pub fn register_fast_unstake(origin: OriginFor<T>) -> DispatchResult {
|
||||
let ctrl = ensure_signed(origin)?;
|
||||
|
||||
let ledger =
|
||||
@@ -243,12 +231,11 @@ pub mod pallet {
|
||||
Staking::<T>::unbond(RawOrigin::Signed(ctrl).into(), ledger.total)?;
|
||||
|
||||
// enqueue them.
|
||||
Queue::<T>::insert(ledger.stash, maybe_pool_id);
|
||||
Queue::<T>::insert(ledger.stash, ());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Deregister oneself from the fast-unstake (also cancels joining the pool if that was
|
||||
/// supplied on `register_fast_unstake` .
|
||||
/// Deregister oneself from the fast-unstake.
|
||||
///
|
||||
/// This is useful if one is registered, they are still waiting, and they change their mind.
|
||||
///
|
||||
@@ -327,17 +314,12 @@ pub mod pallet {
|
||||
return T::DbWeight::get().reads(2)
|
||||
}
|
||||
|
||||
let UnstakeRequest { stash, mut checked, maybe_pool_id } = match Head::<T>::take()
|
||||
.or_else(|| {
|
||||
// NOTE: there is no order guarantees in `Queue`.
|
||||
Queue::<T>::drain()
|
||||
.map(|(stash, maybe_pool_id)| UnstakeRequest {
|
||||
stash,
|
||||
maybe_pool_id,
|
||||
checked: Default::default(),
|
||||
})
|
||||
.next()
|
||||
}) {
|
||||
let UnstakeRequest { stash, mut checked } = match Head::<T>::take().or_else(|| {
|
||||
// NOTE: there is no order guarantees in `Queue`.
|
||||
Queue::<T>::drain()
|
||||
.map(|(stash, _)| UnstakeRequest { stash, checked: Default::default() })
|
||||
.next()
|
||||
}) {
|
||||
None => {
|
||||
// There's no `Head` and nothing in the `Queue`, nothing to do here.
|
||||
return T::DbWeight::get().reads(4)
|
||||
@@ -392,48 +374,15 @@ pub mod pallet {
|
||||
// `stash` is not exposed in any era now -- we can let go of them now.
|
||||
let num_slashing_spans = Staking::<T>::slashing_spans(&stash).iter().count() as u32;
|
||||
|
||||
let ctrl = match pallet_staking::Bonded::<T>::get(&stash) {
|
||||
Some(ctrl) => ctrl,
|
||||
None => {
|
||||
Self::deposit_event(Event::<T>::Errored { stash });
|
||||
return <T as Config>::WeightInfo::on_idle_unstake()
|
||||
},
|
||||
};
|
||||
|
||||
let ledger = match pallet_staking::Ledger::<T>::get(ctrl) {
|
||||
Some(ledger) => ledger,
|
||||
None => {
|
||||
Self::deposit_event(Event::<T>::Errored { stash });
|
||||
return <T as Config>::WeightInfo::on_idle_unstake()
|
||||
},
|
||||
};
|
||||
|
||||
let unstake_result = pallet_staking::Pallet::<T>::force_unstake(
|
||||
let result = pallet_staking::Pallet::<T>::force_unstake(
|
||||
RawOrigin::Root.into(),
|
||||
stash.clone(),
|
||||
num_slashing_spans,
|
||||
);
|
||||
|
||||
let pool_stake_result = if let Some(pool_id) = maybe_pool_id {
|
||||
pallet_nomination_pools::Pallet::<T>::join(
|
||||
RawOrigin::Signed(stash.clone()).into(),
|
||||
ledger.total,
|
||||
pool_id,
|
||||
)
|
||||
} else {
|
||||
Ok(())
|
||||
};
|
||||
log!(info, "unstaked {:?}, outcome: {:?}", stash, result);
|
||||
|
||||
let result = unstake_result.and(pool_stake_result);
|
||||
log!(
|
||||
info,
|
||||
"unstaked {:?}, maybe_pool {:?}, outcome: {:?}",
|
||||
stash,
|
||||
maybe_pool_id,
|
||||
result
|
||||
);
|
||||
|
||||
Self::deposit_event(Event::<T>::Unstaked { stash, maybe_pool_id, result });
|
||||
Self::deposit_event(Event::<T>::Unstaked { stash, result });
|
||||
<T as Config>::WeightInfo::on_idle_unstake()
|
||||
} else {
|
||||
// eras remaining to be checked.
|
||||
@@ -471,11 +420,7 @@ pub mod pallet {
|
||||
// Not exposed in these eras.
|
||||
match checked.try_extend(unchecked_eras_to_check.clone().into_iter()) {
|
||||
Ok(_) => {
|
||||
Head::<T>::put(UnstakeRequest {
|
||||
stash: stash.clone(),
|
||||
checked,
|
||||
maybe_pool_id,
|
||||
});
|
||||
Head::<T>::put(UnstakeRequest { stash: stash.clone(), checked });
|
||||
Self::deposit_event(Event::<T>::Checking {
|
||||
stash,
|
||||
eras: unchecked_eras_to_check,
|
||||
|
||||
@@ -17,19 +17,10 @@
|
||||
|
||||
use crate::{self as fast_unstake};
|
||||
use frame_support::{
|
||||
assert_ok,
|
||||
pallet_prelude::*,
|
||||
parameter_types,
|
||||
traits::{ConstU64, ConstU8, Currency},
|
||||
weights::constants::WEIGHT_PER_SECOND,
|
||||
PalletId,
|
||||
};
|
||||
use sp_runtime::{
|
||||
traits::{Convert, IdentityLookup},
|
||||
FixedU128,
|
||||
pallet_prelude::*, parameter_types, traits::ConstU64, weights::constants::WEIGHT_PER_SECOND,
|
||||
};
|
||||
use sp_runtime::traits::{Convert, IdentityLookup};
|
||||
|
||||
use frame_system::RawOrigin;
|
||||
use pallet_staking::{Exposure, IndividualExposure, StakerStatus};
|
||||
use sp_std::prelude::*;
|
||||
|
||||
@@ -153,7 +144,7 @@ impl pallet_staking::Config for Runtime {
|
||||
type VoterList = pallet_staking::UseNominatorsAndValidatorsMap<Self>;
|
||||
type TargetList = pallet_staking::UseValidatorsMap<Self>;
|
||||
type MaxUnlockingChunks = ConstU32<32>;
|
||||
type OnStakerSlash = Pools;
|
||||
type OnStakerSlash = ();
|
||||
type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig;
|
||||
type WeightInfo = ();
|
||||
}
|
||||
@@ -172,29 +163,6 @@ impl Convert<sp_core::U256, Balance> for U256ToBalance {
|
||||
}
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const PostUnbondingPoolsWindow: u32 = 10;
|
||||
pub const PoolsPalletId: PalletId = PalletId(*b"py/nopls");
|
||||
pub static MaxMetadataLen: u32 = 10;
|
||||
pub static CheckLevel: u8 = 255;
|
||||
}
|
||||
|
||||
impl pallet_nomination_pools::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type WeightInfo = ();
|
||||
type Currency = Balances;
|
||||
type CurrencyBalance = Balance;
|
||||
type RewardCounter = FixedU128;
|
||||
type BalanceToU256 = BalanceToU256;
|
||||
type U256ToBalance = U256ToBalance;
|
||||
type StakingInterface = Staking;
|
||||
type PostUnbondingPoolsWindow = PostUnbondingPoolsWindow;
|
||||
type MaxMetadataLen = MaxMetadataLen;
|
||||
type MaxUnbonding = ConstU32<8>;
|
||||
type MaxPointsToBalance = ConstU8<10>;
|
||||
type PalletId = PoolsPalletId;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub static SlashPerEra: u32 = 100;
|
||||
}
|
||||
@@ -218,7 +186,6 @@ frame_support::construct_runtime!(
|
||||
Timestamp: pallet_timestamp,
|
||||
Balances: pallet_balances,
|
||||
Staking: pallet_staking,
|
||||
Pools: pallet_nomination_pools,
|
||||
FastUnstake: fast_unstake,
|
||||
}
|
||||
);
|
||||
@@ -287,10 +254,6 @@ impl ExtBuilder {
|
||||
let mut storage =
|
||||
frame_system::GenesisConfig::default().build_storage::<Runtime>().unwrap();
|
||||
|
||||
// create one default pool.
|
||||
let _ = pallet_nomination_pools::GenesisConfig::<Runtime> { ..Default::default() }
|
||||
.assimilate_storage(&mut storage);
|
||||
|
||||
let validators_range = VALIDATOR_PREFIX..VALIDATOR_PREFIX + VALIDATORS_PER_ERA;
|
||||
let nominators_range =
|
||||
NOMINATOR_PREFIX..NOMINATOR_PREFIX + NOMINATORS_PER_VALIDATOR_PER_ERA;
|
||||
@@ -337,11 +300,6 @@ impl ExtBuilder {
|
||||
|
||||
// because we read this value as a measure of how many validators we have.
|
||||
pallet_staking::ValidatorCount::<Runtime>::put(VALIDATORS_PER_ERA as u32);
|
||||
|
||||
// make a pool
|
||||
let amount_to_bond = Pools::depositor_min_bond();
|
||||
Balances::make_free_balance_be(&10, amount_to_bond * 5);
|
||||
assert_ok!(Pools::create(RawOrigin::Signed(10).into(), amount_to_bond, 900, 901, 902));
|
||||
});
|
||||
ext
|
||||
}
|
||||
@@ -359,14 +317,12 @@ pub(crate) fn run_to_block(n: u64, on_idle: bool) {
|
||||
while System::block_number() < n {
|
||||
Balances::on_finalize(System::block_number());
|
||||
Staking::on_finalize(System::block_number());
|
||||
Pools::on_finalize(System::block_number());
|
||||
FastUnstake::on_finalize(System::block_number());
|
||||
|
||||
System::set_block_number(System::block_number() + 1);
|
||||
|
||||
Balances::on_initialize(System::block_number());
|
||||
Staking::on_initialize(System::block_number());
|
||||
Pools::on_initialize(System::block_number());
|
||||
FastUnstake::on_initialize(System::block_number());
|
||||
if on_idle {
|
||||
FastUnstake::on_idle(System::block_number(), BlockWeights::get().max_block);
|
||||
|
||||
@@ -20,20 +20,15 @@
|
||||
use super::*;
|
||||
use crate::{mock::*, types::*, weights::WeightInfo, Event};
|
||||
use frame_support::{assert_noop, assert_ok, bounded_vec, pallet_prelude::*, traits::Currency};
|
||||
use pallet_nomination_pools::{BondedPools, LastPoolId, RewardPools};
|
||||
use pallet_staking::{CurrentEra, IndividualExposure, RewardDestination};
|
||||
|
||||
use sp_runtime::{traits::BadOrigin, DispatchError, ModuleError};
|
||||
use sp_runtime::traits::BadOrigin;
|
||||
use sp_staking::StakingInterface;
|
||||
|
||||
#[test]
|
||||
fn test_setup_works() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
assert_eq!(BondedPools::<T>::count(), 1);
|
||||
assert_eq!(RewardPools::<T>::count(), 1);
|
||||
assert_eq!(Staking::bonding_duration(), 3);
|
||||
let last_pool = LastPoolId::<T>::get();
|
||||
assert_eq!(last_pool, 1);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -41,7 +36,7 @@ fn test_setup_works() {
|
||||
fn register_works() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// Controller account registers for fast unstake.
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1_u32)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
// Ensure stash is in the queue.
|
||||
assert_ne!(Queue::<T>::get(1), None);
|
||||
});
|
||||
@@ -56,7 +51,7 @@ fn cannot_register_if_not_bonded() {
|
||||
}
|
||||
// Attempt to fast unstake.
|
||||
assert_noop!(
|
||||
FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1), Some(1_u32)),
|
||||
FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1)),
|
||||
Error::<T>::NotController
|
||||
);
|
||||
});
|
||||
@@ -66,10 +61,10 @@ fn cannot_register_if_not_bonded() {
|
||||
fn cannot_register_if_in_queue() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// Insert some Queue item
|
||||
Queue::<T>::insert(1, Some(1_u32));
|
||||
Queue::<T>::insert(1, ());
|
||||
// Cannot re-register, already in queue
|
||||
assert_noop!(
|
||||
FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1_u32)),
|
||||
FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)),
|
||||
Error::<T>::AlreadyQueued
|
||||
);
|
||||
});
|
||||
@@ -79,10 +74,10 @@ fn cannot_register_if_in_queue() {
|
||||
fn cannot_register_if_head() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// Insert some Head item for stash
|
||||
Head::<T>::put(UnstakeRequest { stash: 1, checked: bounded_vec![], maybe_pool_id: None });
|
||||
Head::<T>::put(UnstakeRequest { stash: 1, checked: bounded_vec![] });
|
||||
// Controller attempts to regsiter
|
||||
assert_noop!(
|
||||
FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1_u32)),
|
||||
FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)),
|
||||
Error::<T>::AlreadyHead
|
||||
);
|
||||
});
|
||||
@@ -95,7 +90,7 @@ fn cannot_register_if_has_unlocking_chunks() {
|
||||
assert_ok!(Staking::unbond(RuntimeOrigin::signed(2), 50_u128));
|
||||
// Cannot register for fast unstake with unlock chunks active
|
||||
assert_noop!(
|
||||
FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1_u32)),
|
||||
FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)),
|
||||
Error::<T>::NotFullyBonded
|
||||
);
|
||||
});
|
||||
@@ -105,7 +100,7 @@ fn cannot_register_if_has_unlocking_chunks() {
|
||||
fn deregister_works() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// Controller account registers for fast unstake.
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1_u32)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
// Controller then changes mind and deregisters.
|
||||
assert_ok!(FastUnstake::deregister(RuntimeOrigin::signed(2)));
|
||||
// Ensure stash no longer exists in the queue.
|
||||
@@ -117,7 +112,7 @@ fn deregister_works() {
|
||||
fn cannot_deregister_if_not_controller() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// Controller account registers for fast unstake.
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1_u32)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
// Stash tries to deregister.
|
||||
assert_noop!(FastUnstake::deregister(RuntimeOrigin::signed(1)), Error::<T>::NotController);
|
||||
});
|
||||
@@ -135,9 +130,9 @@ fn cannot_deregister_if_not_queued() {
|
||||
fn cannot_deregister_already_head() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// Controller attempts to register, should fail
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1_u32)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
// Insert some Head item for stash.
|
||||
Head::<T>::put(UnstakeRequest { stash: 1, checked: bounded_vec![], maybe_pool_id: None });
|
||||
Head::<T>::put(UnstakeRequest { stash: 1, checked: bounded_vec![] });
|
||||
// Controller attempts to deregister
|
||||
assert_noop!(FastUnstake::deregister(RuntimeOrigin::signed(2)), Error::<T>::AlreadyHead);
|
||||
});
|
||||
@@ -169,15 +164,15 @@ mod on_idle {
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// set up Queue item
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(Some(1)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
|
||||
// call on_idle with no remaining weight
|
||||
FastUnstake::on_idle(System::block_number(), Weight::from_ref_time(0));
|
||||
|
||||
// assert nothing changed in Queue and Head
|
||||
assert_eq!(Head::<T>::get(), None);
|
||||
assert_eq!(Queue::<T>::get(1), Some(Some(1)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -189,8 +184,8 @@ mod on_idle {
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// given
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(Some(1)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
|
||||
assert_eq!(Queue::<T>::count(), 1);
|
||||
assert_eq!(Head::<T>::get(), None);
|
||||
@@ -209,7 +204,7 @@ mod on_idle {
|
||||
);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3], maybe_pool_id: Some(1) })
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3] })
|
||||
);
|
||||
|
||||
// when: another 1 era.
|
||||
@@ -225,11 +220,7 @@ mod on_idle {
|
||||
);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2],
|
||||
maybe_pool_id: Some(1)
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2] })
|
||||
);
|
||||
|
||||
// when: then 5 eras, we only need 2 more.
|
||||
@@ -251,11 +242,7 @@ mod on_idle {
|
||||
);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0],
|
||||
maybe_pool_id: Some(1)
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
);
|
||||
|
||||
// when: not enough weight to unstake:
|
||||
@@ -267,11 +254,7 @@ mod on_idle {
|
||||
assert_eq!(fast_unstake_events_since_last_call(), vec![]);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0],
|
||||
maybe_pool_id: Some(1)
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
);
|
||||
|
||||
// when: enough weight to get over at least one iteration: then we are unblocked and can
|
||||
@@ -287,7 +270,7 @@ mod on_idle {
|
||||
// then we finish the unbonding:
|
||||
assert_eq!(
|
||||
fast_unstake_events_since_last_call(),
|
||||
vec![Event::Unstaked { stash: 1, maybe_pool_id: Some(1), result: Ok(()) }]
|
||||
vec![Event::Unstaked { stash: 1, result: Ok(()) }]
|
||||
);
|
||||
assert_eq!(Head::<T>::get(), None,);
|
||||
|
||||
@@ -302,11 +285,11 @@ mod on_idle {
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// given
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), None));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(4), None));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(6), None));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(8), None));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(10), None));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(4)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(6)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(8)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(10)));
|
||||
|
||||
assert_eq!(Queue::<T>::count(), 5);
|
||||
assert_eq!(Head::<T>::get(), None);
|
||||
@@ -317,11 +300,7 @@ mod on_idle {
|
||||
// then
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0],
|
||||
maybe_pool_id: None
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
);
|
||||
assert_eq!(Queue::<T>::count(), 4);
|
||||
|
||||
@@ -338,11 +317,7 @@ mod on_idle {
|
||||
// then
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 5,
|
||||
checked: bounded_vec![3, 2, 1, 0],
|
||||
maybe_pool_id: None
|
||||
}),
|
||||
Some(UnstakeRequest { stash: 5, checked: bounded_vec![3, 2, 1, 0] }),
|
||||
);
|
||||
assert_eq!(Queue::<T>::count(), 3);
|
||||
|
||||
@@ -350,7 +325,7 @@ mod on_idle {
|
||||
fast_unstake_events_since_last_call(),
|
||||
vec![
|
||||
Event::Checking { stash: 1, eras: vec![3, 2, 1, 0] },
|
||||
Event::Unstaked { stash: 1, maybe_pool_id: None, result: Ok(()) },
|
||||
Event::Unstaked { stash: 1, result: Ok(()) },
|
||||
Event::Checking { stash: 5, eras: vec![3, 2, 1, 0] }
|
||||
]
|
||||
);
|
||||
@@ -364,10 +339,10 @@ mod on_idle {
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// register multi accounts for fast unstake
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(Some(1)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(4), Some(1)));
|
||||
assert_eq!(Queue::<T>::get(3), Some(Some(1)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(4)));
|
||||
assert_eq!(Queue::<T>::get(3), Some(()));
|
||||
|
||||
// assert 2 queue items are in Queue & None in Head to start with
|
||||
assert_eq!(Queue::<T>::count(), 2);
|
||||
@@ -397,9 +372,9 @@ mod on_idle {
|
||||
fast_unstake_events_since_last_call(),
|
||||
vec![
|
||||
Event::Checking { stash: 1, eras: vec![3, 2, 1, 0] },
|
||||
Event::Unstaked { stash: 1, maybe_pool_id: Some(1), result: Ok(()) },
|
||||
Event::Unstaked { stash: 1, result: Ok(()) },
|
||||
Event::Checking { stash: 3, eras: vec![3, 2, 1, 0] },
|
||||
Event::Unstaked { stash: 3, maybe_pool_id: Some(1), result: Ok(()) },
|
||||
Event::Unstaked { stash: 3, result: Ok(()) },
|
||||
]
|
||||
);
|
||||
|
||||
@@ -409,14 +384,14 @@ mod on_idle {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn successful_unstake_without_pool_join() {
|
||||
fn successful_unstake() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(BondingDuration::get() + 1);
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// register for fast unstake
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), None));
|
||||
assert_eq!(Queue::<T>::get(1), Some(None));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
|
||||
// process on idle
|
||||
next_block(true);
|
||||
@@ -427,11 +402,7 @@ mod on_idle {
|
||||
// assert head item present
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0],
|
||||
maybe_pool_id: None
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
@@ -441,55 +412,7 @@ mod on_idle {
|
||||
fast_unstake_events_since_last_call(),
|
||||
vec![
|
||||
Event::Checking { stash: 1, eras: vec![3, 2, 1, 0] },
|
||||
Event::Unstaked { stash: 1, maybe_pool_id: None, result: Ok(()) }
|
||||
]
|
||||
);
|
||||
assert_unstaked(&1);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn successful_unstake_joining_bad_pool() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
ErasToCheckPerBlock::<T>::put(BondingDuration::get() + 1);
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// register for fast unstake
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(0)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(Some(0)));
|
||||
|
||||
// process on idle
|
||||
next_block(true);
|
||||
|
||||
// assert queue item has been moved to head
|
||||
assert_eq!(Queue::<T>::get(1), None);
|
||||
|
||||
// assert head item present
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0],
|
||||
maybe_pool_id: Some(0)
|
||||
})
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(Head::<T>::get(), None,);
|
||||
|
||||
assert_eq!(
|
||||
fast_unstake_events_since_last_call(),
|
||||
vec![
|
||||
Event::Checking { stash: 1, eras: vec![3, 2, 1, 0] },
|
||||
Event::Unstaked {
|
||||
stash: 1,
|
||||
maybe_pool_id: Some(0),
|
||||
result: Err(DispatchError::Module(ModuleError {
|
||||
index: 4,
|
||||
error: [0, 0, 0, 0],
|
||||
message: None
|
||||
}))
|
||||
}
|
||||
Event::Unstaked { stash: 1, result: Ok(()) }
|
||||
]
|
||||
);
|
||||
assert_unstaked(&1);
|
||||
@@ -503,8 +426,8 @@ mod on_idle {
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// register for fast unstake
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1_u32)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(Some(1)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
|
||||
// process on idle
|
||||
next_block(true);
|
||||
@@ -515,11 +438,7 @@ mod on_idle {
|
||||
// assert head item present
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0],
|
||||
maybe_pool_id: Some(1)
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
@@ -529,11 +448,10 @@ mod on_idle {
|
||||
fast_unstake_events_since_last_call(),
|
||||
vec![
|
||||
Event::Checking { stash: 1, eras: vec![3, 2, 1, 0] },
|
||||
Event::Unstaked { stash: 1, maybe_pool_id: Some(1), result: Ok(()) }
|
||||
Event::Unstaked { stash: 1, result: Ok(()) }
|
||||
]
|
||||
);
|
||||
assert_unstaked(&1);
|
||||
assert!(pallet_nomination_pools::PoolMembers::<T>::contains_key(&1));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -545,8 +463,8 @@ mod on_idle {
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// register for fast unstake
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1_u32)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(Some(1)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
|
||||
// process on idle
|
||||
next_block(true);
|
||||
@@ -557,40 +475,28 @@ mod on_idle {
|
||||
// assert head item present
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3], maybe_pool_id: Some(1) })
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3] })
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2],
|
||||
maybe_pool_id: Some(1)
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2] })
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1],
|
||||
maybe_pool_id: Some(1)
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1] })
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0],
|
||||
maybe_pool_id: Some(1)
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
@@ -604,11 +510,10 @@ mod on_idle {
|
||||
Event::Checking { stash: 1, eras: vec![2] },
|
||||
Event::Checking { stash: 1, eras: vec![1] },
|
||||
Event::Checking { stash: 1, eras: vec![0] },
|
||||
Event::Unstaked { stash: 1, maybe_pool_id: Some(1), result: Ok(()) }
|
||||
Event::Unstaked { stash: 1, result: Ok(()) }
|
||||
]
|
||||
);
|
||||
assert_unstaked(&1);
|
||||
assert!(pallet_nomination_pools::PoolMembers::<T>::contains_key(&1));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -623,39 +528,31 @@ mod on_idle {
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// register for fast unstake
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), None));
|
||||
assert_eq!(Queue::<T>::get(1), Some(None));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
assert_eq!(Queue::<T>::get(1), Some(()));
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3], maybe_pool_id: None })
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3] })
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2], maybe_pool_id: None })
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2] })
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1],
|
||||
maybe_pool_id: None
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1] })
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 1, 0],
|
||||
maybe_pool_id: None
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 1, 0] })
|
||||
);
|
||||
|
||||
// when: a new era happens right before one is free.
|
||||
@@ -670,7 +567,6 @@ mod on_idle {
|
||||
stash: 1,
|
||||
// note era 0 is pruned to keep the vector length sane.
|
||||
checked: bounded_vec![3, 2, 1, 4],
|
||||
maybe_pool_id: None
|
||||
})
|
||||
);
|
||||
|
||||
@@ -685,7 +581,7 @@ mod on_idle {
|
||||
Event::Checking { stash: 1, eras: vec![1] },
|
||||
Event::Checking { stash: 1, eras: vec![0] },
|
||||
Event::Checking { stash: 1, eras: vec![4] },
|
||||
Event::Unstaked { stash: 1, maybe_pool_id: None, result: Ok(()) }
|
||||
Event::Unstaked { stash: 1, result: Ok(()) }
|
||||
]
|
||||
);
|
||||
assert_unstaked(&1);
|
||||
@@ -700,23 +596,19 @@ mod on_idle {
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
|
||||
// register for fast unstake
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), Some(1_u32)));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
|
||||
// process 2 blocks
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3], maybe_pool_id: Some(1) })
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3] })
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2],
|
||||
maybe_pool_id: Some(1)
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2] })
|
||||
);
|
||||
|
||||
// when
|
||||
@@ -726,21 +618,13 @@ mod on_idle {
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2],
|
||||
maybe_pool_id: Some(1)
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2] })
|
||||
);
|
||||
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2],
|
||||
maybe_pool_id: Some(1)
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2] })
|
||||
);
|
||||
|
||||
// then we register a new era.
|
||||
@@ -752,22 +636,14 @@ mod on_idle {
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 4],
|
||||
maybe_pool_id: Some(1)
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 4] })
|
||||
);
|
||||
|
||||
// progress to end
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 1,
|
||||
checked: bounded_vec![3, 2, 4, 1],
|
||||
maybe_pool_id: Some(1)
|
||||
})
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3, 2, 4, 1] })
|
||||
);
|
||||
|
||||
// but notice that we don't care about era 0 instead anymore! we're done.
|
||||
@@ -781,12 +657,11 @@ mod on_idle {
|
||||
Event::Checking { stash: 1, eras: vec![2] },
|
||||
Event::Checking { stash: 1, eras: vec![4] },
|
||||
Event::Checking { stash: 1, eras: vec![1] },
|
||||
Event::Unstaked { stash: 1, maybe_pool_id: Some(1), result: Ok(()) }
|
||||
Event::Unstaked { stash: 1, result: Ok(()) }
|
||||
]
|
||||
);
|
||||
|
||||
assert_unstaked(&1);
|
||||
assert!(pallet_nomination_pools::PoolMembers::<T>::contains_key(&1));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -812,26 +687,18 @@ mod on_idle {
|
||||
assert_ok!(Staking::nominate(RuntimeOrigin::signed(exposed), vec![exposed]));
|
||||
|
||||
// register the exposed one.
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(exposed), None));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(exposed)));
|
||||
|
||||
// a few blocks later, we realize they are slashed
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: exposed,
|
||||
checked: bounded_vec![3],
|
||||
maybe_pool_id: None
|
||||
})
|
||||
Some(UnstakeRequest { stash: exposed, checked: bounded_vec![3] })
|
||||
);
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: exposed,
|
||||
checked: bounded_vec![3, 2],
|
||||
maybe_pool_id: None
|
||||
})
|
||||
Some(UnstakeRequest { stash: exposed, checked: bounded_vec![3, 2] })
|
||||
);
|
||||
next_block(true);
|
||||
assert_eq!(Head::<T>::get(), None);
|
||||
@@ -872,17 +739,13 @@ mod on_idle {
|
||||
assert_ok!(Staking::nominate(RuntimeOrigin::signed(exposed), vec![exposed]));
|
||||
|
||||
// register the exposed one.
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(exposed), None));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(exposed)));
|
||||
|
||||
// a few blocks later, we realize they are slashed
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: exposed,
|
||||
checked: bounded_vec![3, 2],
|
||||
maybe_pool_id: None
|
||||
})
|
||||
Some(UnstakeRequest { stash: exposed, checked: bounded_vec![3, 2] })
|
||||
);
|
||||
next_block(true);
|
||||
assert_eq!(Head::<T>::get(), None);
|
||||
@@ -909,10 +772,7 @@ mod on_idle {
|
||||
RuntimeOrigin::signed(VALIDATOR_PREFIX),
|
||||
vec![VALIDATOR_PREFIX]
|
||||
));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(
|
||||
RuntimeOrigin::signed(VALIDATOR_PREFIX),
|
||||
None
|
||||
));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(VALIDATOR_PREFIX)));
|
||||
|
||||
// but they indeed are exposed!
|
||||
assert!(pallet_staking::ErasStakers::<T>::contains_key(
|
||||
@@ -943,17 +803,13 @@ mod on_idle {
|
||||
assert_ok!(Staking::validate(RuntimeOrigin::signed(42), Default::default()));
|
||||
|
||||
// let them register:
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(42), None));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(42)));
|
||||
|
||||
// 2 block's enough to unstake them.
|
||||
next_block(true);
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest {
|
||||
stash: 42,
|
||||
checked: bounded_vec![3, 2, 1, 0],
|
||||
maybe_pool_id: None
|
||||
})
|
||||
Some(UnstakeRequest { stash: 42, checked: bounded_vec![3, 2, 1, 0] })
|
||||
);
|
||||
next_block(true);
|
||||
assert_eq!(Head::<T>::get(), None);
|
||||
@@ -962,7 +818,7 @@ mod on_idle {
|
||||
fast_unstake_events_since_last_call(),
|
||||
vec![
|
||||
Event::Checking { stash: 42, eras: vec![3, 2, 1, 0] },
|
||||
Event::Unstaked { stash: 42, maybe_pool_id: None, result: Ok(()) }
|
||||
Event::Unstaked { stash: 42, result: Ok(()) }
|
||||
]
|
||||
);
|
||||
});
|
||||
@@ -990,7 +846,7 @@ mod signed_extension {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// given: stash for 2 is 1.
|
||||
// when
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), None));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
|
||||
// then
|
||||
// stash can't.
|
||||
@@ -1010,7 +866,7 @@ mod signed_extension {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// given: stash for 2 is 1.
|
||||
// when
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2), None));
|
||||
assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(2)));
|
||||
|
||||
ErasToCheckPerBlock::<T>::put(1);
|
||||
CurrentEra::<T>::put(BondingDuration::get());
|
||||
@@ -1018,7 +874,7 @@ mod signed_extension {
|
||||
|
||||
assert_eq!(
|
||||
Head::<T>::get(),
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3], maybe_pool_id: None })
|
||||
Some(UnstakeRequest { stash: 1, checked: bounded_vec![3] })
|
||||
);
|
||||
|
||||
// then
|
||||
|
||||
@@ -23,7 +23,6 @@ use frame_support::{
|
||||
traits::{Currency, Get, IsSubType},
|
||||
BoundedVec, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound,
|
||||
};
|
||||
use pallet_nomination_pools::PoolId;
|
||||
use scale_info::TypeInfo;
|
||||
use sp_runtime::transaction_validity::{InvalidTransaction, TransactionValidityError};
|
||||
use sp_staking::EraIndex;
|
||||
@@ -42,8 +41,6 @@ pub struct UnstakeRequest<AccountId: Eq + PartialEq + Debug, MaxChecked: Get<u32
|
||||
pub(crate) stash: AccountId,
|
||||
/// The list of eras for which they have been checked.
|
||||
pub(crate) checked: BoundedVec<EraIndex, MaxChecked>,
|
||||
/// The pool they wish to join, if any.
|
||||
pub(crate) maybe_pool_id: Option<PoolId>,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Clone, Eq, PartialEq, TypeInfo, RuntimeDebugNoBound)]
|
||||
|
||||
Reference in New Issue
Block a user