Skip to content

Commit f9ba184

Browse files
kianenigmaemostov
authored andcommitted
Store validator self-vote in bags-list, and allow them to be trimmed for election (paritytech#10821)
* Implement the new validator-in-bags-list scenario + migration * Apply suggestions from code review Co-authored-by: Zeke Mostov <z.mostov@gmail.com> * some review comments * guard the migration * some review comments * Fix tests 🤦‍♂️ * Fix build * fix weight_of_fn * reformat line width * make const * use weight of fn cached * SortedListProvider -> VoterList * Fix all build and docs * check post migration Co-authored-by: Zeke Mostov <z.mostov@gmail.com>
1 parent 1b28405 commit f9ba184

File tree

17 files changed

+305
-204
lines changed

17 files changed

+305
-204
lines changed

bin/node/runtime/src/lib.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -558,9 +558,7 @@ impl pallet_staking::Config for Runtime {
558558
type OffendingValidatorsThreshold = OffendingValidatorsThreshold;
559559
type ElectionProvider = ElectionProviderMultiPhase;
560560
type GenesisElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
561-
// Alternatively, use pallet_staking::UseNominatorsMap<Runtime> to just use the nominators map.
562-
// Note that the aforementioned does not scale to a very large number of nominators.
563-
type SortedListProvider = BagsList;
561+
type VoterList = BagsList;
564562
type MaxUnlockingChunks = ConstU32<32>;
565563
type WeightInfo = pallet_staking::weights::SubstrateWeight<Runtime>;
566564
type BenchmarkingConfig = StakingBenchmarkingConfig;

frame/babe/src/mock.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ impl pallet_staking::Config for Test {
197197
type NextNewSession = Session;
198198
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
199199
type GenesisElectionProvider = Self::ElectionProvider;
200-
type SortedListProvider = pallet_staking::UseNominatorsMap<Self>;
200+
type VoterList = pallet_staking::UseNominatorsAndValidatorsMap<Self>;
201201
type MaxUnlockingChunks = ConstU32<32>;
202202
type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig;
203203
type WeightInfo = ();

frame/bags-list/remote-tests/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub fn display_and_check_bags<Runtime: RuntimeT>(currency_unit: u64, currency_na
4848
let min_nominator_bond = <pallet_staking::MinNominatorBond<Runtime>>::get();
4949
log::info!(target: LOG_TARGET, "min nominator bond is {:?}", min_nominator_bond);
5050

51-
let voter_list_count = <Runtime as pallet_staking::Config>::SortedListProvider::count();
51+
let voter_list_count = <Runtime as pallet_staking::Config>::VoterList::count();
5252

5353
// go through every bag to track the total number of voters within bags and log some info about
5454
// how voters are distributed within the bags.

frame/bags-list/remote-tests/src/migration.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
//! Test to check the migration of the voter bag.
1818
1919
use crate::{RuntimeT, LOG_TARGET};
20-
use frame_election_provider_support::SortedListProvider;
2120
use frame_support::traits::PalletInfoAccess;
2221
use pallet_staking::Nominators;
2322
use remote_externalities::{Builder, Mode, OnlineConfig};
@@ -45,16 +44,16 @@ pub async fn execute<Runtime: RuntimeT, Block: BlockT + DeserializeOwned>(
4544
let pre_migrate_nominator_count = <Nominators<Runtime>>::iter().count() as u32;
4645
log::info!(target: LOG_TARGET, "Nominator count: {}", pre_migrate_nominator_count);
4746

48-
// run the actual migration,
49-
let moved = <Runtime as pallet_staking::Config>::SortedListProvider::unsafe_regenerate(
47+
use frame_election_provider_support::SortedListProvider;
48+
// run the actual migration
49+
let moved = <Runtime as pallet_staking::Config>::VoterList::unsafe_regenerate(
5050
pallet_staking::Nominators::<Runtime>::iter().map(|(n, _)| n),
5151
pallet_staking::Pallet::<Runtime>::weight_of_fn(),
5252
);
5353
log::info!(target: LOG_TARGET, "Moved {} nominators", moved);
5454

55-
let voter_list_len =
56-
<Runtime as pallet_staking::Config>::SortedListProvider::iter().count() as u32;
57-
let voter_list_count = <Runtime as pallet_staking::Config>::SortedListProvider::count();
55+
let voter_list_len = <Runtime as pallet_staking::Config>::VoterList::iter().count() as u32;
56+
let voter_list_count = <Runtime as pallet_staking::Config>::VoterList::count();
5857
// and confirm it is equal to the length of the `VoterList`.
5958
assert_eq!(pre_migrate_nominator_count, voter_list_len);
6059
assert_eq!(pre_migrate_nominator_count, voter_list_count);

frame/bags-list/remote-tests/src/snapshot.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
//! Test to execute the snapshot using the voter bag.
1818
19+
use frame_election_provider_support::SortedListProvider;
1920
use frame_support::traits::PalletInfoAccess;
2021
use remote_externalities::{Builder, Mode, OnlineConfig};
2122
use sp_runtime::{traits::Block as BlockT, DeserializeOwned};
@@ -48,11 +49,11 @@ pub async fn execute<Runtime: crate::RuntimeT, Block: BlockT + DeserializeOwned>
4849
.unwrap();
4950

5051
ext.execute_with(|| {
51-
use frame_election_provider_support::{ElectionDataProvider, SortedListProvider};
52+
use frame_election_provider_support::ElectionDataProvider;
5253
log::info!(
5354
target: crate::LOG_TARGET,
5455
"{} nodes in bags list.",
55-
<Runtime as pallet_staking::Config>::SortedListProvider::count(),
56+
<Runtime as pallet_staking::Config>::VoterList::count(),
5657
);
5758

5859
let voters =

frame/grandpa/src/mock.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ impl pallet_staking::Config for Test {
205205
type NextNewSession = Session;
206206
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
207207
type GenesisElectionProvider = Self::ElectionProvider;
208-
type SortedListProvider = pallet_staking::UseNominatorsMap<Self>;
208+
type VoterList = pallet_staking::UseNominatorsAndValidatorsMap<Self>;
209209
type MaxUnlockingChunks = ConstU32<32>;
210210
type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig;
211211
type WeightInfo = ();

frame/offences/benchmarking/src/mock.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ impl pallet_staking::Config for Test {
175175
type OffendingValidatorsThreshold = ();
176176
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
177177
type GenesisElectionProvider = Self::ElectionProvider;
178-
type SortedListProvider = pallet_staking::UseNominatorsMap<Self>;
178+
type VoterList = pallet_staking::UseNominatorsAndValidatorsMap<Self>;
179179
type MaxUnlockingChunks = ConstU32<32>;
180180
type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig;
181181
type WeightInfo = ();

frame/session/benchmarking/src/mock.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl pallet_staking::Config for Test {
182182
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
183183
type GenesisElectionProvider = Self::ElectionProvider;
184184
type MaxUnlockingChunks = ConstU32<32>;
185-
type SortedListProvider = pallet_staking::UseNominatorsMap<Self>;
185+
type VoterList = pallet_staking::UseNominatorsAndValidatorsMap<Self>;
186186
type BenchmarkingConfig = pallet_staking::TestBenchmarkingConfig;
187187
type WeightInfo = ();
188188
}

frame/session/src/migrations/v1.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub fn migrate<T: pallet_session_historical::Config, P: GetStorageVersion + Pall
8787
}
8888

8989
/// Some checks prior to migration. This can be linked to
90-
/// [`frame_support::traits::OnRuntimeUpgrade::pre_upgrade`] for further testing.
90+
/// `frame_support::traits::OnRuntimeUpgrade::pre_upgrade` for further testing.
9191
///
9292
/// Panics if anything goes wrong.
9393
pub fn pre_migrate<
@@ -123,7 +123,7 @@ pub fn pre_migrate<
123123
}
124124

125125
/// Some checks for after migration. This can be linked to
126-
/// [`frame_support::traits::OnRuntimeUpgrade::post_upgrade`] for further testing.
126+
/// `frame_support::traits::OnRuntimeUpgrade::post_upgrade` for further testing.
127127
///
128128
/// Panics if anything goes wrong.
129129
pub fn post_migrate<

frame/staking/src/benchmarking.rs

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,8 @@ impl<T: Config> ListScenario<T> {
155155
/// - the destination bag has at least one node, which will need its next pointer updated.
156156
///
157157
/// NOTE: while this scenario specifically targets a worst case for the bags-list, it should
158-
/// also elicit a worst case for other known `SortedListProvider` implementations; although
159-
/// this may not be true against unknown `SortedListProvider` implementations.
158+
/// also elicit a worst case for other known `VoterList` implementations; although
159+
/// this may not be true against unknown `VoterList` implementations.
160160
fn new(origin_weight: BalanceOf<T>, is_increase: bool) -> Result<Self, &'static str> {
161161
ensure!(!origin_weight.is_zero(), "origin weight must be greater than 0");
162162

@@ -189,7 +189,7 @@ impl<T: Config> ListScenario<T> {
189189

190190
// find a destination weight that will trigger the worst case scenario
191191
let dest_weight_as_vote =
192-
T::SortedListProvider::score_update_worst_case(&origin_stash1, is_increase);
192+
T::VoterList::score_update_worst_case(&origin_stash1, is_increase);
193193

194194
let total_issuance = T::Currency::total_issuance();
195195

@@ -316,7 +316,7 @@ benchmarks! {
316316
let scenario = ListScenario::<T>::new(origin_weight, true)?;
317317
let controller = scenario.origin_controller1.clone();
318318
let stash = scenario.origin_stash1.clone();
319-
assert!(T::SortedListProvider::contains(&stash));
319+
assert!(T::VoterList::contains(&stash));
320320

321321
let ed = T::Currency::minimum_balance();
322322
let mut ledger = Ledger::<T>::get(&controller).unwrap();
@@ -328,28 +328,24 @@ benchmarks! {
328328
}: withdraw_unbonded(RawOrigin::Signed(controller.clone()), s)
329329
verify {
330330
assert!(!Ledger::<T>::contains_key(controller));
331-
assert!(!T::SortedListProvider::contains(&stash));
331+
assert!(!T::VoterList::contains(&stash));
332332
}
333333

334334
validate {
335-
// clean up any existing state.
336-
clear_validators_and_nominators::<T>();
337-
338-
let origin_weight = MinNominatorBond::<T>::get().max(T::Currency::minimum_balance());
339-
340-
// setup a worst case scenario where the user calling validate was formerly a nominator so
341-
// they must be removed from the list.
342-
let scenario = ListScenario::<T>::new(origin_weight, true)?;
343-
let controller = scenario.origin_controller1.clone();
344-
let stash = scenario.origin_stash1.clone();
345-
assert!(T::SortedListProvider::contains(&stash));
335+
let (stash, controller) = create_stash_controller::<T>(
336+
T::MaxNominations::get() - 1,
337+
100,
338+
Default::default(),
339+
)?;
340+
// because it is chilled.
341+
assert!(!T::VoterList::contains(&stash));
346342

347343
let prefs = ValidatorPrefs::default();
348344
whitelist_account!(controller);
349345
}: _(RawOrigin::Signed(controller), prefs)
350346
verify {
351347
assert!(Validators::<T>::contains_key(&stash));
352-
assert!(!T::SortedListProvider::contains(&stash));
348+
assert!(T::VoterList::contains(&stash));
353349
}
354350

355351
kick {
@@ -434,14 +430,14 @@ benchmarks! {
434430
).unwrap();
435431

436432
assert!(!Nominators::<T>::contains_key(&stash));
437-
assert!(!T::SortedListProvider::contains(&stash));
433+
assert!(!T::VoterList::contains(&stash));
438434

439435
let validators = create_validators::<T>(n, 100).unwrap();
440436
whitelist_account!(controller);
441437
}: _(RawOrigin::Signed(controller), validators)
442438
verify {
443439
assert!(Nominators::<T>::contains_key(&stash));
444-
assert!(T::SortedListProvider::contains(&stash))
440+
assert!(T::VoterList::contains(&stash))
445441
}
446442

447443
chill {
@@ -455,12 +451,12 @@ benchmarks! {
455451
let scenario = ListScenario::<T>::new(origin_weight, true)?;
456452
let controller = scenario.origin_controller1.clone();
457453
let stash = scenario.origin_stash1.clone();
458-
assert!(T::SortedListProvider::contains(&stash));
454+
assert!(T::VoterList::contains(&stash));
459455

460456
whitelist_account!(controller);
461457
}: _(RawOrigin::Signed(controller))
462458
verify {
463-
assert!(!T::SortedListProvider::contains(&stash));
459+
assert!(!T::VoterList::contains(&stash));
464460
}
465461

466462
set_payee {
@@ -523,13 +519,13 @@ benchmarks! {
523519
let scenario = ListScenario::<T>::new(origin_weight, true)?;
524520
let controller = scenario.origin_controller1.clone();
525521
let stash = scenario.origin_stash1.clone();
526-
assert!(T::SortedListProvider::contains(&stash));
522+
assert!(T::VoterList::contains(&stash));
527523
add_slashing_spans::<T>(&stash, s);
528524

529525
}: _(RawOrigin::Root, stash.clone(), s)
530526
verify {
531527
assert!(!Ledger::<T>::contains_key(&controller));
532-
assert!(!T::SortedListProvider::contains(&stash));
528+
assert!(!T::VoterList::contains(&stash));
533529
}
534530

535531
cancel_deferred_slash {
@@ -708,13 +704,13 @@ benchmarks! {
708704
Ledger::<T>::insert(&controller, l);
709705

710706
assert!(Bonded::<T>::contains_key(&stash));
711-
assert!(T::SortedListProvider::contains(&stash));
707+
assert!(T::VoterList::contains(&stash));
712708

713709
whitelist_account!(controller);
714710
}: _(RawOrigin::Signed(controller), stash.clone(), s)
715711
verify {
716712
assert!(!Bonded::<T>::contains_key(&stash));
717-
assert!(!T::SortedListProvider::contains(&stash));
713+
assert!(!T::VoterList::contains(&stash));
718714
}
719715

720716
new_era {
@@ -899,7 +895,7 @@ benchmarks! {
899895
let scenario = ListScenario::<T>::new(origin_weight, true)?;
900896
let controller = scenario.origin_controller1.clone();
901897
let stash = scenario.origin_stash1.clone();
902-
assert!(T::SortedListProvider::contains(&stash));
898+
assert!(T::VoterList::contains(&stash));
903899

904900
Staking::<T>::set_staking_configs(
905901
RawOrigin::Root.into(),
@@ -914,7 +910,7 @@ benchmarks! {
914910
let caller = whitelisted_caller();
915911
}: _(RawOrigin::Signed(caller), controller.clone())
916912
verify {
917-
assert!(!T::SortedListProvider::contains(&stash));
913+
assert!(!T::VoterList::contains(&stash));
918914
}
919915

920916
force_apply_min_commission {

0 commit comments

Comments
 (0)