mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-16 08:31:14 +00:00
Bound Election and Staking by MaxActiveValidators (#12436)
* 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>
This commit is contained in:
@@ -17,7 +17,9 @@
|
||||
|
||||
//! Staking FRAME Pallet.
|
||||
|
||||
use frame_election_provider_support::{SortedListProvider, VoteWeight};
|
||||
use frame_election_provider_support::{
|
||||
ElectionProvider, ElectionProviderBase, SortedListProvider, VoteWeight,
|
||||
};
|
||||
use frame_support::{
|
||||
dispatch::Codec,
|
||||
pallet_prelude::*,
|
||||
@@ -32,7 +34,7 @@ use frame_support::{
|
||||
use frame_system::{ensure_root, ensure_signed, pallet_prelude::*};
|
||||
use sp_runtime::{
|
||||
traits::{CheckedSub, SaturatedConversion, StaticLookup, Zero},
|
||||
Perbill, Percent,
|
||||
ArithmeticError, Perbill, Percent,
|
||||
};
|
||||
use sp_staking::{EraIndex, SessionIndex};
|
||||
use sp_std::prelude::*;
|
||||
@@ -107,7 +109,7 @@ pub mod pallet {
|
||||
type CurrencyToVote: CurrencyToVote<BalanceOf<Self>>;
|
||||
|
||||
/// Something that provides the election functionality.
|
||||
type ElectionProvider: frame_election_provider_support::ElectionProvider<
|
||||
type ElectionProvider: ElectionProvider<
|
||||
AccountId = Self::AccountId,
|
||||
BlockNumber = Self::BlockNumber,
|
||||
// we only accept an election provider that has staking as data provider.
|
||||
@@ -115,7 +117,7 @@ pub mod pallet {
|
||||
>;
|
||||
|
||||
/// Something that provides the election functionality at genesis.
|
||||
type GenesisElectionProvider: frame_election_provider_support::ElectionProvider<
|
||||
type GenesisElectionProvider: ElectionProvider<
|
||||
AccountId = Self::AccountId,
|
||||
BlockNumber = Self::BlockNumber,
|
||||
DataProvider = Pallet<Self>,
|
||||
@@ -646,6 +648,10 @@ pub mod pallet {
|
||||
),
|
||||
_ => Ok(()),
|
||||
});
|
||||
assert!(
|
||||
ValidatorCount::<T>::get() <=
|
||||
<T::ElectionProvider as ElectionProviderBase>::MaxWinners::get()
|
||||
);
|
||||
}
|
||||
|
||||
// all voters are reported to the `VoterList`.
|
||||
@@ -743,8 +749,8 @@ pub mod pallet {
|
||||
/// There are too many nominators in the system. Governance needs to adjust the staking
|
||||
/// settings to keep things safe for the runtime.
|
||||
TooManyNominators,
|
||||
/// There are too many validators in the system. Governance needs to adjust the staking
|
||||
/// settings to keep things safe for the runtime.
|
||||
/// There are too many validator candidates in the system. Governance needs to adjust the
|
||||
/// staking settings to keep things safe for the runtime.
|
||||
TooManyValidators,
|
||||
/// Commission is too low. Must be at least `MinCommission`.
|
||||
CommissionTooLow,
|
||||
@@ -782,6 +788,12 @@ pub mod pallet {
|
||||
// and that MaxNominations is always greater than 1, since we count on this.
|
||||
assert!(!T::MaxNominations::get().is_zero());
|
||||
|
||||
// ensure election results are always bounded with the same value
|
||||
assert!(
|
||||
<T::ElectionProvider as ElectionProviderBase>::MaxWinners::get() ==
|
||||
<T::GenesisElectionProvider as ElectionProviderBase>::MaxWinners::get()
|
||||
);
|
||||
|
||||
sp_std::if_std! {
|
||||
sp_io::TestExternalities::new_empty().execute_with(||
|
||||
assert!(
|
||||
@@ -1264,11 +1276,18 @@ pub mod pallet {
|
||||
#[pallet::compact] new: u32,
|
||||
) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
// ensure new validator count does not exceed maximum winners
|
||||
// support by election provider.
|
||||
ensure!(
|
||||
new <= <T::ElectionProvider as ElectionProviderBase>::MaxWinners::get(),
|
||||
Error::<T>::TooManyValidators
|
||||
);
|
||||
ValidatorCount::<T>::put(new);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Increments the ideal number of validators.
|
||||
/// Increments the ideal number of validators upto maximum of
|
||||
/// `ElectionProviderBase::MaxWinners`.
|
||||
///
|
||||
/// The dispatch origin must be Root.
|
||||
///
|
||||
@@ -1281,11 +1300,19 @@ pub mod pallet {
|
||||
#[pallet::compact] additional: u32,
|
||||
) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
ValidatorCount::<T>::mutate(|n| *n += additional);
|
||||
let old = ValidatorCount::<T>::get();
|
||||
let new = old.checked_add(additional).ok_or(ArithmeticError::Overflow)?;
|
||||
ensure!(
|
||||
new <= <T::ElectionProvider as ElectionProviderBase>::MaxWinners::get(),
|
||||
Error::<T>::TooManyValidators
|
||||
);
|
||||
|
||||
ValidatorCount::<T>::put(new);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Scale up the ideal number of validators by a factor.
|
||||
/// Scale up the ideal number of validators by a factor upto maximum of
|
||||
/// `ElectionProviderBase::MaxWinners`.
|
||||
///
|
||||
/// The dispatch origin must be Root.
|
||||
///
|
||||
@@ -1295,7 +1322,15 @@ pub mod pallet {
|
||||
#[pallet::weight(T::WeightInfo::set_validator_count())]
|
||||
pub fn scale_validator_count(origin: OriginFor<T>, factor: Percent) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
ValidatorCount::<T>::mutate(|n| *n += factor * *n);
|
||||
let old = ValidatorCount::<T>::get();
|
||||
let new = old.checked_add(factor.mul_floor(old)).ok_or(ArithmeticError::Overflow)?;
|
||||
|
||||
ensure!(
|
||||
new <= <T::ElectionProvider as ElectionProviderBase>::MaxWinners::get(),
|
||||
Error::<T>::TooManyValidators
|
||||
);
|
||||
|
||||
ValidatorCount::<T>::put(new);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user