diff --git a/substrate/frame/fast-unstake/src/benchmarking.rs b/substrate/frame/fast-unstake/src/benchmarking.rs index 5bbdc163ac02c..f59f79f533e78 100644 --- a/substrate/frame/fast-unstake/src/benchmarking.rs +++ b/substrate/frame/fast-unstake/src/benchmarking.rs @@ -102,6 +102,9 @@ mod benchmarks { #[benchmark] fn on_idle_unstake(b: Linear<1, { T::BatchSize::get() }>) { ErasToCheckPerBlock::::put(1); + // initialise the era. + T::Staking::set_active_era(0, Some(0)); + for who in create_unexposed_batch::(b).into_iter() { assert_ok!(Pallet::::register_fast_unstake(RawOrigin::Signed(who.clone()).into(),)); } @@ -134,7 +137,7 @@ mod benchmarks { let u = T::MaxErasToCheckPerBlock::get().min(T::Staking::bonding_duration()); ErasToCheckPerBlock::::put(u); - T::Staking::set_current_era(u); + T::Staking::set_active_era(u, Some(0)); // setup staking with v validators and u eras of data (0..=u+1) setup_staking::(v, u); diff --git a/substrate/frame/fast-unstake/src/lib.rs b/substrate/frame/fast-unstake/src/lib.rs index 5006ed391da21..86a04dd3467ea 100644 --- a/substrate/frame/fast-unstake/src/lib.rs +++ b/substrate/frame/fast-unstake/src/lib.rs @@ -520,18 +520,17 @@ pub mod pallet { ); // the range that we're allowed to check in this round. - let current_era = T::Staking::current_era(); + let active_era = T::Staking::active_era(); let bonding_duration = T::Staking::bonding_duration(); // prune all the old eras that we don't care about. This will help us keep the bound // of `checked`. - checked.retain(|e| *e >= current_era.saturating_sub(bonding_duration)); + checked.retain(|e| *e >= active_era.saturating_sub(bonding_duration)); let unchecked_eras_to_check = { // get the last available `bonding_duration` eras up to current era in reverse // order. - let total_check_range = (current_era.saturating_sub(bonding_duration)..= - current_era) + let total_check_range = (active_era.saturating_sub(bonding_duration)..=active_era) .rev() .collect::>(); debug_assert!( diff --git a/substrate/frame/fast-unstake/src/mock.rs b/substrate/frame/fast-unstake/src/mock.rs index 77b26a85cdbfc..3bb510845c4c9 100644 --- a/substrate/frame/fast-unstake/src/mock.rs +++ b/substrate/frame/fast-unstake/src/mock.rs @@ -329,3 +329,11 @@ pub fn create_exposed_nominator(exposed: AccountId, era: u32) { // register the exposed one. assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(exposed))); } + +pub fn set_active_era(era: sp_staking::EraIndex) { + pallet_staking::CurrentEra::::put(era); + pallet_staking::ActiveEra::::put(pallet_staking::ActiveEraInfo { + index: era, + start: Some(0), + }); +} diff --git a/substrate/frame/fast-unstake/src/tests.rs b/substrate/frame/fast-unstake/src/tests.rs index 0fddb88e02b7b..1b3a581689113 100644 --- a/substrate/frame/fast-unstake/src/tests.rs +++ b/substrate/frame/fast-unstake/src/tests.rs @@ -230,7 +230,7 @@ mod on_idle { fn early_exit() { ExtBuilder::default().build_and_execute(|| { ErasToCheckPerBlock::::put(BondingDuration::get() + 1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // set up Queue item assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1))); @@ -249,7 +249,7 @@ mod on_idle { fn if_head_not_set_one_random_fetched_from_queue() { ExtBuilder::default().build_and_execute(|| { ErasToCheckPerBlock::::put(BondingDuration::get() + 1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // given // reserved balance prior to registering for fast unstake. @@ -324,7 +324,7 @@ mod on_idle { fn successful_multi_queue() { ExtBuilder::default().build_and_execute(|| { ErasToCheckPerBlock::::put(BondingDuration::get() + 1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // register multi accounts for fast unstake assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1))); @@ -378,7 +378,7 @@ mod on_idle { fn successful_unstake() { ExtBuilder::default().build_and_execute(|| { ErasToCheckPerBlock::::put(BondingDuration::get() + 1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // register for fast unstake assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1))); @@ -418,7 +418,7 @@ mod on_idle { fn successful_unstake_all_eras_per_block() { ExtBuilder::default().build_and_execute(|| { ErasToCheckPerBlock::::put(BondingDuration::get() + 1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); Balances::make_free_balance_be(&2, 100); @@ -461,7 +461,7 @@ mod on_idle { ExtBuilder::default().build_and_execute(|| { // put 1 era per block ErasToCheckPerBlock::::put(1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // register for fast unstake assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1))); @@ -539,7 +539,7 @@ mod on_idle { ExtBuilder::default().build_and_execute(|| { // given ErasToCheckPerBlock::::put(1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // register for fast unstake assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1))); @@ -582,7 +582,7 @@ mod on_idle { ); // when: a new era happens right before one is free. - CurrentEra::::put(CurrentEra::::get().unwrap() + 1); + set_active_era(::active_era() + 1); ExtBuilder::register_stakers_for_era(CurrentEra::::get().unwrap()); // then @@ -620,7 +620,7 @@ mod on_idle { ExtBuilder::default().build_and_execute(|| { // give: put 1 era per block ErasToCheckPerBlock::::put(1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // register for fast unstake assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1))); @@ -668,7 +668,7 @@ mod on_idle { // then we register a new era. Ongoing::set(false); - CurrentEra::::put(CurrentEra::::get().unwrap() + 1); + set_active_era(::active_era() + 1); ExtBuilder::register_stakers_for_era(CurrentEra::::get().unwrap()); // then we can progress again, but notice that the new era that had to be checked. @@ -716,7 +716,7 @@ mod on_idle { fn exposed_nominator_cannot_unstake() { ExtBuilder::default().build_and_execute(|| { ErasToCheckPerBlock::::put(1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // create an exposed nominator in era 1 let exposed = 666; @@ -760,7 +760,7 @@ mod on_idle { // same as the previous check, but we check 2 eras per block, and we make the exposed be // exposed in era 0, so that it is detected halfway in a check era. ErasToCheckPerBlock::::put(2); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // create an exposed nominator in era 0 let exposed = 666; @@ -794,7 +794,7 @@ mod on_idle { fn validators_cannot_bail() { ExtBuilder::default().build_and_execute(|| { ErasToCheckPerBlock::::put(BondingDuration::get() + 1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // a validator switches role and register... assert_ok!(Staking::nominate( @@ -831,7 +831,7 @@ mod on_idle { fn unexposed_validator_can_fast_unstake() { ExtBuilder::default().build_and_execute(|| { ErasToCheckPerBlock::::put(BondingDuration::get() + 1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // create a new validator that 100% not exposed. Balances::make_free_balance_be(&42, 100 + Deposit::get()); @@ -872,7 +872,7 @@ mod batched { fn single_block_batched_successful() { ExtBuilder::default().batch(3).build_and_execute(|| { ErasToCheckPerBlock::::put(BondingDuration::get() + 1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1))); assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(3))); @@ -923,7 +923,7 @@ mod batched { fn multi_block_batched_successful() { ExtBuilder::default().batch(3).build_and_execute(|| { ErasToCheckPerBlock::::put(2); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1))); assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(3))); @@ -989,7 +989,7 @@ mod batched { fn multi_block_batched_some_fail() { ExtBuilder::default().batch(4).build_and_execute(|| { ErasToCheckPerBlock::::put(2); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // register two good ones. assert_ok!(FastUnstake::register_fast_unstake(RuntimeOrigin::signed(1))); @@ -1054,7 +1054,7 @@ mod batched { fn multi_block_batched_all_fail_early_exit() { ExtBuilder::default().batch(2).build_and_execute(|| { ErasToCheckPerBlock::::put(1); - CurrentEra::::put(BondingDuration::get()); + set_active_era(BondingDuration::get()); // register two bad ones. create_exposed_nominator(666, 3); diff --git a/substrate/frame/nomination-pools/fuzzer/src/call.rs b/substrate/frame/nomination-pools/fuzzer/src/call.rs index 9e10d87da6750..072aa0344199d 100644 --- a/substrate/frame/nomination-pools/fuzzer/src/call.rs +++ b/substrate/frame/nomination-pools/fuzzer/src/call.rs @@ -302,7 +302,7 @@ fn main() { // trigger an era change, and check the status of the reward agent. if iteration % ERA == 0 { - CurrentEra::mutate(|c| *c += 1); + ActiveEra::mutate(|c| *c += 1); BondedPools::::iter().for_each(|(id, _)| { let amount = random_ed_multiple(&mut rng); let _ = diff --git a/substrate/frame/nomination-pools/src/adapter.rs b/substrate/frame/nomination-pools/src/adapter.rs index f1c68af4ea6ad..d6b58647f80ae 100644 --- a/substrate/frame/nomination-pools/src/adapter.rs +++ b/substrate/frame/nomination-pools/src/adapter.rs @@ -95,9 +95,9 @@ pub trait StakeStrategy { Self::CoreStaking::bonding_duration() } - /// See [`StakingInterface::current_era`]. - fn current_era() -> EraIndex { - Self::CoreStaking::current_era() + /// See [`StakingInterface::active_era`]. + fn active_era() -> EraIndex { + Self::CoreStaking::active_era() } /// See [`StakingInterface::minimum_nominator_bond`]. diff --git a/substrate/frame/nomination-pools/src/lib.rs b/substrate/frame/nomination-pools/src/lib.rs index 8b6fdee58bffe..3622c36e2f024 100644 --- a/substrate/frame/nomination-pools/src/lib.rs +++ b/substrate/frame/nomination-pools/src/lib.rs @@ -302,7 +302,7 @@ //! ``` //! //! For scalability, a bound is maintained on the number of unbonding sub pools (see -//! [`TotalUnbondingPools`]). An unbonding pool is removed once its older than `current_era - +//! [`TotalUnbondingPools`]). An unbonding pool is removed once its older than `active_era - //! TotalUnbondingPools`. An unbonding pool is merged into the unbonded pool with //! //! ```text @@ -312,9 +312,9 @@ //! //! This scheme "averages" out the points value in the unbonded pool. //! -//! Once a members `unbonding_era` is older than `current_era - +//! Once a members `unbonding_era` is older than `active_era - //! [sp_staking::StakingInterface::bonding_duration]`, it can can cash it's points out of the -//! corresponding unbonding pool. If it's `unbonding_era` is older than `current_era - +//! corresponding unbonding pool. If it's `unbonding_era` is older than `active_era - //! TotalUnbondingPools`, it can cash it's points from the unbonded pool. //! //! **Relevant extrinsics:** @@ -672,13 +672,13 @@ impl PoolMember { /// Infallible, noop if no unbonding eras exist. fn withdraw_unlocked( &mut self, - current_era: EraIndex, + active_era: EraIndex, ) -> BoundedBTreeMap, T::MaxUnbonding> { // NOTE: if only drain-filter was stable.. let mut removed_points = BoundedBTreeMap::, T::MaxUnbonding>::default(); self.unbonding_eras.retain(|e, p| { - if *e > current_era { + if *e > active_era { true } else { removed_points @@ -1593,7 +1593,7 @@ impl UnbondPool { pub struct SubPools { /// A general, era agnostic pool of funds that have fully unbonded. The pools /// of `Self::with_era` will lazily be merged into into this pool if they are - /// older then `current_era - TotalUnbondingPools`. + /// older then `active_era - TotalUnbondingPools`. pub no_era: UnbondPool, /// Map of era in which a pool becomes unbonded in => unbond pools. pub with_era: BoundedBTreeMap, TotalUnbondingPools>, @@ -1604,12 +1604,12 @@ impl SubPools { /// /// This is often used whilst getting the sub-pool from storage, thus it consumes and returns /// `Self` for ergonomic purposes. - fn maybe_merge_pools(mut self, current_era: EraIndex) -> Self { + fn maybe_merge_pools(mut self, active_era: EraIndex) -> Self { // Ex: if `TotalUnbondingPools` is 5 and current era is 10, we only want to retain pools // 6..=10. Note that in the first few eras where `checked_sub` is `None`, we don't remove // anything. if let Some(newest_era_to_remove) = - current_era.checked_sub(T::PostUnbondingPoolsWindow::get()) + active_era.checked_sub(T::PostUnbondingPoolsWindow::get()) { self.with_era.retain(|k, v| { if *k > newest_era_to_remove { @@ -2300,8 +2300,8 @@ pub mod pallet { &mut reward_pool, )?; - let current_era = T::StakeAdapter::current_era(); - let unbond_era = T::StakeAdapter::bonding_duration().saturating_add(current_era); + let active_era = T::StakeAdapter::active_era(); + let unbond_era = T::StakeAdapter::bonding_duration().saturating_add(active_era); // Unbond in the actual underlying nominator. let unbonding_balance = bonded_pool.dissolve(unbonding_points); @@ -2310,7 +2310,7 @@ pub mod pallet { // Note that we lazily create the unbonding pools here if they don't already exist let mut sub_pools = SubPoolsStorage::::get(member.pool_id) .unwrap_or_default() - .maybe_merge_pools(current_era); + .maybe_merge_pools(active_era); // Update the unbond pool associated with the current era with the unbonded funds. Note // that we lazily create the unbond pool if it does not yet exist. @@ -2420,7 +2420,7 @@ pub mod pallet { let mut member = PoolMembers::::get(&member_account).ok_or(Error::::PoolMemberNotFound)?; - let current_era = T::StakeAdapter::current_era(); + let active_era = T::StakeAdapter::active_era(); let bonded_pool = BondedPool::::get(member.pool_id) .defensive_ok_or::>(DefensiveError::PoolNotFound.into())?; @@ -2448,7 +2448,7 @@ pub mod pallet { let pool_account = bonded_pool.bonded_account(); // NOTE: must do this after we have done the `ok_to_withdraw_unbonded_other_with` check. - let withdrawn_points = member.withdraw_unlocked(current_era); + let withdrawn_points = member.withdraw_unlocked(active_era); ensure!(!withdrawn_points.is_empty(), Error::::CannotWithdrawAny); // Before calculating the `balance_to_unbond`, we call withdraw unbonded to ensure the diff --git a/substrate/frame/nomination-pools/src/mock.rs b/substrate/frame/nomination-pools/src/mock.rs index b97d98d66948e..6e03ede2c6556 100644 --- a/substrate/frame/nomination-pools/src/mock.rs +++ b/substrate/frame/nomination-pools/src/mock.rs @@ -49,7 +49,7 @@ pub fn default_reward_account() -> AccountId { parameter_types! { pub static MinJoinBondConfig: Balance = 2; - pub static CurrentEra: EraIndex = 0; + pub static ActiveEra: EraIndex = 0; pub static BondingDuration: EraIndex = 3; pub storage BondedBalanceMap: BTreeMap = Default::default(); // map from a user to a vec of eras and amounts being unlocked in each era. @@ -100,8 +100,8 @@ impl sp_staking::StakingInterface for StakingMock { unimplemented!("method currently not used in testing") } - fn current_era() -> EraIndex { - CurrentEra::get() + fn active_era() -> EraIndex { + ActiveEra::get() } fn bonding_duration() -> EraIndex { @@ -132,7 +132,7 @@ impl sp_staking::StakingInterface for StakingMock { *x.get_mut(who).unwrap() = x.get_mut(who).unwrap().saturating_sub(amount); BondedBalanceMap::set(&x); - let era = Self::current_era(); + let era = Self::active_era(); let unlocking_at = era + Self::bonding_duration(); let mut y = UnbondingBalanceMap::get(); y.entry(*who).or_insert(Default::default()).push((unlocking_at, amount)); @@ -161,9 +161,9 @@ impl sp_staking::StakingInterface for StakingMock { let staker_map = unbonding_map.get_mut(&who).ok_or("Nothing to unbond")?; let unlocking_before = unlocking(&staker_map); - let current_era = Self::current_era(); + let active_era = Self::active_era(); - staker_map.retain(|(unlocking_at, _amount)| *unlocking_at > current_era); + staker_map.retain(|(unlocking_at, _amount)| *unlocking_at > active_era); // if there was a withdrawal, notify the pallet. let withdraw_amount = unlocking_before.saturating_sub(unlocking(&staker_map)); @@ -231,7 +231,15 @@ impl sp_staking::StakingInterface for StakingMock { } #[cfg(feature = "runtime-benchmarks")] - fn set_current_era(_era: EraIndex) { + fn set_active_era(_era: EraIndex, _start: Option) { + unimplemented!("method currently not used in testing") + } + + #[cfg(feature = "runtime-benchmarks")] + fn activate_next_era( + _era_duration_in_session: sp_staking::SessionIndex, + _era_duration_in_millis: u64, + ) { unimplemented!("method currently not used in testing") } diff --git a/substrate/frame/nomination-pools/src/tests.rs b/substrate/frame/nomination-pools/src/tests.rs index 9926e4bccb6f9..171adcdb38dbd 100644 --- a/substrate/frame/nomination-pools/src/tests.rs +++ b/substrate/frame/nomination-pools/src/tests.rs @@ -579,19 +579,19 @@ mod sub_pools { }, }; - // When `current_era < TotalUnbondingPools`, + // When `active_era < TotalUnbondingPools`, let sub_pool_1 = sub_pool_0.clone().maybe_merge_pools(0); // Then it exits early without modifications assert_eq!(sub_pool_1, sub_pool_0); - // When `current_era == TotalUnbondingPools`, + // When `active_era == TotalUnbondingPools`, let sub_pool_1 = sub_pool_1.maybe_merge_pools(1); // Then it exits early without modifications assert_eq!(sub_pool_1, sub_pool_0); - // When `current_era - TotalUnbondingPools == 0`, + // When `active_era - TotalUnbondingPools == 0`, let mut sub_pool_1 = sub_pool_1.maybe_merge_pools(2); // Then era 0 is merged into the `no_era` pool @@ -608,7 +608,7 @@ mod sub_pools { .try_insert(5, UnbondPool:: { points: 50, balance: 50 }) .unwrap(); - // When `current_era - TotalUnbondingPools == 1` + // When `active_era - TotalUnbondingPools == 1` let sub_pool_2 = sub_pool_1.maybe_merge_pools(3); let era_1_pool = sub_pool_0.with_era.remove(&1).unwrap(); @@ -617,7 +617,7 @@ mod sub_pools { sub_pool_0.no_era.balance += era_1_pool.balance; assert_eq!(sub_pool_2, sub_pool_0); - // When `current_era - TotalUnbondingPools == 5`, so all pools with era <= 4 are removed + // When `active_era - TotalUnbondingPools == 5`, so all pools with era <= 4 are removed let sub_pool_3 = sub_pool_2.maybe_merge_pools(7); // Then all eras <= 5 are merged into the `no_era` pool @@ -2343,11 +2343,11 @@ mod claim_payout { assert_ok!(Pools::set_state(RuntimeOrigin::signed(902), 1, PoolState::Destroying)); assert_ok!(fully_unbond_permissioned(20)); - CurrentEra::set(3); + ActiveEra::set(3); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(20), 20, 0)); assert_ok!(fully_unbond_permissioned(10)); - CurrentEra::set(6); + ActiveEra::set(6); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0)); assert_eq!( @@ -2915,7 +2915,7 @@ mod unbond { ); // When - CurrentEra::set(3); + ActiveEra::set(3); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 40, 0)); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 550, 0)); assert_ok!(fully_unbond_permissioned(10)); @@ -2975,8 +2975,8 @@ mod unbond { unsafe_set_state(1, PoolState::Destroying); // When - let current_era = 1 + TotalUnbondingPools::::get(); - CurrentEra::set(current_era); + let active_era = 1 + TotalUnbondingPools::::get(); + ActiveEra::set(active_era); assert_ok!(fully_unbond_permissioned(10)); @@ -2987,7 +2987,7 @@ mod unbond { no_era: UnbondPool { balance: 10 + 20, points: 100 + 20 }, with_era: unbonding_pools_with_era! { 2 + 3 => UnbondPool { balance: 101, points: 101}, - current_era + 3 => UnbondPool { balance: 10, points: 10 }, + active_era + 3 => UnbondPool { balance: 10, points: 10 }, }, }, ); @@ -3156,7 +3156,7 @@ mod unbond { ); // but when everyone is unbonded it can.. - CurrentEra::set(3); + ActiveEra::set(3); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 100, 0)); // still permissionless unbond must be full. @@ -3251,7 +3251,7 @@ mod unbond { ); assert_eq!(BondedPool::::get(1).unwrap().points, 10); assert!(SubPoolsStorage::::get(1).is_none()); - assert_eq!(CurrentEra::get(), 0); + assert_eq!(ActiveEra::get(), 0); assert_eq!(BondingDuration::get(), 3); // so the depositor can leave, just keeps the test simpler. @@ -3313,7 +3313,7 @@ mod unbond { ); // when: casual further unbond, next era. - CurrentEra::set(1); + ActiveEra::set(1); assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 1)); // then @@ -3383,7 +3383,7 @@ mod unbond { // given assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 2)); - CurrentEra::set(1); + ActiveEra::set(1); assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 3)); assert_eq!( PoolMembers::::get(20).unwrap().unbonding_eras, @@ -3391,7 +3391,7 @@ mod unbond { ); // when - CurrentEra::set(2); + ActiveEra::set(2); assert_noop!( frame_support::storage::with_storage_layer(|| Pools::unbond( RuntimeOrigin::signed(20), @@ -3501,7 +3501,7 @@ mod unbond { ] ); - CurrentEra::set(1); + ActiveEra::set(1); Currency::set_balance(&default_reward_account(), 4 * Currency::minimum_balance()); assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 3)); @@ -3514,7 +3514,7 @@ mod unbond { ] ); - CurrentEra::set(2); + ActiveEra::set(2); Currency::set_balance(&default_reward_account(), 4 * Currency::minimum_balance()); assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 5)); @@ -3549,7 +3549,7 @@ mod pool_withdraw_unbonded { assert_eq!(pool_balance(1), 20); // When - CurrentEra::set(StakingMock::current_era() + StakingMock::bonding_duration() + 1); + ActiveEra::set(StakingMock::active_era() + StakingMock::bonding_duration() + 1); assert_ok!(Pools::pool_withdraw_unbonded(RuntimeOrigin::signed(10), 1, 0)); // Then their unbonding balance is no longer locked @@ -3570,7 +3570,7 @@ mod pool_withdraw_unbonded { assert_eq!(TotalValueLocked::::get(), 20); // When - CurrentEra::set(StakingMock::current_era() + StakingMock::bonding_duration() + 1); + ActiveEra::set(StakingMock::active_era() + StakingMock::bonding_duration() + 1); assert_ok!(Pools::pool_withdraw_unbonded(RuntimeOrigin::signed(10), 1, 0)); assert_eq!(TotalValueLocked::::get(), 15); @@ -3613,8 +3613,8 @@ mod withdraw_unbonded { assert_ok!(Pools::fully_unbond(RuntimeOrigin::signed(40), 40)); assert_eq!(pool_balance(1), 600); - let mut current_era = 1; - CurrentEra::set(current_era); + let mut active_era = 1; + ActiveEra::set(active_era); let mut sub_pools = SubPoolsStorage::::get(1).unwrap(); let unbond_pool = sub_pools.with_era.get_mut(&3).unwrap(); @@ -3622,7 +3622,7 @@ mod withdraw_unbonded { assert_eq!(*unbond_pool, UnbondPool { points: 550 + 40, balance: 550 + 40 }); assert_eq!(TotalValueLocked::::get(), 600); - // Simulate a slash to the pool with_era(current_era), decreasing the balance by + // Simulate a slash to the pool with_era(active_era), decreasing the balance by // half { unbond_pool.balance /= 2; // 295 @@ -3635,7 +3635,7 @@ mod withdraw_unbonded { let mut x = UnbondingBalanceMap::get(); x.get_mut(&default_bonded_account()) .unwrap() - .get_mut(current_era as usize) + .get_mut(active_era as usize) .unwrap() .1 /= 2; UnbondingBalanceMap::set(&x); @@ -3646,15 +3646,15 @@ mod withdraw_unbonded { assert_eq!(StakingMock::active_stake(&default_bonded_account()).unwrap(), 5); }; - // Advance the current_era to ensure all `with_era` pools will be merged into + // Advance the active_era to ensure all `with_era` pools will be merged into // `no_era` pool - current_era += TotalUnbondingPools::::get(); - CurrentEra::set(current_era); + active_era += TotalUnbondingPools::::get(); + ActiveEra::set(active_era); // Simulate some other call to unbond that would merge `with_era` pools into // `no_era` let sub_pools = - SubPoolsStorage::::get(1).unwrap().maybe_merge_pools(current_era); + SubPoolsStorage::::get(1).unwrap().maybe_merge_pools(active_era); SubPoolsStorage::::insert(1, sub_pools); assert_eq!( @@ -3727,8 +3727,8 @@ mod withdraw_unbonded { assert_ok!(fully_unbond_permissioned(10)); assert_eq!(member_delegation(10), 10); - current_era += 3; - CurrentEra::set(current_era); + active_era += 3; + ActiveEra::set(active_era); // when assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0)); @@ -3794,7 +3794,7 @@ mod withdraw_unbonded { ] ); - CurrentEra::set(StakingMock::bonding_duration()); + ActiveEra::set(StakingMock::bonding_duration()); // When assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(40), 40, 0)); @@ -3836,7 +3836,7 @@ mod withdraw_unbonded { unbonding_pools_with_era! { 6 => UnbondPool { points: 5, balance: 5 }} ); - CurrentEra::set(CurrentEra::get() + 3); + ActiveEra::set(ActiveEra::get() + 3); // set metadata to check that it's being removed on dissolve assert_ok!(Pools::set_metadata(RuntimeOrigin::signed(900), 1, vec![1, 1])); @@ -3934,7 +3934,7 @@ mod withdraw_unbonded { } } ); - CurrentEra::set(StakingMock::bonding_duration()); + ActiveEra::set(StakingMock::bonding_duration()); // Cannot kick when pool is open assert_noop!( @@ -4016,7 +4016,7 @@ mod withdraw_unbonded { } } ); - CurrentEra::set(StakingMock::bonding_duration()); + ActiveEra::set(StakingMock::bonding_duration()); assert_eq!(member_delegation(100), 100); // Cannot permissionlessly withdraw @@ -4058,7 +4058,7 @@ mod withdraw_unbonded { // given assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 6)); - CurrentEra::set(1); + ActiveEra::set(1); assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 1)); assert_eq!( PoolMembers::::get(10).unwrap().unbonding_eras, @@ -4089,14 +4089,14 @@ mod withdraw_unbonded { ); // when - CurrentEra::set(2); + ActiveEra::set(2); assert_noop!( Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0), Error::::CannotWithdrawAny ); // when - CurrentEra::set(3); + ActiveEra::set(3); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0)); // then @@ -4119,7 +4119,7 @@ mod withdraw_unbonded { ); // when - CurrentEra::set(4); + ActiveEra::set(4); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0)); // then @@ -4146,7 +4146,7 @@ mod withdraw_unbonded { ExtBuilder::default().add_members(vec![(11, 10)]).build_and_execute(|| { // given assert_ok!(Pools::unbond(RuntimeOrigin::signed(11), 11, 6)); - CurrentEra::set(1); + ActiveEra::set(1); assert_ok!(Pools::unbond(RuntimeOrigin::signed(11), 11, 1)); assert_eq!( PoolMembers::::get(11).unwrap().unbonding_eras, @@ -4177,14 +4177,14 @@ mod withdraw_unbonded { ); // when - CurrentEra::set(2); + ActiveEra::set(2); assert_noop!( Pools::withdraw_unbonded(RuntimeOrigin::signed(11), 11, 0), Error::::CannotWithdrawAny ); // when - CurrentEra::set(3); + ActiveEra::set(3); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(11), 11, 0)); // then @@ -4207,7 +4207,7 @@ mod withdraw_unbonded { ); // when - CurrentEra::set(4); + ActiveEra::set(4); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(11), 11, 0)); // then @@ -4244,7 +4244,7 @@ mod withdraw_unbonded { assert_eq!(TotalValueLocked::::get(), 110); // progress one era and unbond the leftover. - CurrentEra::set(1); + ActiveEra::set(1); assert_ok!(Pools::unbond(RuntimeOrigin::signed(100), 100, 25)); assert_eq!( PoolMembers::::get(100).unwrap().unbonding_eras, @@ -4259,7 +4259,7 @@ mod withdraw_unbonded { assert_eq!(TotalValueLocked::::get(), 110); // now the 75 should be free. - CurrentEra::set(3); + ActiveEra::set(3); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(100), 100, 0)); assert_eq!( pool_events_since_last_call(), @@ -4281,7 +4281,7 @@ mod withdraw_unbonded { assert_eq!(TotalValueLocked::::get(), 35); // the 25 should be free now, and the member removed. - CurrentEra::set(4); + ActiveEra::set(4); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(100), 100, 0)); assert_eq!( pool_events_since_last_call(), @@ -4335,7 +4335,7 @@ mod withdraw_unbonded { ); // when - CurrentEra::set(1); + ActiveEra::set(1); assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 5)); // then still member-local unbonding is pretty much in sync with the global pools. @@ -4359,7 +4359,7 @@ mod withdraw_unbonded { ); // when - CurrentEra::set(2); + ActiveEra::set(2); assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 5)); // then still member-local unbonding is pretty much in sync with the global pools. @@ -4384,7 +4384,7 @@ mod withdraw_unbonded { ); // when - CurrentEra::set(5); + ActiveEra::set(5); assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 5)); // then @@ -4468,7 +4468,7 @@ mod withdraw_unbonded { assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 7)); // progress one era and unbond the leftover. - CurrentEra::set(1); + ActiveEra::set(1); assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 3)); assert_eq!( @@ -4497,7 +4497,7 @@ mod withdraw_unbonded { assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 10)); // now the 7 should be free. - CurrentEra::set(3); + ActiveEra::set(3); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0)); assert_eq!( @@ -4519,7 +4519,7 @@ mod withdraw_unbonded { ); // the 13 should be free now, and the member removed. - CurrentEra::set(4); + ActiveEra::set(4); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0)); assert_eq!( @@ -4538,7 +4538,7 @@ mod withdraw_unbonded { fn withdraw_unbonded_removes_claim_permissions_on_leave() { ExtBuilder::default().add_members(vec![(20, 20)]).build_and_execute(|| { // Given - CurrentEra::set(1); + ActiveEra::set(1); assert_eq!(PoolMembers::::get(20).unwrap().points, 20); assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 20)); @@ -4558,7 +4558,7 @@ mod withdraw_unbonded { ] ); - CurrentEra::set(5); + ActiveEra::set(5); // When assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(20), 20, 0)); @@ -4585,7 +4585,7 @@ mod withdraw_unbonded { unsafe_set_state(1, PoolState::Destroying); // set current era - CurrentEra::set(1); + ActiveEra::set(1); assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 10)); assert_eq!( @@ -4599,7 +4599,7 @@ mod withdraw_unbonded { ); // move to era when unbonded funds can be withdrawn. - CurrentEra::set(4); + ActiveEra::set(4); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0)); assert_eq!( @@ -4628,7 +4628,7 @@ mod withdraw_unbonded { unsafe_set_state(1, PoolState::Destroying); // set current era - CurrentEra::set(1); + ActiveEra::set(1); assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 10)); assert_eq!( @@ -4642,7 +4642,7 @@ mod withdraw_unbonded { ); // move to era when unbonded funds can be withdrawn. - CurrentEra::set(4); + ActiveEra::set(4); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 0)); assert_eq!( @@ -4846,7 +4846,7 @@ mod create { assert_ok!(Pools::set_state(RuntimeOrigin::signed(902), 1, PoolState::Destroying)); assert_ok!(fully_unbond_permissioned(10)); - CurrentEra::set(3); + ActiveEra::set(3); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 10)); assert_ok!(Pools::create_with_pool_id(RuntimeOrigin::signed(10), 20, 234, 654, 783, 1)); @@ -7626,7 +7626,7 @@ mod filter { // can unbond assert_ok!(Pools::unbond(RuntimeOrigin::signed(alice), alice, 5)); // and withdraw - CurrentEra::set(3); + ActiveEra::set(3); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(alice), alice, 0)); // WHEN alice is removed from restrict list diff --git a/substrate/frame/nomination-pools/test-delegate-stake/src/lib.rs b/substrate/frame/nomination-pools/test-delegate-stake/src/lib.rs index 103e38b57f0cf..5c8556a5e4050 100644 --- a/substrate/frame/nomination-pools/test-delegate-stake/src/lib.rs +++ b/substrate/frame/nomination-pools/test-delegate-stake/src/lib.rs @@ -46,7 +46,7 @@ use sp_staking::Agent; fn pool_lifecycle_e2e() { new_test_ext().execute_with(|| { assert_eq!(Balances::minimum_balance(), 5); - assert_eq!(CurrentEra::::get(), None); + assert_eq!(CurrentEra::::get(), Some(0)); // create the pool, we know this has id 1. assert_ok!(Pools::create(RuntimeOrigin::signed(10), 50, 10, 10, 10)); @@ -128,7 +128,7 @@ fn pool_lifecycle_e2e() { ); for e in 1..BondingDuration::get() { - CurrentEra::::set(Some(e)); + set_active_era(e); assert_noop!( Pools::withdraw_unbonded(RuntimeOrigin::signed(20), 20, 0), PoolsError::::CannotWithdrawAny @@ -136,7 +136,7 @@ fn pool_lifecycle_e2e() { } // members are now unlocked. - CurrentEra::::set(Some(BondingDuration::get())); + set_active_era(BondingDuration::get()); // depositor cannot still unbond assert_noop!( @@ -179,7 +179,7 @@ fn pool_lifecycle_e2e() { ); // waiting another bonding duration: - CurrentEra::::set(Some(BondingDuration::get() * 2)); + set_active_era(BondingDuration::get() * 2); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(10), 10, 1)); // pools is fully destroyed now. @@ -202,7 +202,7 @@ fn pool_lifecycle_e2e() { fn pool_chill_e2e() { new_test_ext().execute_with(|| { assert_eq!(Balances::minimum_balance(), 5); - assert_eq!(CurrentEra::::get(), None); + assert_eq!(CurrentEra::::get(), Some(0)); // create the pool, we know this has id 1. assert_ok!(Pools::create(RuntimeOrigin::signed(10), 50, 10, 10, 10)); @@ -304,7 +304,7 @@ fn pool_chill_e2e() { assert_ok!(Pools::nominate(RuntimeOrigin::signed(10), 1, vec![1, 2, 3])); // skip to make the unbonding period end. - CurrentEra::::set(Some(BondingDuration::get())); + set_active_era(BondingDuration::get()); // members can now withdraw. assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(20), 20, 0)); @@ -329,7 +329,7 @@ fn pool_slash_e2e() { new_test_ext().execute_with(|| { ExistentialDeposit::set(1); assert_eq!(Balances::minimum_balance(), 1); - assert_eq!(CurrentEra::::get(), None); + assert_eq!(CurrentEra::::get(), Some(0)); // create the pool, we know this has id 1. assert_ok!(Pools::create(RuntimeOrigin::signed(10), 40, 10, 10, 10)); @@ -372,7 +372,7 @@ fn pool_slash_e2e() { ); // now let's progress a bit. - CurrentEra::::set(Some(1)); + set_active_era(1); // 20 / 80 of the total funds are unlocked, and safe from any further slash. assert_ok!(Pools::unbond(RuntimeOrigin::signed(10), 10, 10)); @@ -393,7 +393,7 @@ fn pool_slash_e2e() { ] ); - CurrentEra::::set(Some(2)); + set_active_era(2); // note: depositor cannot fully unbond at this point. // these funds will still get slashed. @@ -443,7 +443,7 @@ fn pool_slash_e2e() { ] ); - CurrentEra::::set(Some(3)); + set_active_era(3); assert_ok!(Pools::unbond(RuntimeOrigin::signed(21), 21, 10)); assert_eq!( @@ -466,7 +466,7 @@ fn pool_slash_e2e() { ); // now we start withdrawing. we do it all at once, at era 6 where 20 and 21 are fully free. - CurrentEra::::set(Some(6)); + set_active_era(6); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(20), 20, 0)); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(21), 21, 0)); @@ -503,7 +503,7 @@ fn pool_slash_e2e() { ] ); - CurrentEra::::set(Some(9)); + set_active_era(9); assert_eq!( PoolMembers::::get(10).unwrap(), PoolMember { @@ -539,7 +539,7 @@ fn pool_slash_proportional() { ExistentialDeposit::set(2); BondingDuration::set(28); assert_eq!(Balances::minimum_balance(), 2); - assert_eq!(Staking::current_era(), None); + assert_eq!(Staking::active_era().unwrap().index, 0); // create the pool, we know this has id 1. assert_ok!(Pools::create(RuntimeOrigin::signed(10), 40, 10, 10, 10)); @@ -609,7 +609,7 @@ fn pool_slash_proportional() { ); // now let's progress a lot. - CurrentEra::::set(Some(99)); + set_active_era(99); // and unbond assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, bond)); @@ -629,7 +629,7 @@ fn pool_slash_proportional() { }] ); - CurrentEra::::set(Some(100)); + set_active_era(100); assert_ok!(Pools::unbond(RuntimeOrigin::signed(21), 21, bond)); assert_eq!( staking_events_since_last_call(), @@ -646,7 +646,7 @@ fn pool_slash_proportional() { }] ); - CurrentEra::::set(Some(101)); + set_active_era(101); assert_ok!(Pools::unbond(RuntimeOrigin::signed(22), 22, bond)); assert_eq!( staking_events_since_last_call(), @@ -753,7 +753,7 @@ fn pool_slash_proportional() { assert_eq!(Balances::total_balance_on_hold(&22), bond); // they try to withdraw. This should slash them. - CurrentEra::::set(Some(129)); + set_active_era(129); let pre_balance = Balances::free_balance(&22); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(22), 22, 0)); // all balance should be released. @@ -785,7 +785,7 @@ fn pool_slash_non_proportional_only_bonded_pool() { ExistentialDeposit::set(1); BondingDuration::set(28); assert_eq!(Balances::minimum_balance(), 1); - assert_eq!(CurrentEra::::get(), None); + assert_eq!(CurrentEra::::get(), Some(0)); // create the pool, we know this has id 1. assert_ok!(Pools::create(RuntimeOrigin::signed(10), 40, 10, 10, 10)); @@ -814,7 +814,7 @@ fn pool_slash_non_proportional_only_bonded_pool() { ); // progress and unbond. - CurrentEra::::set(Some(99)); + set_active_era(99); assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, bond)); assert_eq!( staking_events_since_last_call(), @@ -832,7 +832,7 @@ fn pool_slash_non_proportional_only_bonded_pool() { ); // slash for 30. This will be deducted only from the bonded pool. - CurrentEra::::set(Some(100)); + set_active_era(100); assert_eq!(BondedPools::::get(1).unwrap().points, 40); pallet_staking::slashing::do_slash::( &POOL1_BONDED, @@ -864,7 +864,7 @@ fn pool_slash_non_proportional_bonded_pool_and_chunks() { ExistentialDeposit::set(1); BondingDuration::set(28); assert_eq!(Balances::minimum_balance(), 1); - assert_eq!(CurrentEra::::get(), None); + assert_eq!(CurrentEra::::get(), Some(0)); // create the pool, we know this has id 1. assert_ok!(Pools::create(RuntimeOrigin::signed(10), 40, 10, 10, 10)); @@ -893,7 +893,7 @@ fn pool_slash_non_proportional_bonded_pool_and_chunks() { ); // progress and unbond. - CurrentEra::::set(Some(99)); + set_active_era(99); assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, bond)); assert_eq!( staking_events_since_last_call(), @@ -911,7 +911,7 @@ fn pool_slash_non_proportional_bonded_pool_and_chunks() { ); // slash 50. This will be deducted only from the bonded pool and one of the unbonding pools. - CurrentEra::::set(Some(100)); + set_active_era(100); assert_eq!(BondedPools::::get(1).unwrap().points, 40); pallet_staking::slashing::do_slash::( &POOL1_BONDED, @@ -941,7 +941,7 @@ fn pool_slash_non_proportional_bonded_pool_and_chunks() { fn pool_migration_e2e() { new_test_ext().execute_with(|| { LegacyAdapter::set(true); - assert_eq!(CurrentEra::::get(), None); + assert_eq!(CurrentEra::::get(), Some(0)); // hack: mint ED to pool so that the deprecated `TransferStake` works correctly with // staking. @@ -998,11 +998,11 @@ fn pool_migration_e2e() { ] ); - CurrentEra::::set(Some(2)); + set_active_era(2); // 20 is partially unbonding assert_ok!(Pools::unbond(RuntimeOrigin::signed(20), 20, 5)); - CurrentEra::::set(Some(3)); + set_active_era(3); // 21 is fully unbonding assert_ok!(Pools::unbond(RuntimeOrigin::signed(21), 21, 10)); @@ -1063,7 +1063,7 @@ fn pool_migration_e2e() { ); // move to era 5 when 20 can withdraw unbonded funds. - CurrentEra::::set(Some(5)); + set_active_era(5); // Cannot unbond without claiming delegation. Lets unbond 22. assert_noop!( @@ -1134,7 +1134,7 @@ fn pool_migration_e2e() { ); // go to era when 21 can unbond - CurrentEra::::set(Some(6)); + set_active_era(6); // withdraw works now assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(21), 21, 10)); @@ -1173,7 +1173,7 @@ fn pool_migration_e2e() { ); // go to era when 22 can unbond - CurrentEra::::set(Some(9)); + set_active_era(9); // withdraw works now assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(22), 22, 10)); @@ -1226,7 +1226,7 @@ fn disable_pool_operations_on_non_migrated() { new_test_ext().execute_with(|| { LegacyAdapter::set(true); assert_eq!(Balances::minimum_balance(), 5); - assert_eq!(CurrentEra::::get(), None); + assert_eq!(CurrentEra::::get(), Some(0)); // hack: mint ED to pool so that the deprecated `TransferStake` works correctly with // staking. @@ -1410,7 +1410,7 @@ fn pool_no_dangling_delegation() { new_test_ext().execute_with(|| { ExistentialDeposit::set(1); assert_eq!(Balances::minimum_balance(), 1); - assert_eq!(CurrentEra::::get(), None); + assert_eq!(CurrentEra::::get(), Some(0)); // pool creator let alice = 10; let bob = 20; @@ -1481,7 +1481,7 @@ fn pool_no_dangling_delegation() { ); // now let's progress a bit. - CurrentEra::::set(Some(1)); + set_active_era(1); // bob is completely unbonding assert_ok!(Pools::unbond(RuntimeOrigin::signed(bob), 20, 20)); @@ -1496,7 +1496,7 @@ fn pool_no_dangling_delegation() { ); // this era will get slashed - CurrentEra::::set(Some(2)); + set_active_era(2); assert_ok!(Pools::unbond(RuntimeOrigin::signed(alice), 10, 10)); assert_ok!(Pools::unbond(RuntimeOrigin::signed(charlie), 21, 10)); @@ -1583,7 +1583,7 @@ fn pool_no_dangling_delegation() { ); // go forward to an era after PostUnbondingPoolsWindow = 10 ends for era 5. - CurrentEra::::set(Some(15)); + set_active_era(15); // At this point subpools will all be merged in no-era causing Bob to lose some value while // Alice and Charlie will gain some value. assert_ok!(Pools::unbond(RuntimeOrigin::signed(charlie), charlie, 10)); @@ -1643,7 +1643,7 @@ fn pool_no_dangling_delegation() { ); // Charlie can withdraw as much as he has locked. - CurrentEra::::set(Some(18)); + set_active_era(18); let charlie_pre_withdraw_balance = Balances::free_balance(&charlie); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(charlie), charlie, 0)); // Charlie's total balance was 12, but we don't have enough funds to unlock. We try the best @@ -1693,7 +1693,7 @@ fn pool_no_dangling_delegation() { ] ); - CurrentEra::::set(Some(21)); + set_active_era(21); assert_ok!(Pools::withdraw_unbonded(RuntimeOrigin::signed(alice), alice, 0)); assert_eq!( diff --git a/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs b/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs index ab49403b2e08e..ee3acb5b5a412 100644 --- a/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs +++ b/substrate/frame/nomination-pools/test-delegate-stake/src/mock.rs @@ -339,6 +339,9 @@ pub fn new_test_ext() -> sp_io::TestExternalities { pallet_staking::ConfigOp::Noop, pallet_staking::ConfigOp::Noop, )); + + // ensure staking era is initialised. + set_active_era(0); }); ext @@ -386,3 +389,11 @@ pub(crate) fn delegated_staking_events_since_last_call( ObservedEventsDelegatedStaking::set(events.len()); events.into_iter().skip(already_seen).collect() } + +pub fn set_active_era(era: sp_staking::EraIndex) { + pallet_staking::CurrentEra::::put(era); + pallet_staking::ActiveEra::::put(pallet_staking::ActiveEraInfo { + index: era, + start: Some(0), + }); +} diff --git a/substrate/frame/staking-async/ahm-test/src/ah/mock.rs b/substrate/frame/staking-async/ahm-test/src/ah/mock.rs index 7e86524a058b6..af8d58e658b9d 100644 --- a/substrate/frame/staking-async/ahm-test/src/ah/mock.rs +++ b/substrate/frame/staking-async/ahm-test/src/ah/mock.rs @@ -87,10 +87,7 @@ pub fn roll_until_matches(criteria: impl Fn() -> bool, with_rc: bool) { /// Use the given `end_index` as the first session report, and increment as per needed. pub(crate) fn roll_until_next_active(mut end_index: SessionIndex) -> Vec { // receive enough session reports, such that we plan a new era - let planned_era = pallet_staking_async::session_rotation::Rotator::::planned_era(); - let active_era = pallet_staking_async::session_rotation::Rotator::::active_era(); - - while pallet_staking_async::session_rotation::Rotator::::planned_era() == planned_era { + while pallet_staking_async::session_rotation::Rotator::::is_planning().is_none() { let report = SessionReport { end_index, activation_timestamp: None, @@ -105,6 +102,11 @@ pub(crate) fn roll_until_next_active(mut end_index: SessionIndex) -> Vec::is_planning() + .expect("new era must be planned since we exited the loop"); + let active_era = pallet_staking_async::session_rotation::Rotator::::active_era(); + assert_eq!(planned_era, active_era + 1); + // now we have planned a new session. Roll until we have an outgoing message ready, meaning the // election is done LocalQueue::flush(); @@ -121,7 +123,7 @@ pub(crate) fn roll_until_next_active(mut end_index: SessionIndex) -> Vec Vec( // Start a new Era let new_validators = Rotator::::legacy_insta_plan_era(); - let planned_era = CurrentEra::::get().unwrap_or_default(); + let planned_era = Rotator::::is_planning().expect("Planning should be in progress"); assert_eq!(new_validators.len(), 1, "New validators is not 1"); assert_eq!(new_validators[0], v_stash, "Our validator was not selected"); @@ -311,7 +311,7 @@ mod benchmarks { let (_, controller) = create_stash_controller::(0, 100, RewardDestination::Staked)?; let amount = asset::existential_deposit::() * 5u32.into(); // Half of total Staking::::unbond(RawOrigin::Signed(controller.clone()).into(), amount)?; - set_active_era::(EraIndex::max_value()); + Staking::::set_active_era(EraIndex::max_value(), Some(0)); let ledger = Ledger::::get(&controller).ok_or("ledger not created before")?; let original_total: BalanceOf = ledger.total; whitelist_account!(controller); @@ -345,7 +345,7 @@ mod benchmarks { let mut ledger = Ledger::::get(&controller).unwrap(); ledger.active = ed - One::one(); Ledger::::insert(&controller, ledger); - set_active_era::(EraIndex::max_value()); + Staking::::set_active_era(EraIndex::max_value(), Some(0)); whitelist_account!(controller); @@ -728,6 +728,9 @@ mod benchmarks { nominator_balances_before.push(balance); } + // activate the current era. + Staking::::activate_next_era(1, 1); + #[extrinsic_call] payout_stakers(RawOrigin::Signed(caller), validator.clone(), current_era); @@ -1042,14 +1045,16 @@ mod benchmarks { let _new_validators = Rotator::::legacy_insta_plan_era(); // activate the previous one Rotator::::start_era( - crate::ActiveEraInfo { index: Rotator::::planned_era() - 1, start: Some(1) }, + crate::ActiveEraInfo { + index: Rotator::::is_planning().expect("era must be planned") - 1, + start: Some(1), + }, 42, // start session index doesn't really matter, 2, // timestamp doesn't really matter ); // ensure our offender has at least a full exposure page - let offender_exposure = - Eras::::get_full_exposure(Rotator::::planned_era(), &offender); + let offender_exposure = Eras::::get_full_exposure(Rotator::::active_era(), &offender); ensure!( offender_exposure.others.len() as u32 == 2 * T::MaxExposurePageSize::get(), "exposure not created" @@ -1091,7 +1096,7 @@ mod benchmarks { fn rc_on_offence( v: Linear<2, { T::MaxValidatorSet::get() / 2 }>, ) -> Result<(), BenchmarkError> { - let initial_era = Rotator::::planned_era(); + let initial_era = Rotator::::active_era(); let _ = crate::testing_utils::create_validators_with_nominators_for_era::( 2 * v, // number of nominators is irrelevant here, so we hardcode these @@ -1103,7 +1108,7 @@ mod benchmarks { // plan new era let new_validators = Rotator::::legacy_insta_plan_era(); - ensure!(Rotator::::planned_era() == initial_era + 1, "era should be incremented"); + ensure!(Rotator::::is_planning().is_some(), "era should be planned"); // activate the previous one Rotator::::start_era( crate::ActiveEraInfo { index: initial_era, start: Some(1) }, @@ -1153,7 +1158,6 @@ mod benchmarks { #[benchmark] fn rc_on_session_report() -> Result<(), BenchmarkError> { - let initial_planned_era = Rotator::::planned_era(); let initial_active_era = Rotator::::active_era(); // create a small, arbitrary number of stakers. This is just for sanity of the era planning, @@ -1164,16 +1168,13 @@ mod benchmarks { // plan new era let _new_validators = Rotator::::legacy_insta_plan_era(); - ensure!( - CurrentEra::::get().unwrap() == initial_planned_era + 1, - "era should be incremented" - ); + let planning_era = Rotator::::is_planning().expect("era should be planned"); // receive a session report with timestamp that actives the previous one. let validator_points = (0..T::MaxValidatorSet::get()) .map(|v| (account::("random", v, SEED), v)) .collect::>(); - let activation_timestamp = Some((1u64, initial_planned_era + 1)); + let activation_timestamp = Some((1u64, planning_era)); let report = rc_client::SessionReport { end_index: 42, leftover: false, @@ -1495,6 +1496,9 @@ mod tests { assert_eq!(nominators.len() as u32, n); + // activate the current era. + Staking::activate_next_era(1, 1); + let original_stakeable_balance = asset::stakeable_balance::(&validator_stash); assert_ok!(Staking::payout_stakers_by_page( RuntimeOrigin::signed(1337), diff --git a/substrate/frame/staking-async/src/pallet/impls.rs b/substrate/frame/staking-async/src/pallet/impls.rs index e5c594f6998da..d0297b6d57338 100644 --- a/substrate/frame/staking-async/src/pallet/impls.rs +++ b/substrate/frame/staking-async/src/pallet/impls.rs @@ -331,15 +331,11 @@ impl Pallet { page: Page, ) -> DispatchResultWithPostInfo { // Validate input data - let current_era = CurrentEra::::get().ok_or_else(|| { - Error::::InvalidEraToReward - .with_weight(T::WeightInfo::payout_stakers_alive_staked(0)) - })?; - + let active_era = Rotator::::active_era(); let history_depth = T::HistoryDepth::get(); ensure!( - era <= current_era && era >= current_era.saturating_sub(history_depth), + era <= active_era && era >= active_era.saturating_sub(history_depth), Error::::InvalidEraToReward .with_weight(T::WeightInfo::payout_stakers_alive_staked(0)) ); @@ -1560,8 +1556,8 @@ impl StakingInterface for Pallet { T::BondingDuration::get() } - fn current_era() -> EraIndex { - CurrentEra::::get().unwrap_or(Zero::zero()) + fn active_era() -> EraIndex { + Rotator::::active_era() } fn stake(who: &Self::AccountId) -> Result>, DispatchError> { @@ -1706,8 +1702,18 @@ impl StakingInterface for Pallet { Eras::::upsert_exposure(*current_era, stash, exposure); } - fn set_current_era(era: EraIndex) { + fn set_active_era(era: EraIndex, start: Option) { CurrentEra::::put(era); + ActiveEra::::put(crate::ActiveEraInfo { index: era, start }); + } + + fn activate_next_era(era_duration_in_session: SessionIndex, era_duration_in_millis: u64) { + let planning_era = Rotator::::is_planning().expect("No planning era found"); + let last_activation_timestamp = ActiveEra::::get() + .and_then(|a| a.start) + .unwrap_or(0); + + Rotator::::end_session(Rotator::::active_era_start_session_index() + era_duration_in_session, Some((last_activation_timestamp + era_duration_in_millis, planning_era))); } fn max_exposure_page_size() -> Page { diff --git a/substrate/frame/staking-async/src/pallet/mod.rs b/substrate/frame/staking-async/src/pallet/mod.rs index 11174e7f26ade..ed65581b4099d 100644 --- a/substrate/frame/staking-async/src/pallet/mod.rs +++ b/substrate/frame/staking-async/src/pallet/mod.rs @@ -18,10 +18,11 @@ //! `pallet-staking-async`'s main `pallet` module. use crate::{ - asset, slashing, weights::WeightInfo, AccountIdLookupOf, ActiveEraInfo, BalanceOf, EraPayout, - EraRewardPoints, ExposurePage, Forcing, LedgerIntegrityState, MaxNominationsOf, - NegativeImbalanceOf, Nominations, NominationsQuota, PositiveImbalanceOf, RewardDestination, - StakingLedger, UnappliedSlash, UnlockChunk, ValidatorPrefs, + asset, session_rotation::Rotator, slashing, weights::WeightInfo, AccountIdLookupOf, + ActiveEraInfo, BalanceOf, EraPayout, EraRewardPoints, ExposurePage, Forcing, + LedgerIntegrityState, MaxNominationsOf, NegativeImbalanceOf, Nominations, NominationsQuota, + PositiveImbalanceOf, RewardDestination, StakingLedger, UnappliedSlash, UnlockChunk, + ValidatorPrefs, }; use alloc::{format, vec::Vec}; use codec::Codec; @@ -521,6 +522,8 @@ pub mod pallet { /// /// This is the latest planned era, depending on how the Session pallet queues the validator /// set, it might be active or not. + /// + /// Managed via the [`session_rotation::Rotator`]. #[pallet::storage] pub type CurrentEra = StorageValue<_, EraIndex>; @@ -528,6 +531,8 @@ pub mod pallet { /// /// The active era is the era being currently rewarded. Validator set of this era must be /// equal to what is RC's session pallet. + /// + /// Managed via the [`session_rotation::Rotator`]. #[pallet::storage] pub type ActiveEra = StorageValue<_, ActiveEraInfo>; @@ -912,6 +917,10 @@ pub mod pallet { self.invulnerables.len() as u32 <= T::MaxInvulnerables::get(), "Too many invulnerable validators at genesis." ); + let (active_era, session_index, timestamp) = self.active_era; + ActiveEra::::put(ActiveEraInfo { index: active_era, start: Some(timestamp) }); + // at genesis, we do not have any new planned era. + CurrentEra::::put(active_era); >::put(&self.invulnerables); ForceEra::::put(self.force_era); @@ -1053,10 +1062,6 @@ pub mod pallet { }) } - let (active_era, session_index, timestamp) = self.active_era; - ActiveEra::::put(ActiveEraInfo { index: active_era, start: Some(timestamp) }); - // at genesis, we do not have any new planned era. - CurrentEra::::put(active_era); // set the bonded genesis era BondedEras::::put( BoundedVec::<_, BondedErasBound>::try_from( @@ -1621,11 +1626,8 @@ pub mod pallet { // If a user runs into this error, they should chill first. ensure!(ledger.active >= min_active_bond, Error::::InsufficientBond); - // Note: we used current era before, but that is meant to be used for only election. - // The right value to use here is the active era. - - let era = session_rotation::Rotator::::active_era() - .saturating_add(T::BondingDuration::get()); + let era = + Rotator::::active_era().defensive_saturating_add(T::BondingDuration::get()); if let Some(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 @@ -1791,7 +1793,7 @@ pub mod pallet { let nominations = Nominations { targets, // Initial nominations are considered submitted at era 0. See `Nominations` doc. - submitted_in: CurrentEra::::get().unwrap_or(0), + submitted_in: Rotator::::active_era(), suppressed: false, }; diff --git a/substrate/frame/staking-async/src/session_rotation.rs b/substrate/frame/staking-async/src/session_rotation.rs index ff0b1e12d52af..cef5a8541fb10 100644 --- a/substrate/frame/staking-async/src/session_rotation.rs +++ b/substrate/frame/staking-async/src/session_rotation.rs @@ -577,7 +577,7 @@ impl Rotator { /// this value, it means that the era is currently active and no new era is planned. /// /// See [`Self::is_planning()`] to only get the next index if planning in progress. - pub fn planned_era() -> EraIndex { + fn planned_era() -> EraIndex { CurrentEra::::get().unwrap_or(0) } @@ -696,7 +696,7 @@ impl Rotator { new_era_start_timestamp: u64, ) { // verify that a new era was planned - debug_assert!(CurrentEra::::get().unwrap_or(0) == ending_era.index + 1); + debug_assert!(Self::is_planning().is_some(), "new era must be planned"); let starting_era = ending_era.index + 1; @@ -912,8 +912,7 @@ impl EraElectionPlanner { ); debug_assert!( - CurrentEra::::get().unwrap_or(0) == - ActiveEra::::get().map_or(0, |a| a.index) + 1, + Rotator::::is_planning().is_some(), "Next era must be already planned." ); @@ -929,7 +928,7 @@ impl EraElectionPlanner { // we can report it now. if maybe_next_page.is_none() { use pallet_staking_async_rc_client::RcClientInterface; - let id = CurrentEra::::get().defensive_unwrap_or(0); + let id = Rotator::::is_planning().defensive_unwrap_or(0); let prune_up_to = Self::get_prune_up_to(); let rc_validators = ElectableStashes::::take().into_iter().collect::>(); diff --git a/substrate/frame/staking-async/src/testing_utils.rs b/substrate/frame/staking-async/src/testing_utils.rs index 3028b3a4e55aa..d00e1e945c67c 100644 --- a/substrate/frame/staking-async/src/testing_utils.rs +++ b/substrate/frame/staking-async/src/testing_utils.rs @@ -237,11 +237,6 @@ pub fn create_validators_with_nominators_for_era( Ok(validator_chosen) } -/// get the current era. -pub fn current_era() -> EraIndex { - CurrentEra::::get().unwrap_or(0) -} - pub fn migrate_to_old_currency(who: T::AccountId) { use frame_support::traits::LockableCurrency; let staked = asset::staked::(&who); @@ -259,11 +254,3 @@ pub fn migrate_to_old_currency(who: T::AccountId) { // replicate old behaviour of explicit increment of consumer. frame_system::Pallet::::inc_consumers(&who).expect("increment consumer failed"); } - -/// Set active era to the given era index. -pub fn set_active_era(era: EraIndex) { - // set the current era. - CurrentEra::::put(era); - // set the active era. - ActiveEra::::put(ActiveEraInfo { index: era, start: None }); -} diff --git a/substrate/frame/staking-async/src/tests/era_rotation.rs b/substrate/frame/staking-async/src/tests/era_rotation.rs index 91cac42f35bf9..2d67171c45d5c 100644 --- a/substrate/frame/staking-async/src/tests/era_rotation.rs +++ b/substrate/frame/staking-async/src/tests/era_rotation.rs @@ -192,7 +192,7 @@ fn activation_timestamp_when_no_planned_era() { // GIVEN: no new planned era assert_eq!(Rotator::::active_era(), 2); - assert_eq!(Rotator::::planned_era(), 2); + assert!(Rotator::::is_planning().is_none()); // WHEN: send a new activation timestamp (manually). ::on_relay_session_report( diff --git a/substrate/frame/staking/src/pallet/impls.rs b/substrate/frame/staking/src/pallet/impls.rs index 6b8e65049cc7f..393667fcc94d6 100644 --- a/substrate/frame/staking/src/pallet/impls.rs +++ b/substrate/frame/staking/src/pallet/impls.rs @@ -1990,8 +1990,8 @@ impl StakingInterface for Pallet { T::BondingDuration::get() } - fn current_era() -> EraIndex { - CurrentEra::::get().unwrap_or(Zero::zero()) + fn active_era() -> EraIndex { + ActiveEra::::get().map(|a| a.index).defensive_unwrap_or(0) } fn stake(who: &Self::AccountId) -> Result>, DispatchError> { @@ -2144,8 +2144,13 @@ impl StakingInterface for Pallet { EraInfo::::set_exposure(*current_era, stash, exposure); } - fn set_current_era(era: EraIndex) { + fn set_active_era(era: EraIndex, start: Option) { CurrentEra::::put(era); + ActiveEra::::put(crate::ActiveEraInfo { index: era, start }); + } + + fn activate_next_era(_era_duration_in_session: SessionIndex, _era_duration_in_millis: u64) { + unimplemented!(); } fn max_exposure_page_size() -> Page { diff --git a/substrate/primitives/staking/src/lib.rs b/substrate/primitives/staking/src/lib.rs index 863e6cbe2b20f..e98c76c567feb 100644 --- a/substrate/primitives/staking/src/lib.rs +++ b/substrate/primitives/staking/src/lib.rs @@ -200,10 +200,8 @@ pub trait StakingInterface { /// Number of eras that staked funds must remain bonded for. fn bonding_duration() -> EraIndex; - /// The current era index. - /// - /// This should be the latest planned era that the staking system knows about. - fn current_era() -> EraIndex; + /// The ongoing era index in the staking system. + fn active_era() -> EraIndex; /// Returns the [`Stake`] of `who`. fn stake(who: &Self::AccountId) -> Result, DispatchError>; @@ -244,7 +242,7 @@ pub trait StakingInterface { fn bond_extra(who: &Self::AccountId, extra: Self::Balance) -> DispatchResult; /// Schedule a portion of the active bonded balance to be unlocked at era - /// [Self::current_era] + [`Self::bonding_duration`]. + /// [Self::active_era] + [`Self::bonding_duration`]. /// /// Once the unlock era has been reached, [`Self::withdraw_unbonded`] can be called to unlock /// the funds. @@ -313,8 +311,18 @@ pub trait StakingInterface { exposures: Vec<(Self::AccountId, Self::Balance)>, ); + /// Unsafe sets the current and active era index in the staking system. + /// + /// Note: This may break some invariance. Only to be used in tests where era transition can be + /// unsafe. Use [`Self::activate_next_era`] when possible. + #[cfg(feature = "runtime-benchmarks")] + fn set_active_era(era: EraIndex, start: Option); + + /// Activates the next era by ending the active era and starting a new one. + /// + /// An era must be planned. #[cfg(feature = "runtime-benchmarks")] - fn set_current_era(era: EraIndex); + fn activate_next_era(era_duration_in_session: SessionIndex, era_duration_in_millis: u64); } /// Set of low level apis to manipulate staking ledger.