diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 47bdedbab8..565f151ce2 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -23,7 +23,7 @@ #![recursion_limit = "256"] use codec::{Decode, Encode, MaxEncodedLen}; -use frame_election_provider_support::{onchain, ExtendedBalance, VoteWeight}; +use frame_election_provider_support::{onchain, ExtendedBalance, SequentialPhragmen, VoteWeight}; use frame_support::{ construct_runtime, pallet_prelude::Get, @@ -557,7 +557,7 @@ impl pallet_staking::Config for Runtime { type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator; type OffendingValidatorsThreshold = OffendingValidatorsThreshold; type ElectionProvider = ElectionProviderMultiPhase; - type GenesisElectionProvider = onchain::OnChainSequentialPhragmen; + type GenesisElectionProvider = onchain::UnboundedExecution; type VoterList = BagsList; type MaxUnlockingChunks = ConstU32<32>; type WeightInfo = pallet_staking::weights::SubstrateWeight; @@ -642,9 +642,19 @@ impl Get> for OffchainRandomBalancing { } } -impl onchain::Config for Runtime { - type Accuracy = Perbill; - type DataProvider = ::DataProvider; +pub struct OnChainSeqPhragmen; +impl onchain::ExecutionConfig for OnChainSeqPhragmen { + type System = Runtime; + type Solver = SequentialPhragmen< + AccountId, + pallet_election_provider_multi_phase::SolutionAccuracyOf, + >; + type DataProvider = ::DataProvider; +} + +impl onchain::BoundedExecutionConfig for OnChainSeqPhragmen { + type VotersBound = ConstU32<20_000>; + type TargetsBound = ConstU32<2_000>; } impl pallet_election_provider_multi_phase::Config for Runtime { @@ -668,13 +678,9 @@ impl pallet_election_provider_multi_phase::Config for Runtime { type RewardHandler = (); // nothing to do upon rewards type DataProvider = Staking; type Solution = NposSolution16; - type Fallback = pallet_election_provider_multi_phase::NoFallback; - type GovernanceFallback = onchain::OnChainSequentialPhragmen; - type Solver = frame_election_provider_support::SequentialPhragmen< - AccountId, - SolutionAccuracyOf, - OffchainRandomBalancing, - >; + type Fallback = onchain::BoundedExecution; + type GovernanceFallback = onchain::BoundedExecution; + type Solver = SequentialPhragmen, OffchainRandomBalancing>; type ForceOrigin = EnsureRootOrHalfCouncil; type MaxElectableTargets = ConstU16<{ u16::MAX }>; type MaxElectingVoters = MaxElectingVoters; @@ -1899,6 +1905,7 @@ impl_runtime_apis! { #[cfg(test)] mod tests { use super::*; + use frame_election_provider_support::NposSolution; use frame_system::offchain::CreateSignedTransaction; use sp_runtime::UpperOf; @@ -1915,7 +1922,8 @@ mod tests { #[test] fn perbill_as_onchain_accuracy() { - type OnChainAccuracy = ::Accuracy; + type OnChainAccuracy = + <::Solution as NposSolution>::Accuracy; let maximum_chain_accuracy: Vec> = (0..MaxNominations::get()) .map(|_| >::from(OnChainAccuracy::one().deconstruct())) .collect(); diff --git a/substrate/frame/babe/src/mock.rs b/substrate/frame/babe/src/mock.rs index e74288577c..37d8e9e37a 100644 --- a/substrate/frame/babe/src/mock.rs +++ b/substrate/frame/babe/src/mock.rs @@ -19,7 +19,7 @@ use crate::{self as pallet_babe, Config, CurrentSlot}; use codec::Encode; -use frame_election_provider_support::onchain; +use frame_election_provider_support::{onchain, SequentialPhragmen}; use frame_support::{ parameter_types, traits::{ConstU128, ConstU32, ConstU64, GenesisBuild, KeyOwnerProofSystem, OnInitialize}, @@ -172,8 +172,10 @@ parameter_types! { pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(16); } -impl onchain::Config for Test { - type Accuracy = Perbill; +pub struct OnChainSeqPhragmen; +impl onchain::ExecutionConfig for OnChainSeqPhragmen { + type System = Test; + type Solver = SequentialPhragmen; type DataProvider = Staking; } @@ -195,7 +197,7 @@ impl pallet_staking::Config for Test { type MaxNominatorRewardedPerValidator = ConstU32<64>; type OffendingValidatorsThreshold = OffendingValidatorsThreshold; type NextNewSession = Session; - type ElectionProvider = onchain::OnChainSequentialPhragmen; + type ElectionProvider = onchain::UnboundedExecution; type GenesisElectionProvider = Self::ElectionProvider; type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; type MaxUnlockingChunks = ConstU32<32>; diff --git a/substrate/frame/election-provider-multi-phase/src/lib.rs b/substrate/frame/election-provider-multi-phase/src/lib.rs index ddc06ce0ae..e67a5cab8d 100644 --- a/substrate/frame/election-provider-multi-phase/src/lib.rs +++ b/substrate/frame/election-provider-multi-phase/src/lib.rs @@ -242,7 +242,7 @@ use frame_support::{ use frame_system::{ensure_none, offchain::SendTransactionTypes}; use scale_info::TypeInfo; use sp_arithmetic::{ - traits::{CheckedAdd, Saturating, Zero}, + traits::{Bounded, CheckedAdd, Saturating, Zero}, UpperOf, }; use sp_npos_elections::{ @@ -323,10 +323,7 @@ impl ElectionProvider for NoFallback { } impl InstantElectionProvider for NoFallback { - fn instant_elect( - _: Option, - _: Option, - ) -> Result, Self::Error> { + fn elect_with_bounds(_: usize, _: usize) -> Result, Self::Error> { Err("NoFallback.") } } @@ -683,7 +680,7 @@ pub mod pallet { + TypeInfo; /// Configuration for the fallback. - type Fallback: ElectionProvider< + type Fallback: InstantElectionProvider< AccountId = Self::AccountId, BlockNumber = Self::BlockNumber, DataProvider = Self::DataProvider, @@ -692,7 +689,7 @@ pub mod pallet { /// Configuration of the governance-only fallback. /// /// As a side-note, it is recommend for test-nets to use `type ElectionProvider = - /// OnChainSeqPhragmen<_>` if the test-net is not expected to have thousands of nominators. + /// BoundedExecution<_>` if the test-net is not expected to have thousands of nominators. type GovernanceFallback: InstantElectionProvider< AccountId = Self::AccountId, BlockNumber = Self::BlockNumber, @@ -1040,13 +1037,14 @@ pub mod pallet { let maybe_max_voters = maybe_max_voters.map(|x| x as usize); let maybe_max_targets = maybe_max_targets.map(|x| x as usize); - let supports = - T::GovernanceFallback::instant_elect(maybe_max_voters, maybe_max_targets).map_err( - |e| { - log!(error, "GovernanceFallback failed: {:?}", e); - Error::::FallbackFailed - }, - )?; + let supports = T::GovernanceFallback::elect_with_bounds( + maybe_max_voters.unwrap_or(Bounded::max_value()), + maybe_max_targets.unwrap_or(Bounded::max_value()), + ) + .map_err(|e| { + log!(error, "GovernanceFallback failed: {:?}", e); + Error::::FallbackFailed + })?; let solution = ReadySolution { supports, diff --git a/substrate/frame/election-provider-multi-phase/src/mock.rs b/substrate/frame/election-provider-multi-phase/src/mock.rs index e2384d2f15..1b3c4d9306 100644 --- a/substrate/frame/election-provider-multi-phase/src/mock.rs +++ b/substrate/frame/election-provider-multi-phase/src/mock.rs @@ -272,11 +272,13 @@ parameter_types! { pub static MaxElectableTargets: TargetIndex = TargetIndex::max_value(); pub static EpochLength: u64 = 30; - pub static OnChianFallback: bool = true; + pub static OnChainFallback: bool = true; } -impl onchain::Config for Runtime { - type Accuracy = sp_runtime::Perbill; +pub struct OnChainSeqPhragmen; +impl onchain::ExecutionConfig for OnChainSeqPhragmen { + type System = Runtime; + type Solver = SequentialPhragmen, Balancing>; type DataProvider = StakingMock; } @@ -288,11 +290,23 @@ impl ElectionProvider for MockFallback { type DataProvider = StakingMock; fn elect() -> Result, Self::Error> { - if OnChianFallback::get() { - onchain::OnChainSequentialPhragmen::::elect() - .map_err(|_| "OnChainSequentialPhragmen failed") + Self::elect_with_bounds(Bounded::max_value(), Bounded::max_value()) + } +} + +impl InstantElectionProvider for MockFallback { + fn elect_with_bounds( + max_voters: usize, + max_targets: usize, + ) -> Result, Self::Error> { + if OnChainFallback::get() { + onchain::UnboundedExecution::::elect_with_bounds( + max_voters, + max_targets, + ) + .map_err(|_| "UnboundedExecution failed") } else { - super::NoFallback::::elect() + super::NoFallback::::elect_with_bounds(max_voters, max_targets) } } } @@ -532,7 +546,7 @@ impl ExtBuilder { self } pub fn onchain_fallback(self, onchain: bool) -> Self { - ::set(onchain); + ::set(onchain); self } pub fn miner_weight(self, weight: Weight) -> Self { diff --git a/substrate/frame/election-provider-support/src/lib.rs b/substrate/frame/election-provider-support/src/lib.rs index 2cc27472e8..d79b5289df 100644 --- a/substrate/frame/election-provider-support/src/lib.rs +++ b/substrate/frame/election-provider-support/src/lib.rs @@ -168,6 +168,7 @@ pub mod onchain; pub mod traits; +#[cfg(feature = "std")] use codec::{Decode, Encode}; use frame_support::{traits::Get, BoundedVec, RuntimeDebug}; use sp_runtime::traits::Bounded; @@ -368,9 +369,10 @@ pub trait ElectionProvider { BlockNumber = Self::BlockNumber, >; - /// Elect a new set of winners. + /// Elect a new set of winners, without specifying any bounds on the amount of data fetched from + /// [`Self::DataProvider`]. An implementation could nonetheless impose its own custom limits. /// - /// The result is returned in a target major format, namely as vector of supports. + /// The result is returned in a target major format, namely as *vector of supports*. /// /// This should be implemented as a self-weighing function. The implementor should register its /// appropriate weight at the end of execution with the system pallet directly. @@ -385,11 +387,17 @@ pub trait ElectionProvider { /// Consequently, allows for control over the amount of data that is being fetched from the /// [`ElectionProvider::DataProvider`]. pub trait InstantElectionProvider: ElectionProvider { - /// Elect a new set of winners, instantly, with the given given limits set on the + /// Elect a new set of winners, but unlike [`ElectionProvider::elect`] which cannot enforce + /// bounds, this trait method can enforce bounds on the amount of data provided by the /// `DataProvider`. - fn instant_elect( - maybe_max_voters: Option, - maybe_max_targets: Option, + /// + /// An implementing type, if itself bounded, should choose the minimum of the two bounds to + /// choose the final value of `max_voters` and `max_targets`. In other words, an implementation + /// should guarantee that `max_voter` and `max_targets` provided to this method are absolutely + /// respected. + fn elect_with_bounds( + max_voters: usize, + max_targets: usize, ) -> Result, Self::Error>; } diff --git a/substrate/frame/election-provider-support/src/onchain.rs b/substrate/frame/election-provider-support/src/onchain.rs index 7d845c2dc5..57fd931a46 100644 --- a/substrate/frame/election-provider-support/src/onchain.rs +++ b/substrate/frame/election-provider-support/src/onchain.rs @@ -15,9 +15,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! An implementation of [`ElectionProvider`] that does an on-chain sequential phragmen. +//! An implementation of [`ElectionProvider`] that uses an `NposSolver` to do the election. -use crate::{ElectionDataProvider, ElectionProvider, InstantElectionProvider}; +use crate::{ElectionDataProvider, ElectionProvider, InstantElectionProvider, NposSolver}; use frame_support::{traits::Get, weights::DispatchClass}; use sp_npos_elections::*; use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData, prelude::*}; @@ -41,92 +41,141 @@ impl From for Error { /// /// This will accept voting data on the fly and produce the results immediately. /// +/// Finally, the [`ElectionProvider`] implementation of this type does not impose any limits on the +/// number of voters and targets that are fetched. This could potentially make this unsuitable for +/// execution onchain. One could, however, impose bounds on it by using for example +/// `BoundedExecution` which will the bounds provided in the configuration. +/// +/// On the other hand, the [`InstantElectionProvider`] implementation does limit these inputs, +/// either via using `BoundedExecution` and imposing the bounds there, or dynamically via calling +/// `elect_with_bounds` providing these bounds. If you use `elect_with_bounds` along with +/// `InstantElectionProvider`, the bound that would be used is the minimum of the 2 bounds. +/// +/// It is advisable to use the former ([`ElectionProvider::elect`]) only at genesis, or for testing, +/// the latter [`InstantElectionProvider::elect_with_bounds`] for onchain operations, with +/// thoughtful bounds. +/// +/// Please use `BoundedExecution` at all times except at genesis or for testing, with thoughtful +/// bounds in order to bound the potential execution time. Limit the use `UnboundedExecution` at +/// genesis or for testing, as it does not bound the inputs. However, this can be used with +/// `[InstantElectionProvider::elect_with_bounds`] that dynamically imposes limits. +pub struct BoundedExecution(PhantomData); + +/// An unbounded variant of [`BoundedExecution`]. +/// /// ### Warning /// /// This can be very expensive to run frequently on-chain. Use with care. Moreover, this /// implementation ignores the additional data of the election data provider and gives no insight on /// how much weight was consumed. -/// -/// Finally, the [`ElectionProvider`] implementation of this type does not impose any limits on the -/// number of voters and targets that are fetched. This could potentially make this unsuitable for -/// execution onchain. On the other hand, the [`InstantElectionProvider`] implementation does limit -/// these inputs. -/// -/// It is advisable to use the former ([`ElectionProvider::elect`]) only at genesis, or for testing, -/// the latter [`InstantElectionProvider::instant_elect`] for onchain operations, with thoughtful -/// bounds. -pub struct OnChainSequentialPhragmen(PhantomData); +pub struct UnboundedExecution(PhantomData); -/// Configuration trait of [`OnChainSequentialPhragmen`]. -/// -/// Note that this is similar to a pallet traits, but [`OnChainSequentialPhragmen`] is not a pallet. -/// -/// WARNING: the user of this pallet must ensure that the `Accuracy` type will work nicely with the -/// normalization operation done inside `seq_phragmen`. See -/// [`sp_npos_elections::Assignment::try_normalize`] for more info. -pub trait Config: frame_system::Config { - /// The accuracy used to compute the election: - type Accuracy: PerThing128; +/// Configuration trait of [`UnboundedExecution`]. +pub trait ExecutionConfig { + /// Something that implements the system pallet configs. This is to enable to register extra + /// weight. + type System: frame_system::Config; + /// `NposSolver` that should be used, an example would be `PhragMMS`. + type Solver: NposSolver< + AccountId = ::AccountId, + Error = sp_npos_elections::Error, + >; /// Something that provides the data for election. type DataProvider: ElectionDataProvider< - AccountId = Self::AccountId, - BlockNumber = Self::BlockNumber, + AccountId = ::AccountId, + BlockNumber = ::BlockNumber, >; } -impl OnChainSequentialPhragmen { - fn elect_with( - maybe_max_voters: Option, - maybe_max_targets: Option, - ) -> Result, Error> { - let voters = ::DataProvider::electing_voters(maybe_max_voters) - .map_err(Error::DataProvider)?; - let targets = - ::DataProvider::electable_targets(maybe_max_targets) - .map_err(Error::DataProvider)?; - let desired_targets = ::DataProvider::desired_targets() - .map_err(Error::DataProvider)?; - - let stake_map: BTreeMap = voters - .iter() - .map(|(validator, vote_weight, _)| (validator.clone(), *vote_weight)) - .collect(); - - let stake_of = - |w: &T::AccountId| -> VoteWeight { stake_map.get(w).cloned().unwrap_or_default() }; - - let ElectionResult::<_, T::Accuracy> { winners: _, assignments } = - seq_phragmen(desired_targets as usize, targets, voters, None).map_err(Error::from)?; - - let staked = assignment_ratio_to_staked_normalized(assignments, &stake_of)?; - - let weight = T::BlockWeights::get().max_block; - frame_system::Pallet::::register_extra_weight_unchecked( - weight, - DispatchClass::Mandatory, - ); - - Ok(to_supports(&staked)) - } +/// Configuration trait of [`BoundedExecution`]. +pub trait BoundedExecutionConfig: ExecutionConfig { + /// Bounds the number of voters. + type VotersBound: Get; + /// Bounds the number of targets. + type TargetsBound: Get; } -impl ElectionProvider for OnChainSequentialPhragmen { - type AccountId = T::AccountId; - type BlockNumber = T::BlockNumber; +fn elect_with( + maybe_max_voters: Option, + maybe_max_targets: Option, +) -> Result::AccountId>, Error> { + let voters = T::DataProvider::electing_voters(maybe_max_voters).map_err(Error::DataProvider)?; + let targets = + T::DataProvider::electable_targets(maybe_max_targets).map_err(Error::DataProvider)?; + let desired_targets = T::DataProvider::desired_targets().map_err(Error::DataProvider)?; + + let stake_map: BTreeMap<_, _> = voters + .iter() + .map(|(validator, vote_weight, _)| (validator.clone(), *vote_weight)) + .collect(); + + let stake_of = |w: &::AccountId| -> VoteWeight { + stake_map.get(w).cloned().unwrap_or_default() + }; + + let ElectionResult { winners: _, assignments } = + T::Solver::solve(desired_targets as usize, targets, voters).map_err(Error::from)?; + + let staked = assignment_ratio_to_staked_normalized(assignments, &stake_of)?; + + let weight = ::BlockWeights::get().max_block; + frame_system::Pallet::::register_extra_weight_unchecked( + weight, + DispatchClass::Mandatory, + ); + + Ok(to_supports(&staked)) +} + +impl ElectionProvider for UnboundedExecution { + type AccountId = ::AccountId; + type BlockNumber = ::BlockNumber; type Error = Error; type DataProvider = T::DataProvider; - fn elect() -> Result, Self::Error> { - Self::elect_with(None, None) + fn elect() -> Result::AccountId>, Self::Error> { + // This should not be called if not in `std` mode (and therefore neither in genesis nor in + // testing) + if cfg!(not(feature = "std")) { + frame_support::log::error!( + "Please use `InstantElectionProvider` instead to provide bounds on election if not in \ + genesis or testing mode" + ); + } + + elect_with::(None, None) } } -impl InstantElectionProvider for OnChainSequentialPhragmen { - fn instant_elect( - maybe_max_voters: Option, - maybe_max_targets: Option, +impl InstantElectionProvider for UnboundedExecution { + fn elect_with_bounds( + max_voters: usize, + max_targets: usize, ) -> Result, Self::Error> { - Self::elect_with(maybe_max_voters, maybe_max_targets) + elect_with::(Some(max_voters), Some(max_targets)) + } +} + +impl ElectionProvider for BoundedExecution { + type AccountId = ::AccountId; + type BlockNumber = ::BlockNumber; + type Error = Error; + type DataProvider = T::DataProvider; + + fn elect() -> Result::AccountId>, Self::Error> { + elect_with::(Some(T::VotersBound::get() as usize), Some(T::TargetsBound::get() as usize)) + } +} + +impl InstantElectionProvider for BoundedExecution { + fn elect_with_bounds( + max_voters: usize, + max_targets: usize, + ) -> Result, Self::Error> { + elect_with::( + Some(max_voters.min(T::VotersBound::get() as usize)), + Some(max_targets.min(T::TargetsBound::get() as usize)), + ) } } @@ -135,7 +184,6 @@ mod tests { use super::*; use sp_npos_elections::Support; use sp_runtime::Perbill; - type AccountId = u64; type BlockNumber = u64; @@ -180,12 +228,13 @@ mod tests { type MaxConsumers = frame_support::traits::ConstU32<16>; } - impl Config for Runtime { - type Accuracy = Perbill; + impl ExecutionConfig for Runtime { + type System = Self; + type Solver = crate::SequentialPhragmen; type DataProvider = mock_data_provider::DataProvider; } - type OnChainPhragmen = OnChainSequentialPhragmen; + type OnChainPhragmen = UnboundedExecution; mod mock_data_provider { use frame_support::{bounded_vec, traits::ConstU32}; diff --git a/substrate/frame/grandpa/src/mock.rs b/substrate/frame/grandpa/src/mock.rs index 6490a2b699..0296cd2e28 100644 --- a/substrate/frame/grandpa/src/mock.rs +++ b/substrate/frame/grandpa/src/mock.rs @@ -22,7 +22,7 @@ use crate::{self as pallet_grandpa, AuthorityId, AuthorityList, Config, ConsensusLog}; use ::grandpa as finality_grandpa; use codec::Encode; -use frame_election_provider_support::onchain; +use frame_election_provider_support::{onchain, SequentialPhragmen}; use frame_support::{ parameter_types, traits::{ @@ -180,8 +180,10 @@ parameter_types! { pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17); } -impl onchain::Config for Test { - type Accuracy = Perbill; +pub struct OnChainSeqPhragmen; +impl onchain::ExecutionConfig for OnChainSeqPhragmen { + type System = Test; + type Solver = SequentialPhragmen<::AccountId, Perbill>; type DataProvider = Staking; } @@ -203,7 +205,7 @@ impl pallet_staking::Config for Test { type MaxNominatorRewardedPerValidator = ConstU32<64>; type OffendingValidatorsThreshold = OffendingValidatorsThreshold; type NextNewSession = Session; - type ElectionProvider = onchain::OnChainSequentialPhragmen; + type ElectionProvider = onchain::UnboundedExecution; type GenesisElectionProvider = Self::ElectionProvider; type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; type MaxUnlockingChunks = ConstU32<32>; diff --git a/substrate/frame/merkle-mountain-range/src/mmr/storage.rs b/substrate/frame/merkle-mountain-range/src/mmr/storage.rs index a48f60183d..535057ca80 100644 --- a/substrate/frame/merkle-mountain-range/src/mmr/storage.rs +++ b/substrate/frame/merkle-mountain-range/src/mmr/storage.rs @@ -18,7 +18,6 @@ //! A MMR storage implementations. use codec::Encode; -use frame_support::log; use mmr_lib::helper; use sp_io::offchain_index; use sp_std::iter::Peekable; @@ -93,7 +92,7 @@ where } sp_std::if_std! { - log::trace!("elems: {:?}", elems.iter().map(|elem| elem.hash()).collect::>()); + frame_support::log::trace!("elems: {:?}", elems.iter().map(|elem| elem.hash()).collect::>()); } let leaves = NumberOfLeaves::::get(); @@ -152,8 +151,8 @@ fn peaks_to_prune_and_store( let peaks_before = if old_size == 0 { vec![] } else { helper::get_peaks(old_size) }; let peaks_after = helper::get_peaks(new_size); sp_std::if_std! { - log::trace!("peaks_before: {:?}", peaks_before); - log::trace!("peaks_after: {:?}", peaks_after); + frame_support::log::trace!("peaks_before: {:?}", peaks_before); + frame_support::log::trace!("peaks_after: {:?}", peaks_after); } let mut peaks_before = peaks_before.into_iter().peekable(); let mut peaks_after = peaks_after.into_iter().peekable(); diff --git a/substrate/frame/offences/benchmarking/src/mock.rs b/substrate/frame/offences/benchmarking/src/mock.rs index 4359b7745d..1a4414de0b 100644 --- a/substrate/frame/offences/benchmarking/src/mock.rs +++ b/substrate/frame/offences/benchmarking/src/mock.rs @@ -20,7 +20,7 @@ #![cfg(test)] use super::*; -use frame_election_provider_support::onchain; +use frame_election_provider_support::{onchain, SequentialPhragmen}; use frame_support::{ parameter_types, traits::{ConstU32, ConstU64}, @@ -150,8 +150,10 @@ parameter_types! { pub type Extrinsic = sp_runtime::testing::TestXt; -impl onchain::Config for Test { - type Accuracy = Perbill; +pub struct OnChainSeqPhragmen; +impl onchain::ExecutionConfig for OnChainSeqPhragmen { + type System = Test; + type Solver = SequentialPhragmen; type DataProvider = Staking; } @@ -173,7 +175,7 @@ impl pallet_staking::Config for Test { type NextNewSession = Session; type MaxNominatorRewardedPerValidator = ConstU32<64>; type OffendingValidatorsThreshold = (); - type ElectionProvider = onchain::OnChainSequentialPhragmen; + type ElectionProvider = onchain::UnboundedExecution; type GenesisElectionProvider = Self::ElectionProvider; type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; type MaxUnlockingChunks = ConstU32<32>; diff --git a/substrate/frame/session/benchmarking/src/mock.rs b/substrate/frame/session/benchmarking/src/mock.rs index 5ebc752456..24b42b3e9f 100644 --- a/substrate/frame/session/benchmarking/src/mock.rs +++ b/substrate/frame/session/benchmarking/src/mock.rs @@ -19,7 +19,7 @@ #![cfg(test)] -use frame_election_provider_support::onchain; +use frame_election_provider_support::{onchain, SequentialPhragmen}; use frame_support::{ parameter_types, traits::{ConstU32, ConstU64}, @@ -156,8 +156,10 @@ where type Extrinsic = Extrinsic; } -impl onchain::Config for Test { - type Accuracy = sp_runtime::Perbill; +pub struct OnChainSeqPhragmen; +impl onchain::ExecutionConfig for OnChainSeqPhragmen { + type System = Test; + type Solver = SequentialPhragmen; type DataProvider = Staking; } @@ -179,7 +181,7 @@ impl pallet_staking::Config for Test { type NextNewSession = Session; type MaxNominatorRewardedPerValidator = ConstU32<64>; type OffendingValidatorsThreshold = (); - type ElectionProvider = onchain::OnChainSequentialPhragmen; + type ElectionProvider = onchain::UnboundedExecution; type GenesisElectionProvider = Self::ElectionProvider; type MaxUnlockingChunks = ConstU32<32>; type VoterList = pallet_staking::UseNominatorsAndValidatorsMap; diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs index bb71232c34..bb90aded85 100644 --- a/substrate/frame/staking/src/mock.rs +++ b/substrate/frame/staking/src/mock.rs @@ -18,7 +18,9 @@ //! Test utilities use crate::{self as pallet_staking, *}; -use frame_election_provider_support::{onchain, SortedListProvider, VoteWeight}; +use frame_election_provider_support::{ + onchain, SequentialPhragmen, SortedListProvider, VoteWeight, +}; use frame_support::{ assert_ok, parameter_types, traits::{ @@ -245,8 +247,10 @@ impl pallet_bags_list::Config for Test { type Score = VoteWeight; } -impl onchain::Config for Test { - type Accuracy = Perbill; +pub struct OnChainSeqPhragmen; +impl onchain::ExecutionConfig for OnChainSeqPhragmen { + type System = Test; + type Solver = SequentialPhragmen; type DataProvider = Staking; } @@ -268,7 +272,7 @@ impl crate::pallet::pallet::Config for Test { type NextNewSession = Session; type MaxNominatorRewardedPerValidator = ConstU32<64>; type OffendingValidatorsThreshold = OffendingValidatorsThreshold; - type ElectionProvider = onchain::OnChainSequentialPhragmen; + type ElectionProvider = onchain::UnboundedExecution; type GenesisElectionProvider = Self::ElectionProvider; // NOTE: consider a macro and use `UseNominatorsAndValidatorsMap` as well. type VoterList = BagsList;