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

Store validator self-vote in bags-list, and allow them to be trimmed for election #10821

Merged
merged 22 commits into from
Mar 23, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frame/babe/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ impl pallet_staking::Config for Test {
type NextNewSession = Session;
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
type GenesisElectionProvider = Self::ElectionProvider;
type SortedListProvider = pallet_staking::UseNominatorsMap<Self>;
type SortedListProvider = pallet_staking::UseNominatorsAndValidatorsMap<Self>;
type MaxUnlockingChunks = ConstU32<32>;
type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig;
type WeightInfo = ();
Expand Down
2 changes: 1 addition & 1 deletion frame/grandpa/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ impl pallet_staking::Config for Test {
type NextNewSession = Session;
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
type GenesisElectionProvider = Self::ElectionProvider;
type SortedListProvider = pallet_staking::UseNominatorsMap<Self>;
type SortedListProvider = pallet_staking::UseNominatorsAndValidatorsMap<Self>;
type MaxUnlockingChunks = ConstU32<32>;
type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig;
type WeightInfo = ();
Expand Down
2 changes: 1 addition & 1 deletion frame/offences/benchmarking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ impl pallet_staking::Config for Test {
type OffendingValidatorsThreshold = ();
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
type GenesisElectionProvider = Self::ElectionProvider;
type SortedListProvider = pallet_staking::UseNominatorsMap<Self>;
type SortedListProvider = pallet_staking::UseNominatorsAndValidatorsMap<Self>;
type MaxUnlockingChunks = ConstU32<32>;
type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig;
type WeightInfo = ();
Expand Down
2 changes: 1 addition & 1 deletion frame/session/benchmarking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ impl pallet_staking::Config for Test {
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
type GenesisElectionProvider = Self::ElectionProvider;
type MaxUnlockingChunks = ConstU32<32>;
type SortedListProvider = pallet_staking::UseNominatorsMap<Self>;
type SortedListProvider = pallet_staking::UseNominatorsAndValidatorsMap<Self>;
type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig;
type WeightInfo = ();
}
Expand Down
20 changes: 8 additions & 12 deletions frame/staking/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,24 +332,20 @@ benchmarks! {
}

validate {
// clean up any existing state.
clear_validators_and_nominators::<T>();

let origin_weight = MinNominatorBond::<T>::get().max(T::Currency::minimum_balance());

// setup a worst case scenario where the user calling validate was formerly a nominator so
// they must be removed from the list.
let scenario = ListScenario::<T>::new(origin_weight, true)?;
let controller = scenario.origin_controller1.clone();
let stash = scenario.origin_stash1.clone();
assert!(T::SortedListProvider::contains(&stash));
let (stash, controller) = create_stash_controller::<T>(
T::MaxNominations::get() - 1,
100,
Default::default(),
)?;
// because it is chilled.
assert!(!T::SortedListProvider::contains(&stash));

let prefs = ValidatorPrefs::default();
whitelist_account!(controller);
}: _(RawOrigin::Signed(controller), prefs)
verify {
assert!(Validators::<T>::contains_key(&stash));
assert!(!T::SortedListProvider::contains(&stash));
assert!(T::SortedListProvider::contains(&stash));
}

kick {
Expand Down
7 changes: 4 additions & 3 deletions frame/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ mod pallet;
use codec::{Decode, Encode, HasCompact};
use frame_support::{
parameter_types,
traits::{ConstU32, Currency, Get},
traits::{Currency, Get},
weights::Weight,
BoundedVec, EqNoBound, PartialEqNoBound, RuntimeDebugNoBound,
};
Expand Down Expand Up @@ -781,6 +781,7 @@ enum Releases {
V6_0_0, // removal of all storage associated with offchain phragmen.
V7_0_0, // keep track of number of nominators / validators in map
V8_0_0, // populate `SortedListProvider`.
V9_0_0, // inject validators into `SortedListProvider` as well.
}

impl Default for Releases {
Expand Down Expand Up @@ -861,6 +862,6 @@ pub struct TestBenchmarkingConfig;

#[cfg(feature = "std")]
impl BenchmarkingConfig for TestBenchmarkingConfig {
type MaxValidators = ConstU32<100>;
type MaxNominators = ConstU32<100>;
type MaxValidators = frame_support::traits::ConstU32<100>;
type MaxNominators = frame_support::traits::ConstU32<100>;
}
47 changes: 47 additions & 0 deletions frame/staking/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,53 @@
//! Storage migrations for the Staking pallet.

use super::*;
use frame_election_provider_support::{SortedListProvider, VoteWeightProvider};
use frame_support::traits::OnRuntimeUpgrade;

/// Migration implementation that injects all validators into sorted list.
///
/// This is only useful for chains that started their `SortedListProvider` just based on nominators.
pub struct InjectValidatorsIntoSortedListProvider<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> OnRuntimeUpgrade for InjectValidatorsIntoSortedListProvider<T> {
fn on_runtime_upgrade() -> Weight {
if StorageVersion::<T>::get() == Releases::V8_0_0 {
for (v, _) in Validators::<T>::iter() {
let weight = Pallet::<T>::vote_weight(&v);
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
let _ = T::SortedListProvider::on_insert(v.clone(), weight).map_err(|err| {
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
log!(warn, "failed to insert {:?} into SortedListProvider: {:?}", v, err)
});
}

T::BlockWeights::get().max_block
} else {
log!(warn, "InjectValidatorsIntoSortedListProvider being executed on the wrong storage version, expected Releases::V8_0_0");
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
T::DbWeight::get().reads(1)
}
}

#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<(), &'static str> {
use frame_support::traits::OnRuntimeUpgradeHelpersExt;
frame_support::ensure!(
StorageVersion::<T>::get() == crate::Releases::V8_0_0,
"must upgrade linearly"
);

let prev_count = T::SortedListProvider::count();
Self::set_temp_storage(prev_count, "prev");
Ok(())
}

#[cfg(feature = "try-runtime")]
fn post_upgrade() -> Result<(), &'static str> {
use frame_support::traits::OnRuntimeUpgradeHelpersExt;
let post_count = T::SortedListProvider::count();
let prev_count = Self::get_temp_storage::<u32>("prev").unwrap();
let validators = Validators::<T>::count();
assert!(post_count == prev_count + validators);
Ok(())
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
}
}

pub mod v8 {
use frame_election_provider_support::SortedListProvider;
Expand Down
4 changes: 2 additions & 2 deletions frame/staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ impl crate::pallet::pallet::Config for Test {
type OffendingValidatorsThreshold = OffendingValidatorsThreshold;
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
type GenesisElectionProvider = Self::ElectionProvider;
// NOTE: consider a macro and use `UseNominatorsMap<Self>` as well.
// NOTE: consider a macro and use `UseNominatorsAndValidatorsMap<Self>` as well.
type SortedListProvider = BagsList;
type MaxUnlockingChunks = ConstU32<32>;
type BenchmarkingConfig = TestBenchmarkingConfig;
Expand Down Expand Up @@ -543,7 +543,7 @@ fn check_count() {

// the voters that the `SortedListProvider` list is storing for us.
let external_voters = <Test as Config>::SortedListProvider::count();
assert_eq!(external_voters, nominator_count);
assert_eq!(external_voters, nominator_count + validator_count);
}

fn check_ledgers() {
Expand Down
Loading