mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 05:21:08 +00:00
Make the number of nominations configurable (#8368)
* Base features and traits. * pallet and unsigned phase * Undo bad formattings. * some formatting cleanup. * Small self-cleanup. * Make it all build * self-review * Some doc tests. * Some changes from other PR * Fix session test * Update Cargo.lock * Update frame/election-provider-multi-phase/src/lib.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Some review comments * Rename + make encode/decode * Do an assert as well, just in case. * Fix build * Update frame/election-provider-multi-phase/src/unsigned.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Las comment * fix staking fuzzer. * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_election_provider_multi_phase --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/election-provider-multi-phase/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Add one last layer of feasibility check as well. * Last fixes to benchmarks * Some more docs. * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_election_provider_multi_phase --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/election-provider-multi-phase/src/weights.rs --template=./.maintain/frame-weight-template.hbs * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_election_provider_multi_phase --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/election-provider-multi-phase/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Some nits * It all works * Some self cleanup * Update frame/staking/src/lib.rs Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com> * remove most todos. * Round of self-review. * Fix migration * clean macro * Revert wrong merge * Make the number of nominations configurable * Self reivew * renmae. Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> Co-authored-by: Parity Benchmarking Bot <admin@parity.io> Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com>
This commit is contained in:
Generated
+1
-1
@@ -4338,6 +4338,7 @@ dependencies = [
|
||||
"sp-inherents",
|
||||
"sp-io",
|
||||
"sp-keyring",
|
||||
"sp-npos-elections",
|
||||
"sp-offchain",
|
||||
"sp-runtime",
|
||||
"sp-session",
|
||||
@@ -5436,7 +5437,6 @@ dependencies = [
|
||||
"sp-application-crypto",
|
||||
"sp-core",
|
||||
"sp-io",
|
||||
"sp-npos-elections",
|
||||
"sp-runtime",
|
||||
"sp-staking",
|
||||
"sp-std",
|
||||
|
||||
@@ -36,6 +36,7 @@ sp-keyring = { version = "3.0.0", optional = true, path = "../../../primitives/k
|
||||
sp-session = { version = "3.0.0", default-features = false, path = "../../../primitives/session" }
|
||||
sp-transaction-pool = { version = "3.0.0", default-features = false, path = "../../../primitives/transaction-pool" }
|
||||
sp-version = { version = "3.0.0", default-features = false, path = "../../../primitives/version" }
|
||||
sp-npos-elections = { version = "3.0.0", default-features = false, path = "../../../primitives/npos-elections" }
|
||||
|
||||
# frame dependencies
|
||||
frame-executive = { version = "3.0.0", default-features = false, path = "../../../frame/executive" }
|
||||
@@ -159,6 +160,7 @@ std = [
|
||||
"pallet-vesting/std",
|
||||
"log/std",
|
||||
"frame-try-runtime/std",
|
||||
"sp-npos-elections/std",
|
||||
]
|
||||
runtime-benchmarks = [
|
||||
"frame-benchmarking",
|
||||
|
||||
@@ -471,6 +471,8 @@ parameter_types! {
|
||||
}
|
||||
|
||||
impl pallet_staking::Config for Runtime {
|
||||
const MAX_NOMINATIONS: u32 =
|
||||
<NposCompactSolution16 as sp_npos_elections::CompactSolution>::LIMIT as u32;
|
||||
type Currency = Balances;
|
||||
type UnixTime = Timestamp;
|
||||
type CurrencyToVote = U128CurrencyToVote;
|
||||
@@ -515,6 +517,12 @@ parameter_types! {
|
||||
.saturating_sub(BlockExecutionWeight::get());
|
||||
}
|
||||
|
||||
sp_npos_elections::generate_solution_type!(
|
||||
#[compact]
|
||||
pub struct NposCompactSolution16::<u32, u16, sp_runtime::PerU16>(16)
|
||||
// -------------------- ^^ <NominatorIndex, ValidatorIndex, Accuracy>
|
||||
);
|
||||
|
||||
impl pallet_election_provider_multi_phase::Config for Runtime {
|
||||
type Event = Event;
|
||||
type Currency = Balances;
|
||||
@@ -526,7 +534,7 @@ impl pallet_election_provider_multi_phase::Config for Runtime {
|
||||
type MinerTxPriority = MultiPhaseUnsignedPriority;
|
||||
type DataProvider = Staking;
|
||||
type OnChainAccuracy = Perbill;
|
||||
type CompactSolution = pallet_staking::CompactAssignments;
|
||||
type CompactSolution = NposCompactSolution16;
|
||||
type Fallback = Fallback;
|
||||
type WeightInfo = pallet_election_provider_multi_phase::weights::SubstrateWeight<Runtime>;
|
||||
type BenchmarkingConfig = ();
|
||||
|
||||
@@ -193,6 +193,7 @@ impl onchain::Config for Test {
|
||||
}
|
||||
|
||||
impl pallet_staking::Config for Test {
|
||||
const MAX_NOMINATIONS: u32 = 16;
|
||||
type RewardRemainder = ();
|
||||
type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote;
|
||||
type Event = Event;
|
||||
|
||||
@@ -678,6 +678,16 @@ pub mod pallet {
|
||||
let _: UpperOf<CompactAccuracyOf<T>> = maximum_chain_accuracy
|
||||
.iter()
|
||||
.fold(Zero::zero(), |acc, x| acc.checked_add(x).unwrap());
|
||||
|
||||
// We only accept data provider who's maximum votes per voter matches our
|
||||
// `T::CompactSolution`'s `LIMIT`.
|
||||
//
|
||||
// NOTE that this pallet does not really need to enforce this in runtime. The compact
|
||||
// solution cannot represent any voters more than `LIMIT` anyhow.
|
||||
assert_eq!(
|
||||
<T::DataProvider as ElectionDataProvider<T::AccountId, T::BlockNumber>>::MAXIMUM_VOTES_PER_VOTER,
|
||||
<CompactOf<T> as CompactSolution>::LIMIT as u32,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -300,6 +300,7 @@ pub struct ExtBuilder {}
|
||||
|
||||
pub struct StakingMock;
|
||||
impl ElectionDataProvider<AccountId, u64> for StakingMock {
|
||||
const MAXIMUM_VOTES_PER_VOTER: u32 = <TestCompact as CompactSolution>::LIMIT as u32;
|
||||
fn targets(maybe_max_len: Option<usize>) -> data_provider::Result<(Vec<AccountId>, Weight)> {
|
||||
let targets = Targets::get();
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
//! pub struct Module<T: Config>(std::marker::PhantomData<T>);
|
||||
//!
|
||||
//! impl<T: Config> ElectionDataProvider<AccountId, BlockNumber> for Module<T> {
|
||||
//! const MAXIMUM_VOTES_PER_VOTER: u32 = 1;
|
||||
//! fn desired_targets() -> data_provider::Result<(u32, Weight)> {
|
||||
//! Ok((1, 0))
|
||||
//! }
|
||||
@@ -180,6 +181,9 @@ pub mod data_provider {
|
||||
|
||||
/// Something that can provide the data to an [`ElectionProvider`].
|
||||
pub trait ElectionDataProvider<AccountId, BlockNumber> {
|
||||
/// Maximum number of votes per voter that this data provider is providing.
|
||||
const MAXIMUM_VOTES_PER_VOTER: u32;
|
||||
|
||||
/// All possible targets for the election, i.e. the candidates.
|
||||
///
|
||||
/// If `maybe_max_len` is `Some(v)` then the resulting vector MUST NOT be longer than `v` items
|
||||
@@ -226,6 +230,7 @@ pub trait ElectionDataProvider<AccountId, BlockNumber> {
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<AccountId, BlockNumber> ElectionDataProvider<AccountId, BlockNumber> for () {
|
||||
const MAXIMUM_VOTES_PER_VOTER: u32 = 0;
|
||||
fn targets(_maybe_max_len: Option<usize>) -> data_provider::Result<(Vec<AccountId>, Weight)> {
|
||||
Ok(Default::default())
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ mod tests {
|
||||
pub struct DataProvider;
|
||||
|
||||
impl ElectionDataProvider<AccountId, BlockNumber> for DataProvider {
|
||||
const MAXIMUM_VOTES_PER_VOTER: u32 = 2;
|
||||
fn voters(
|
||||
_: Option<usize>,
|
||||
) -> data_provider::Result<(Vec<(AccountId, VoteWeight, Vec<AccountId>)>, Weight)> {
|
||||
|
||||
@@ -199,6 +199,7 @@ impl onchain::Config for Test {
|
||||
}
|
||||
|
||||
impl pallet_staking::Config for Test {
|
||||
const MAX_NOMINATIONS: u32 = 16;
|
||||
type RewardRemainder = ();
|
||||
type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote;
|
||||
type Event = Event;
|
||||
|
||||
@@ -28,7 +28,10 @@ use frame_system::{RawOrigin, Pallet as System, Config as SystemConfig};
|
||||
use frame_benchmarking::{benchmarks, account, impl_benchmark_test_suite};
|
||||
use frame_support::traits::{Currency, OnInitialize, ValidatorSet, ValidatorSetWithIdentification};
|
||||
|
||||
use sp_runtime::{Perbill, traits::{Convert, StaticLookup, Saturating, UniqueSaturatedInto}};
|
||||
use sp_runtime::{
|
||||
Perbill,
|
||||
traits::{Convert, StaticLookup, Saturating, UniqueSaturatedInto},
|
||||
};
|
||||
use sp_staking::offence::{ReportOffence, Offence, OffenceDetails};
|
||||
|
||||
use pallet_balances::Config as BalancesConfig;
|
||||
@@ -39,8 +42,8 @@ use pallet_offences::{Config as OffencesConfig, Module as Offences};
|
||||
use pallet_session::historical::{Config as HistoricalConfig, IdentificationTuple};
|
||||
use pallet_session::{Config as SessionConfig, SessionManager};
|
||||
use pallet_staking::{
|
||||
Module as Staking, Config as StakingConfig, RewardDestination, ValidatorPrefs,
|
||||
Exposure, IndividualExposure, MAX_NOMINATIONS, Event as StakingEvent
|
||||
Module as Staking, Config as StakingConfig, RewardDestination, ValidatorPrefs, Exposure,
|
||||
IndividualExposure, Event as StakingEvent,
|
||||
};
|
||||
|
||||
const SEED: u32 = 0;
|
||||
@@ -236,7 +239,7 @@ benchmarks! {
|
||||
let r in 1 .. MAX_REPORTERS;
|
||||
// we skip 1 offender, because in such case there is no slashing
|
||||
let o in 2 .. MAX_OFFENDERS;
|
||||
let n in 0 .. MAX_NOMINATORS.min(MAX_NOMINATIONS as u32);
|
||||
let n in 0 .. MAX_NOMINATORS.min(<T as pallet_staking::Config>::MAX_NOMINATIONS);
|
||||
|
||||
// Make r reporters
|
||||
let mut reporters = vec![];
|
||||
@@ -310,7 +313,7 @@ benchmarks! {
|
||||
}
|
||||
|
||||
report_offence_grandpa {
|
||||
let n in 0 .. MAX_NOMINATORS.min(MAX_NOMINATIONS as u32);
|
||||
let n in 0 .. MAX_NOMINATORS.min(<T as pallet_staking::Config>::MAX_NOMINATIONS);
|
||||
|
||||
// for grandpa equivocation reports the number of reporters
|
||||
// and offenders is always 1
|
||||
@@ -346,7 +349,7 @@ benchmarks! {
|
||||
}
|
||||
|
||||
report_offence_babe {
|
||||
let n in 0 .. MAX_NOMINATORS.min(MAX_NOMINATIONS as u32);
|
||||
let n in 0 .. MAX_NOMINATORS.min(<T as pallet_staking::Config>::MAX_NOMINATIONS);
|
||||
|
||||
// for babe equivocation reports the number of reporters
|
||||
// and offenders is always 1
|
||||
|
||||
@@ -158,6 +158,7 @@ impl onchain::Config for Test {
|
||||
}
|
||||
|
||||
impl pallet_staking::Config for Test {
|
||||
const MAX_NOMINATIONS: u32 = 16;
|
||||
type Currency = Balances;
|
||||
type UnixTime = pallet_timestamp::Pallet<Self>;
|
||||
type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote;
|
||||
|
||||
@@ -35,7 +35,7 @@ use frame_system::RawOrigin;
|
||||
use pallet_session::{historical::Module as Historical, Module as Session, *};
|
||||
use pallet_staking::{
|
||||
benchmarking::create_validator_with_nominators, testing_utils::create_validators,
|
||||
MAX_NOMINATIONS, RewardDestination,
|
||||
RewardDestination,
|
||||
};
|
||||
use sp_runtime::traits::{One, StaticLookup};
|
||||
|
||||
@@ -52,10 +52,10 @@ impl<T: Config> OnInitialize<T::BlockNumber> for Pallet<T> {
|
||||
|
||||
benchmarks! {
|
||||
set_keys {
|
||||
let n = MAX_NOMINATIONS as u32;
|
||||
let n = <T as pallet_staking::Config>::MAX_NOMINATIONS;
|
||||
let (v_stash, _) = create_validator_with_nominators::<T>(
|
||||
n,
|
||||
MAX_NOMINATIONS as u32,
|
||||
<T as pallet_staking::Config>::MAX_NOMINATIONS,
|
||||
false,
|
||||
RewardDestination::Staked,
|
||||
)?;
|
||||
@@ -68,10 +68,10 @@ benchmarks! {
|
||||
}: _(RawOrigin::Signed(v_controller), keys, proof)
|
||||
|
||||
purge_keys {
|
||||
let n = MAX_NOMINATIONS as u32;
|
||||
let n = <T as pallet_staking::Config>::MAX_NOMINATIONS;
|
||||
let (v_stash, _) = create_validator_with_nominators::<T>(
|
||||
n,
|
||||
MAX_NOMINATIONS as u32,
|
||||
<T as pallet_staking::Config>::MAX_NOMINATIONS,
|
||||
false,
|
||||
RewardDestination::Staked
|
||||
)?;
|
||||
|
||||
@@ -163,6 +163,7 @@ impl onchain::Config for Test {
|
||||
}
|
||||
|
||||
impl pallet_staking::Config for Test {
|
||||
const MAX_NOMINATIONS: u32 = 16;
|
||||
type Currency = Balances;
|
||||
type UnixTime = pallet_timestamp::Pallet<Self>;
|
||||
type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote;
|
||||
|
||||
@@ -17,7 +17,6 @@ static_assertions = "1.1.0"
|
||||
serde = { version = "1.0.101", optional = true }
|
||||
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
|
||||
sp-std = { version = "3.0.0", default-features = false, path = "../../primitives/std" }
|
||||
sp-npos-elections = { version = "3.0.0", default-features = false, path = "../../primitives/npos-elections" }
|
||||
sp-io ={ version = "3.0.0", default-features = false, path = "../../primitives/io" }
|
||||
sp-runtime = { version = "3.0.0", default-features = false, path = "../../primitives/runtime" }
|
||||
sp-staking = { version = "3.0.0", default-features = false, path = "../../primitives/staking" }
|
||||
@@ -54,7 +53,6 @@ std = [
|
||||
"serde",
|
||||
"codec/std",
|
||||
"sp-std/std",
|
||||
"sp-npos-elections/std",
|
||||
"sp-io/std",
|
||||
"frame-support/std",
|
||||
"sp-runtime/std",
|
||||
|
||||
@@ -204,16 +204,20 @@ benchmarks! {
|
||||
kick {
|
||||
// scenario: we want to kick `k` nominators from nominating us (we are a validator).
|
||||
// we'll assume that `k` is under 128 for the purposes of determining the slope.
|
||||
// each nominator should have `MAX_NOMINATIONS` validators nominated, and our validator
|
||||
// each nominator should have `T::MAX_NOMINATIONS` validators nominated, and our validator
|
||||
// should be somewhere in there.
|
||||
let k in 1 .. 128;
|
||||
|
||||
// these are the other validators; there are `MAX_NOMINATIONS - 1` of them, so there are a
|
||||
// total of `MAX_NOMINATIONS` validators in the system.
|
||||
let rest_of_validators = create_validators::<T>(MAX_NOMINATIONS as u32 - 1, 100)?;
|
||||
// these are the other validators; there are `T::MAX_NOMINATIONS - 1` of them, so
|
||||
// there are a total of `T::MAX_NOMINATIONS` validators in the system.
|
||||
let rest_of_validators = create_validators::<T>(T::MAX_NOMINATIONS - 1, 100)?;
|
||||
|
||||
// this is the validator that will be kicking.
|
||||
let (stash, controller) = create_stash_controller::<T>(MAX_NOMINATIONS as u32 - 1, 100, Default::default())?;
|
||||
let (stash, controller) = create_stash_controller::<T>(
|
||||
T::MAX_NOMINATIONS - 1,
|
||||
100,
|
||||
Default::default(),
|
||||
)?;
|
||||
let stash_lookup: <T::Lookup as StaticLookup>::Source = T::Lookup::unlookup(stash.clone());
|
||||
|
||||
// they start validating.
|
||||
@@ -224,7 +228,11 @@ benchmarks! {
|
||||
let mut nominator_stashes = Vec::with_capacity(k as usize);
|
||||
for i in 0 .. k {
|
||||
// create a nominator stash.
|
||||
let (n_stash, n_controller) = create_stash_controller::<T>(MAX_NOMINATIONS as u32 + i, 100, Default::default())?;
|
||||
let (n_stash, n_controller) = create_stash_controller::<T>(
|
||||
T::MAX_NOMINATIONS + i,
|
||||
100,
|
||||
Default::default(),
|
||||
)?;
|
||||
|
||||
// bake the nominations; we first clone them from the rest of the validators.
|
||||
let mut nominations = rest_of_validators.clone();
|
||||
@@ -256,9 +264,9 @@ benchmarks! {
|
||||
}
|
||||
}
|
||||
|
||||
// Worst case scenario, MAX_NOMINATIONS
|
||||
// Worst case scenario, T::MAX_NOMINATIONS
|
||||
nominate {
|
||||
let n in 1 .. MAX_NOMINATIONS as u32;
|
||||
let n in 1 .. T::MAX_NOMINATIONS;
|
||||
let (stash, controller) = create_stash_controller::<T>(n + 1, 100, Default::default())?;
|
||||
let validators = create_validators::<T>(n, 100)?;
|
||||
whitelist_account!(controller);
|
||||
@@ -467,7 +475,13 @@ benchmarks! {
|
||||
let v in 1 .. 10;
|
||||
let n in 1 .. 100;
|
||||
|
||||
create_validators_with_nominators_for_era::<T>(v, n, MAX_NOMINATIONS, false, None)?;
|
||||
create_validators_with_nominators_for_era::<T>(
|
||||
v,
|
||||
n,
|
||||
<T as Config>::MAX_NOMINATIONS as usize,
|
||||
false,
|
||||
None,
|
||||
)?;
|
||||
let session_index = SessionIndex::one();
|
||||
}: {
|
||||
let validators = Staking::<T>::new_era(session_index).ok_or("`new_era` failed")?;
|
||||
@@ -478,7 +492,13 @@ benchmarks! {
|
||||
payout_all {
|
||||
let v in 1 .. 10;
|
||||
let n in 1 .. 100;
|
||||
create_validators_with_nominators_for_era::<T>(v, n, MAX_NOMINATIONS, false, None)?;
|
||||
create_validators_with_nominators_for_era::<T>(
|
||||
v,
|
||||
n,
|
||||
<T as Config>::MAX_NOMINATIONS as usize,
|
||||
false,
|
||||
None,
|
||||
)?;
|
||||
// Start a new Era
|
||||
let new_validators = Staking::<T>::new_era(SessionIndex::one()).unwrap();
|
||||
assert!(new_validators.len() == v as usize);
|
||||
@@ -548,7 +568,7 @@ benchmarks! {
|
||||
// total number of slashing spans. Assigned to validators randomly.
|
||||
let s in 1 .. 20;
|
||||
|
||||
let validators = create_validators_with_nominators_for_era::<T>(v, n, MAX_NOMINATIONS, false, None)?
|
||||
let validators = create_validators_with_nominators_for_era::<T>(v, n, T::MAX_NOMINATIONS as usize, false, None)?
|
||||
.into_iter()
|
||||
.map(|v| T::Lookup::lookup(v).unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
@@ -567,7 +587,7 @@ benchmarks! {
|
||||
// number of nominator intention.
|
||||
let n = 500;
|
||||
|
||||
let _ = create_validators_with_nominators_for_era::<T>(v, n, MAX_NOMINATIONS, false, None)?;
|
||||
let _ = create_validators_with_nominators_for_era::<T>(v, n, T::MAX_NOMINATIONS as usize, false, None)?;
|
||||
}: {
|
||||
let targets = <Staking<T>>::get_npos_targets();
|
||||
assert_eq!(targets.len() as u32, v);
|
||||
@@ -586,8 +606,13 @@ mod tests {
|
||||
let v = 10;
|
||||
let n = 100;
|
||||
|
||||
create_validators_with_nominators_for_era::<Test>(v, n, MAX_NOMINATIONS, false, None)
|
||||
.unwrap();
|
||||
create_validators_with_nominators_for_era::<Test>(
|
||||
v,
|
||||
n,
|
||||
<Test as Config>::MAX_NOMINATIONS as usize,
|
||||
false,
|
||||
None,
|
||||
).unwrap();
|
||||
|
||||
let count_validators = Validators::<Test>::iter().count();
|
||||
let count_nominators = Nominators::<Test>::iter().count();
|
||||
|
||||
@@ -284,8 +284,7 @@ use sp_std::{
|
||||
result,
|
||||
prelude::*,
|
||||
collections::btree_map::BTreeMap,
|
||||
convert::{TryInto, From},
|
||||
mem::size_of,
|
||||
convert::From,
|
||||
};
|
||||
use codec::{HasCompact, Encode, Decode};
|
||||
use frame_support::{
|
||||
@@ -303,7 +302,7 @@ use frame_support::{
|
||||
};
|
||||
use pallet_session::historical;
|
||||
use sp_runtime::{
|
||||
Percent, Perbill, PerU16, RuntimeDebug, DispatchError,
|
||||
Percent, Perbill, RuntimeDebug, DispatchError,
|
||||
curve::PiecewiseLinear,
|
||||
traits::{
|
||||
Convert, Zero, StaticLookup, CheckedSub, Saturating, SaturatedConversion,
|
||||
@@ -337,22 +336,6 @@ macro_rules! log {
|
||||
};
|
||||
}
|
||||
|
||||
/// Data type used to index nominators in the compact type
|
||||
pub type NominatorIndex = u32;
|
||||
|
||||
/// Data type used to index validators in the compact type.
|
||||
pub type ValidatorIndex = u16;
|
||||
|
||||
// Ensure the size of both ValidatorIndex and NominatorIndex. They both need to be well below usize.
|
||||
static_assertions::const_assert!(size_of::<ValidatorIndex>() <= size_of::<usize>());
|
||||
static_assertions::const_assert!(size_of::<NominatorIndex>() <= size_of::<usize>());
|
||||
static_assertions::const_assert!(size_of::<ValidatorIndex>() <= size_of::<u32>());
|
||||
static_assertions::const_assert!(size_of::<NominatorIndex>() <= size_of::<u32>());
|
||||
|
||||
/// Maximum number of stakers that can be stored in a snapshot.
|
||||
pub const MAX_NOMINATIONS: usize =
|
||||
<CompactAssignments as sp_npos_elections::CompactSolution>::LIMIT;
|
||||
|
||||
pub const MAX_UNLOCKING_CHUNKS: usize = 32;
|
||||
|
||||
/// Counter for the number of eras that have passed.
|
||||
@@ -361,15 +344,6 @@ pub type EraIndex = u32;
|
||||
/// Counter for the number of "reward" points earned by a given validator.
|
||||
pub type RewardPoint = u32;
|
||||
|
||||
// Note: Maximum nomination limit is set here -- 16.
|
||||
sp_npos_elections::generate_solution_type!(
|
||||
#[compact]
|
||||
pub struct CompactAssignments::<NominatorIndex, ValidatorIndex, OffchainAccuracy>(16)
|
||||
);
|
||||
|
||||
/// Accuracy used for off-chain election. This better be small.
|
||||
pub type OffchainAccuracy = PerU16;
|
||||
|
||||
/// The balance type of this module.
|
||||
pub type BalanceOf<T> =
|
||||
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
|
||||
@@ -766,6 +740,9 @@ pub trait Config: frame_system::Config + SendTransactionTypes<Call<Self>> {
|
||||
DataProvider = Module<Self>,
|
||||
>;
|
||||
|
||||
/// Maximum number of nominations per nominator.
|
||||
const MAX_NOMINATIONS: u32;
|
||||
|
||||
/// Tokens have been minted and are unused for validator-reward.
|
||||
/// See [Era payout](./index.html#era-payout).
|
||||
type RewardRemainder: OnUnbalanced<NegativeImbalanceOf<Self>>;
|
||||
@@ -1213,6 +1190,9 @@ decl_module! {
|
||||
/// their reward. This used to limit the i/o cost for the nominator payout.
|
||||
const MaxNominatorRewardedPerValidator: u32 = T::MaxNominatorRewardedPerValidator::get();
|
||||
|
||||
/// Maximum number of nominations per nominator.
|
||||
const MaxNominations: u32 = T::MAX_NOMINATIONS;
|
||||
|
||||
type Error = Error<T>;
|
||||
|
||||
fn deposit_event() = default;
|
||||
@@ -1247,15 +1227,6 @@ decl_module! {
|
||||
T::BondingDuration::get(),
|
||||
)
|
||||
);
|
||||
|
||||
use sp_runtime::UpperOf;
|
||||
// 1. Maximum sum of Vec<OffchainAccuracy> must fit into `UpperOf<OffchainAccuracy>`.
|
||||
assert!(
|
||||
<usize as TryInto<UpperOf<OffchainAccuracy>>>::try_into(MAX_NOMINATIONS)
|
||||
.unwrap()
|
||||
.checked_mul(<OffchainAccuracy>::one().deconstruct().try_into().unwrap())
|
||||
.is_some()
|
||||
);
|
||||
}
|
||||
|
||||
/// Take the origin account as a stash and lock up `value` of its balance. `controller` will
|
||||
@@ -1547,7 +1518,7 @@ decl_module! {
|
||||
let ledger = Self::ledger(&controller).ok_or(Error::<T>::NotController)?;
|
||||
let stash = &ledger.stash;
|
||||
ensure!(!targets.is_empty(), Error::<T>::EmptyTargets);
|
||||
ensure!(targets.len() <= MAX_NOMINATIONS, Error::<T>::TooManyTargets);
|
||||
ensure!(targets.len() <= T::MAX_NOMINATIONS as usize, Error::<T>::TooManyTargets);
|
||||
|
||||
let old = Nominators::<T>::get(stash).map_or_else(Vec::new, |x| x.targets);
|
||||
|
||||
@@ -2313,7 +2284,7 @@ impl<T: Config> Module<T> {
|
||||
/// Returns `Err(())` if less than [`MinimumValidatorCount`] validators have been elected, `Ok`
|
||||
/// otherwise.
|
||||
pub fn process_election(
|
||||
flat_supports: sp_npos_elections::Supports<T::AccountId>,
|
||||
flat_supports: frame_election_provider_support::Supports<T::AccountId>,
|
||||
current_era: EraIndex,
|
||||
) -> Result<Vec<T::AccountId>, ()> {
|
||||
let exposures = Self::collect_exposures(flat_supports);
|
||||
@@ -2554,6 +2525,7 @@ impl<T: Config> Module<T> {
|
||||
impl<T: Config> frame_election_provider_support::ElectionDataProvider<T::AccountId, T::BlockNumber>
|
||||
for Module<T>
|
||||
{
|
||||
const MAXIMUM_VOTES_PER_VOTER: u32 = T::MAX_NOMINATIONS;
|
||||
fn desired_targets() -> data_provider::Result<(u32, Weight)> {
|
||||
Ok((Self::validator_count(), <T as frame_system::Config>::DbWeight::get().reads(1)))
|
||||
}
|
||||
|
||||
@@ -240,6 +240,7 @@ impl onchain::Config for Test {
|
||||
type DataProvider = Staking;
|
||||
}
|
||||
impl Config for Test {
|
||||
const MAX_NOMINATIONS: u32 = 16;
|
||||
type Currency = Balances;
|
||||
type UnixTime = Timestamp;
|
||||
type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote;
|
||||
|
||||
Reference in New Issue
Block a user