Skip to content

Commit

Permalink
Bound Election and Staking by MaxActiveValidators (paritytech#12436)
Browse files Browse the repository at this point in the history
* bounding election provider with kian

* multi phase implement bounded election provider

* election provider blanket implementation

* staking compiles

* fix test for election provider support

* fmt

* fixing epmp tests, does not compile yet

* fix epmp tests

* fix staking tests

* fmt

* fix runtime tests

* fmt

* remove outdated wip tags

* add enum error

* sort and truncate supports

* comment

* error when unsupported number of election winners

* compiling wip after kian's suggestions

* fix TODOs

* remove,fix tags

* ensure validator count does not exceed maxwinners

* clean up

* some more clean up and todos

* handle too many winners

* rename parameter for mock

* todo

* add sort and truncate rule if there are too many winners

* fmt

* fail, not swallow emergency result bound not met

* remove too many winners resolution as it can be guaranteed to be bounded

* fix benchmark

* give MaxWinners more contextual name

* make ready solution generic over T

* kian feedback

* fix stuff

* Kian's way of solvign this

* comment fix

* fix compile

* remove use of BoundedExecution

* fmt

* comment out failing integrity test

* cap validator count increment to max winners

* dont panic

* add test for bad data provider

* Update frame/staking/src/pallet/impls.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* fix namespace conflict and add test for onchain max winners less than desired targets

* defensive unwrap

* early convert to bounded vec

* fix syntax

* fmt

* fix doc

* fix rustdoc

* fmt

* fix maxwinner count for benchmarking

* add instant election for noelection

* fmt

* fix compile

* pr feedbacks

* always error at validator count exceeding max winners

* add useful error message

* pr comments

* import fix

* add checked_desired_targets

* fmt

* fmt

* fix rust doc

Co-authored-by: parity-processbot <>
Co-authored-by: kianenigma <kian@parity.io>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
  • Loading branch information
3 people authored and ark0f committed Feb 27, 2023
1 parent 658f9ba commit fc0face
Show file tree
Hide file tree
Showing 21 changed files with 538 additions and 312 deletions.
26 changes: 16 additions & 10 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ impl pallet_staking::Config for Runtime {
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type OffendingValidatorsThreshold = OffendingValidatorsThreshold;
type ElectionProvider = ElectionProviderMultiPhase;
type GenesisElectionProvider = onchain::UnboundedExecution<OnChainSeqPhragmen>;
type GenesisElectionProvider = onchain::OnChainExecution<OnChainSeqPhragmen>;
type VoterList = VoterList;
// This a placeholder, to be introduced in the next PR as an instance of bags-list
type TargetList = pallet_staking::UseValidatorsMap<Self>;
Expand Down Expand Up @@ -628,7 +628,14 @@ frame_election_provider_support::generate_solution_type!(

parameter_types! {
pub MaxNominations: u32 = <NposSolution16 as frame_election_provider_support::NposSolution>::LIMIT as u32;
pub MaxElectingVoters: u32 = 10_000;
pub MaxElectingVoters: u32 = 40_000;
pub MaxElectableTargets: u16 = 10_000;
// OnChain values are lower.
pub MaxOnChainElectingVoters: u32 = 5000;
pub MaxOnChainElectableTargets: u16 = 1250;
// The maximum winners that can be elected by the Election pallet which is equivalent to the
// maximum active validators the staking pallet can have.
pub MaxActiveValidators: u32 = 1000;
}

/// The numbers configured here could always be more than the the maximum limits of staking pallet
Expand Down Expand Up @@ -679,11 +686,9 @@ impl onchain::Config for OnChainSeqPhragmen {
>;
type DataProvider = <Runtime as pallet_election_provider_multi_phase::Config>::DataProvider;
type WeightInfo = frame_election_provider_support::weights::SubstrateWeight<Runtime>;
}

impl onchain::BoundedConfig for OnChainSeqPhragmen {
type VotersBound = MaxElectingVoters;
type TargetsBound = ConstU32<2_000>;
type MaxWinners = <Runtime as pallet_election_provider_multi_phase::Config>::MaxWinners;
type VotersBound = MaxOnChainElectingVoters;
type TargetsBound = MaxOnChainElectableTargets;
}

impl pallet_election_provider_multi_phase::MinerConfig for Runtime {
Expand Down Expand Up @@ -726,11 +731,12 @@ impl pallet_election_provider_multi_phase::Config for Runtime {
type SlashHandler = (); // burn slashes
type RewardHandler = (); // nothing to do upon rewards
type DataProvider = Staking;
type Fallback = onchain::BoundedExecution<OnChainSeqPhragmen>;
type GovernanceFallback = onchain::BoundedExecution<OnChainSeqPhragmen>;
type Fallback = onchain::OnChainExecution<OnChainSeqPhragmen>;
type GovernanceFallback = onchain::OnChainExecution<OnChainSeqPhragmen>;
type Solver = SequentialPhragmen<AccountId, SolutionAccuracyOf<Self>, OffchainRandomBalancing>;
type ForceOrigin = EnsureRootOrHalfCouncil;
type MaxElectableTargets = ConstU16<{ u16::MAX }>;
type MaxElectableTargets = MaxElectableTargets;
type MaxWinners = MaxActiveValidators;
type MaxElectingVoters = MaxElectingVoters;
type BenchmarkingConfig = ElectionProviderBenchmarkConfig;
type WeightInfo = pallet_election_provider_multi_phase::weights::SubstrateWeight<Self>;
Expand Down
5 changes: 4 additions & 1 deletion frame/babe/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ impl onchain::Config for OnChainSeqPhragmen {
type Solver = SequentialPhragmen<DummyValidatorId, Perbill>;
type DataProvider = Staking;
type WeightInfo = ();
type MaxWinners = ConstU32<100>;
type VotersBound = ConstU32<{ u32::MAX }>;
type TargetsBound = ConstU32<{ u32::MAX }>;
}

impl pallet_staking::Config for Test {
Expand All @@ -199,7 +202,7 @@ impl pallet_staking::Config for Test {
type MaxNominatorRewardedPerValidator = ConstU32<64>;
type OffendingValidatorsThreshold = OffendingValidatorsThreshold;
type NextNewSession = Session;
type ElectionProvider = onchain::UnboundedExecution<OnChainSeqPhragmen>;
type ElectionProvider = onchain::OnChainExecution<OnChainSeqPhragmen>;
type GenesisElectionProvider = Self::ElectionProvider;
type VoterList = pallet_staking::UseNominatorsAndValidatorsMap<Self>;
type TargetList = pallet_staking::UseValidatorsMap<Self>;
Expand Down
8 changes: 2 additions & 6 deletions frame/election-provider-multi-phase/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,7 @@ frame_benchmarking::benchmarks! {
let receiver = account("receiver", 0, SEED);
let initial_balance = T::Currency::minimum_balance() * 10u32.into();
T::Currency::make_free_balance_be(&receiver, initial_balance);
let ready = ReadySolution {
supports: vec![],
score: Default::default(),
compute: Default::default()
};
let ready = Default::default();
let deposit: BalanceOf<T> = 10u32.into();

let reward: BalanceOf<T> = T::SignedRewardBase::get();
Expand Down Expand Up @@ -403,7 +399,7 @@ frame_benchmarking::benchmarks! {
assert_eq!(raw_solution.solution.voter_count() as u32, a);
assert_eq!(raw_solution.solution.unique_targets().len() as u32, d);
}: {
assert_ok!(<MultiPhase<T>>::feasibility_check(raw_solution, ElectionCompute::Unsigned));
assert!(<MultiPhase<T>>::feasibility_check(raw_solution, ElectionCompute::Unsigned).is_ok());
}

// NOTE: this weight is not used anywhere, but the fact that it should succeed when execution in
Expand Down
Loading

0 comments on commit fc0face

Please sign in to comment.