Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit bb94ac7

Browse files
authored
Staking: store last min-active-bond on-chain (#12889)
* Staking: store last min-active-bond on-chain Storing the `min-active-bond` onchain helps the UIs with minimal on-chain costs. Closes #12746 * Avoid relying on sorting to set the * Addresses PR comments
1 parent 2f6105b commit bb94ac7

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

frame/staking/src/pallet/impls.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,9 @@ impl<T: Config> Pallet<T> {
704704
///
705705
/// `maybe_max_len` can imposes a cap on the number of voters returned;
706706
///
707+
/// Sets `MinimumActiveStake` to the minimum active nominator stake in the returned set of
708+
/// nominators.
709+
///
707710
/// This function is self-weighing as [`DispatchClass::Mandatory`].
708711
pub fn get_npos_voters(maybe_max_len: Option<usize>) -> Vec<VoterOf<Self>> {
709712
let max_allowed_len = {
@@ -719,6 +722,7 @@ impl<T: Config> Pallet<T> {
719722
let mut voters_seen = 0u32;
720723
let mut validators_taken = 0u32;
721724
let mut nominators_taken = 0u32;
725+
let mut min_active_stake = u64::MAX;
722726

723727
let mut sorted_voters = T::VoterList::iter();
724728
while all_voters.len() < max_allowed_len &&
@@ -733,12 +737,15 @@ impl<T: Config> Pallet<T> {
733737
};
734738

735739
if let Some(Nominations { targets, .. }) = <Nominators<T>>::get(&voter) {
740+
let voter_weight = weight_of(&voter);
736741
if !targets.is_empty() {
737-
all_voters.push((voter.clone(), weight_of(&voter), targets));
742+
all_voters.push((voter.clone(), voter_weight, targets));
738743
nominators_taken.saturating_inc();
739744
} else {
740745
// Technically should never happen, but not much we can do about it.
741746
}
747+
min_active_stake =
748+
if voter_weight < min_active_stake { voter_weight } else { min_active_stake };
742749
} else if Validators::<T>::contains_key(&voter) {
743750
// if this voter is a validator:
744751
let self_vote = (
@@ -769,6 +776,11 @@ impl<T: Config> Pallet<T> {
769776

770777
Self::register_weight(T::WeightInfo::get_npos_voters(validators_taken, nominators_taken));
771778

779+
let min_active_stake: T::CurrencyBalance =
780+
if all_voters.len() == 0 { 0u64.into() } else { min_active_stake.into() };
781+
782+
MinimumActiveStake::<T>::put(min_active_stake);
783+
772784
log!(
773785
info,
774786
"generated {} npos voters, {} from validators and {} nominators",

frame/staking/src/pallet/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,10 @@ pub mod pallet {
295295
#[pallet::storage]
296296
pub type MinValidatorBond<T: Config> = StorageValue<_, BalanceOf<T>, ValueQuery>;
297297

298+
/// The minimum active nominator stake of the last successful election.
299+
#[pallet::storage]
300+
pub type MinimumActiveStake<T> = StorageValue<_, BalanceOf<T>, ValueQuery>;
301+
298302
/// The minimum amount of commission that validators can set.
299303
///
300304
/// If set to `0`, no limit exists.

frame/staking/src/tests.rs

+26
Original file line numberDiff line numberDiff line change
@@ -4463,6 +4463,32 @@ mod election_data_provider {
44634463
);
44644464
}
44654465

4466+
#[test]
4467+
fn set_minimum_active_stake_is_correct() {
4468+
ExtBuilder::default()
4469+
.nominate(false)
4470+
.add_staker(61, 60, 2_000, StakerStatus::<AccountId>::Nominator(vec![21]))
4471+
.add_staker(71, 70, 10, StakerStatus::<AccountId>::Nominator(vec![21]))
4472+
.add_staker(81, 80, 50, StakerStatus::<AccountId>::Nominator(vec![21]))
4473+
.build_and_execute(|| {
4474+
assert_ok!(<Staking as ElectionDataProvider>::electing_voters(None));
4475+
assert_eq!(MinimumActiveStake::<Test>::get(), 10);
4476+
4477+
// remove staker with lower bond by limiting the number of voters and check
4478+
// `MinimumActiveStake` again after electing voters.
4479+
assert_ok!(<Staking as ElectionDataProvider>::electing_voters(Some(5)));
4480+
assert_eq!(MinimumActiveStake::<Test>::get(), 50);
4481+
});
4482+
}
4483+
4484+
#[test]
4485+
fn set_minimum_active_stake_zero_correct() {
4486+
ExtBuilder::default().has_stakers(false).build_and_execute(|| {
4487+
assert_ok!(<Staking as ElectionDataProvider>::electing_voters(None));
4488+
assert_eq!(MinimumActiveStake::<Test>::get(), 0);
4489+
});
4490+
}
4491+
44664492
#[test]
44674493
fn voters_include_self_vote() {
44684494
ExtBuilder::default().nominate(false).build_and_execute(|| {

0 commit comments

Comments
 (0)