mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 18:11:10 +00:00
Decouple Staking and Election - Part 2 Unsigned Phase (#7909)
* 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 * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_staking --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/staking/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Fix doc * Mkae ci green 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>
This commit is contained in:
@@ -328,15 +328,13 @@ use frame_system::{
|
||||
};
|
||||
use sp_npos_elections::{
|
||||
ExtendedBalance, Assignment, ElectionScore, ElectionResult as PrimitiveElectionResult,
|
||||
to_support_map, EvaluateSupport, seq_phragmen, generate_solution_type, is_score_better,
|
||||
SupportMap, VoteWeight, CompactSolution, PerThing128,
|
||||
to_supports, EvaluateSupport, seq_phragmen, generate_solution_type, is_score_better, Supports,
|
||||
VoteWeight, CompactSolution, PerThing128,
|
||||
};
|
||||
use sp_election_providers::ElectionProvider;
|
||||
pub use weights::WeightInfo;
|
||||
|
||||
const STAKING_ID: LockIdentifier = *b"staking ";
|
||||
pub const MAX_UNLOCKING_CHUNKS: usize = 32;
|
||||
pub const MAX_NOMINATIONS: usize = <CompactAssignments as CompactSolution>::LIMIT;
|
||||
|
||||
pub(crate) const LOG_TARGET: &'static str = "staking";
|
||||
|
||||
// syntactic sugar for logging.
|
||||
@@ -345,7 +343,7 @@ macro_rules! log {
|
||||
($level:tt, $patter:expr $(, $values:expr)* $(,)?) => {
|
||||
frame_support::debug::$level!(
|
||||
target: crate::LOG_TARGET,
|
||||
$patter $(, $values)*
|
||||
concat!("💸 ", $patter) $(, $values)*
|
||||
)
|
||||
};
|
||||
}
|
||||
@@ -365,6 +363,10 @@ static_assertions::const_assert!(size_of::<NominatorIndex>() <= size_of::<u32>()
|
||||
/// Maximum number of stakers that can be stored in a snapshot.
|
||||
pub(crate) const MAX_VALIDATORS: usize = ValidatorIndex::max_value() as usize;
|
||||
pub(crate) const MAX_NOMINATORS: usize = NominatorIndex::max_value() as usize;
|
||||
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.
|
||||
pub type EraIndex = u32;
|
||||
@@ -388,10 +390,12 @@ pub type OffchainAccuracy = PerU16;
|
||||
pub type BalanceOf<T> =
|
||||
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
|
||||
|
||||
type PositiveImbalanceOf<T> =
|
||||
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::PositiveImbalance;
|
||||
type NegativeImbalanceOf<T> =
|
||||
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;
|
||||
type PositiveImbalanceOf<T> = <<T as Config>::Currency as Currency<
|
||||
<T as frame_system::Config>::AccountId,
|
||||
>>::PositiveImbalance;
|
||||
type NegativeImbalanceOf<T> = <<T as Config>::Currency as Currency<
|
||||
<T as frame_system::Config>::AccountId,
|
||||
>>::NegativeImbalance;
|
||||
|
||||
/// Information regarding the active era (era in used in session).
|
||||
#[derive(Encode, Decode, RuntimeDebug)]
|
||||
@@ -778,7 +782,7 @@ impl<T: Config> SessionInterface<<T as frame_system::Config>::AccountId> for T w
|
||||
|
||||
pub trait Config: frame_system::Config + SendTransactionTypes<Call<Self>> {
|
||||
/// The staking balance.
|
||||
type Currency: LockableCurrency<Self::AccountId, Moment=Self::BlockNumber>;
|
||||
type Currency: LockableCurrency<Self::AccountId, Moment = Self::BlockNumber>;
|
||||
|
||||
/// Time used for computing era duration.
|
||||
///
|
||||
@@ -793,6 +797,14 @@ pub trait Config: frame_system::Config + SendTransactionTypes<Call<Self>> {
|
||||
/// [`BalanceOf`].
|
||||
type CurrencyToVote: CurrencyToVote<BalanceOf<Self>>;
|
||||
|
||||
/// Something that provides the election functionality.
|
||||
type ElectionProvider: sp_election_providers::ElectionProvider<
|
||||
Self::AccountId,
|
||||
Self::BlockNumber,
|
||||
// we only accept an election provider that has staking as data provider.
|
||||
DataProvider = Module<Self>,
|
||||
>;
|
||||
|
||||
/// Tokens have been minted and are unused for validator-reward.
|
||||
/// See [Era payout](./index.html#era-payout).
|
||||
type RewardRemainder: OnUnbalanced<NegativeImbalanceOf<Self>>;
|
||||
@@ -889,7 +901,9 @@ pub enum Forcing {
|
||||
}
|
||||
|
||||
impl Default for Forcing {
|
||||
fn default() -> Self { Forcing::NotForcing }
|
||||
fn default() -> Self {
|
||||
Forcing::NotForcing
|
||||
}
|
||||
}
|
||||
|
||||
// A value placed in storage that represents the current version of the Staking storage. This value
|
||||
@@ -1066,28 +1080,45 @@ decl_storage! {
|
||||
/// The earliest era for which we have a pending, unapplied slash.
|
||||
EarliestUnappliedSlash: Option<EraIndex>;
|
||||
|
||||
/// The last planned session scheduled by the session pallet.
|
||||
///
|
||||
/// This is basically in sync with the call to [`SessionManager::new_session`].
|
||||
pub CurrentPlannedSession get(fn current_planned_session): SessionIndex;
|
||||
|
||||
/// Snapshot of validators at the beginning of the current election window. This should only
|
||||
/// have a value when [`EraElectionStatus`] == `ElectionStatus::Open(_)`.
|
||||
///
|
||||
/// TWO_PHASE_NOTE: should be removed once we switch to multi-phase.
|
||||
pub SnapshotValidators get(fn snapshot_validators): Option<Vec<T::AccountId>>;
|
||||
|
||||
/// Snapshot of nominators at the beginning of the current election window. This should only
|
||||
/// have a value when [`EraElectionStatus`] == `ElectionStatus::Open(_)`.
|
||||
///
|
||||
/// TWO_PHASE_NOTE: should be removed once we switch to multi-phase.
|
||||
pub SnapshotNominators get(fn snapshot_nominators): Option<Vec<T::AccountId>>;
|
||||
|
||||
/// The next validator set. At the end of an era, if this is available (potentially from the
|
||||
/// result of an offchain worker), it is immediately used. Otherwise, the on-chain election
|
||||
/// is executed.
|
||||
///
|
||||
/// TWO_PHASE_NOTE: should be removed once we switch to multi-phase.
|
||||
pub QueuedElected get(fn queued_elected): Option<ElectionResult<T::AccountId, BalanceOf<T>>>;
|
||||
|
||||
/// The score of the current [`QueuedElected`].
|
||||
///
|
||||
/// TWO_PHASE_NOTE: should be removed once we switch to multi-phase.
|
||||
pub QueuedScore get(fn queued_score): Option<ElectionScore>;
|
||||
|
||||
/// Flag to control the execution of the offchain election. When `Open(_)`, we accept
|
||||
/// solutions to be submitted.
|
||||
///
|
||||
/// TWO_PHASE_NOTE: should be removed once we switch to multi-phase.
|
||||
pub EraElectionStatus get(fn era_election_status): ElectionStatus<T::BlockNumber>;
|
||||
|
||||
/// True if the current **planned** session is final. Note that this does not take era
|
||||
/// forcing into account.
|
||||
///
|
||||
/// TWO_PHASE_NOTE: should be removed once we switch to multi-phase.
|
||||
pub IsCurrentSessionFinal get(fn is_current_session_final): bool = false;
|
||||
|
||||
/// True if network has been upgraded to this version.
|
||||
@@ -1345,14 +1376,14 @@ decl_module! {
|
||||
ElectionStatus::<T::BlockNumber>::Open(now)
|
||||
);
|
||||
add_weight(0, 1, 0);
|
||||
log!(info, "💸 Election window is Open({:?}). Snapshot created", now);
|
||||
log!(info, "Election window is Open({:?}). Snapshot created", now);
|
||||
} else {
|
||||
log!(warn, "💸 Failed to create snapshot at {:?}.", now);
|
||||
log!(warn, "Failed to create snapshot at {:?}.", now);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log!(warn, "💸 Estimating next session change failed.");
|
||||
log!(warn, "Estimating next session change failed.");
|
||||
}
|
||||
add_weight(0, 0, T::NextNewSession::weight(now))
|
||||
}
|
||||
@@ -1367,16 +1398,15 @@ decl_module! {
|
||||
/// to open. If so, it runs the offchain worker code.
|
||||
fn offchain_worker(now: T::BlockNumber) {
|
||||
use offchain_election::{set_check_offchain_execution_status, compute_offchain_election};
|
||||
|
||||
if Self::era_election_status().is_open_at(now) {
|
||||
let offchain_status = set_check_offchain_execution_status::<T>(now);
|
||||
if let Err(why) = offchain_status {
|
||||
log!(warn, "💸 skipping offchain worker in open election window due to [{}]", why);
|
||||
log!(warn, "skipping offchain worker in open election window due to [{}]", why);
|
||||
} else {
|
||||
if let Err(e) = compute_offchain_election::<T>() {
|
||||
log!(error, "💸 Error in election offchain worker: {:?}", e);
|
||||
log!(error, "Error in election offchain worker: {:?}", e);
|
||||
} else {
|
||||
log!(debug, "💸 Executed offchain worker thread without errors.");
|
||||
log!(debug, "Executed offchain worker thread without errors.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2267,7 +2297,10 @@ impl<T: Config> Module<T> {
|
||||
}
|
||||
|
||||
/// Internal impl of [`Self::slashable_balance_of`] that returns [`VoteWeight`].
|
||||
pub fn slashable_balance_of_vote_weight(stash: &T::AccountId, issuance: BalanceOf<T>) -> VoteWeight {
|
||||
pub fn slashable_balance_of_vote_weight(
|
||||
stash: &T::AccountId,
|
||||
issuance: BalanceOf<T>,
|
||||
) -> VoteWeight {
|
||||
T::CurrencyToVote::to_vote(Self::slashable_balance_of(stash), issuance)
|
||||
}
|
||||
|
||||
@@ -2306,7 +2339,7 @@ impl<T: Config> Module<T> {
|
||||
{
|
||||
log!(
|
||||
warn,
|
||||
"💸 Snapshot size too big [{} <> {}][{} <> {}].",
|
||||
"Snapshot size too big [{} <> {}][{} <> {}].",
|
||||
num_validators,
|
||||
MAX_VALIDATORS,
|
||||
num_nominators,
|
||||
@@ -2330,10 +2363,7 @@ impl<T: Config> Module<T> {
|
||||
<SnapshotNominators<T>>::kill();
|
||||
}
|
||||
|
||||
fn do_payout_stakers(
|
||||
validator_stash: T::AccountId,
|
||||
era: EraIndex,
|
||||
) -> DispatchResult {
|
||||
fn do_payout_stakers(validator_stash: T::AccountId, era: EraIndex) -> DispatchResult {
|
||||
// Validate input data
|
||||
let current_era = CurrentEra::get().ok_or(Error::<T>::InvalidEraToReward)?;
|
||||
ensure!(era <= current_era, Error::<T>::InvalidEraToReward);
|
||||
@@ -2626,7 +2656,7 @@ impl<T: Config> Module<T> {
|
||||
validator_at,
|
||||
).map_err(|e| {
|
||||
// log the error since it is not propagated into the runtime error.
|
||||
log!(warn, "💸 un-compacting solution failed due to {:?}", e);
|
||||
log!(warn, "un-compacting solution failed due to {:?}", e);
|
||||
Error::<T>::OffchainElectionBogusCompact
|
||||
})?;
|
||||
|
||||
@@ -2641,7 +2671,7 @@ impl<T: Config> Module<T> {
|
||||
// all of the indices must map to either a validator or a nominator. If this is ever
|
||||
// not the case, then the locking system of staking is most likely faulty, or we
|
||||
// have bigger problems.
|
||||
log!(error, "💸 detected an error in the staking locking and snapshot.");
|
||||
log!(error, "detected an error in the staking locking and snapshot.");
|
||||
// abort.
|
||||
return Err(Error::<T>::OffchainElectionBogusNominator.into());
|
||||
}
|
||||
@@ -2690,7 +2720,7 @@ impl<T: Config> Module<T> {
|
||||
);
|
||||
|
||||
// build the support map thereof in order to evaluate.
|
||||
let supports = to_support_map::<T::AccountId>(&winners, &staked_assignments)
|
||||
let supports = to_supports(&winners, &staked_assignments)
|
||||
.map_err(|_| Error::<T>::OffchainElectionBogusEdge)?;
|
||||
|
||||
// Check if the score is the same as the claimed one.
|
||||
@@ -2698,10 +2728,11 @@ impl<T: Config> Module<T> {
|
||||
ensure!(submitted_score == claimed_score, Error::<T>::OffchainElectionBogusScore);
|
||||
|
||||
// At last, alles Ok. Exposures and store the result.
|
||||
let exposures = Self::collect_exposure(supports);
|
||||
let exposures = Self::collect_exposures(supports);
|
||||
log!(
|
||||
info,
|
||||
"💸 A better solution (with compute {:?} and score {:?}) has been validated and stored on chain.",
|
||||
"A better solution (with compute {:?} and score {:?}) has been validated and stored \
|
||||
on chain.",
|
||||
compute,
|
||||
submitted_score,
|
||||
);
|
||||
@@ -2834,6 +2865,8 @@ impl<T: Config> Module<T> {
|
||||
|
||||
// Set staking information for new era.
|
||||
let maybe_new_validators = Self::select_and_update_validators(current_era);
|
||||
// TWO_PHASE_NOTE: use this later on.
|
||||
let _unused_new_validators = Self::enact_election(current_era);
|
||||
|
||||
maybe_new_validators
|
||||
}
|
||||
@@ -2901,7 +2934,7 @@ impl<T: Config> Module<T> {
|
||||
|
||||
log!(
|
||||
info,
|
||||
"💸 new validator set of size {:?} has been elected via {:?} for era {:?}",
|
||||
"new validator set of size {:?} has been elected via {:?} for staring era {:?}",
|
||||
elected_stashes.len(),
|
||||
compute,
|
||||
current_era,
|
||||
@@ -2950,20 +2983,20 @@ impl<T: Config> Module<T> {
|
||||
Self::slashable_balance_of_fn(),
|
||||
);
|
||||
|
||||
let supports = to_support_map::<T::AccountId>(
|
||||
let supports = to_supports(
|
||||
&elected_stashes,
|
||||
&staked_assignments,
|
||||
)
|
||||
.map_err(|_|
|
||||
log!(
|
||||
error,
|
||||
"💸 on-chain phragmen is failing due to a problem in the result. This must be a bug."
|
||||
"on-chain phragmen is failing due to a problem in the result. This must be a bug."
|
||||
)
|
||||
)
|
||||
.ok()?;
|
||||
|
||||
// collect exposures
|
||||
let exposures = Self::collect_exposure(supports);
|
||||
let exposures = Self::collect_exposures(supports);
|
||||
|
||||
// In order to keep the property required by `on_session_ending` that we must return the
|
||||
// new validator set even if it's the same as the old, as long as any underlying
|
||||
@@ -3025,7 +3058,7 @@ impl<T: Config> Module<T> {
|
||||
// If we don't have enough candidates, nothing to do.
|
||||
log!(
|
||||
warn,
|
||||
"💸 Chain does not have enough staking candidates to operate. Era {:?}.",
|
||||
"chain does not have enough staking candidates to operate. Era {:?}.",
|
||||
Self::current_era()
|
||||
);
|
||||
None
|
||||
@@ -3041,9 +3074,10 @@ impl<T: Config> Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Consume a set of [`Supports`] from [`sp_npos_elections`] and collect them into a [`Exposure`]
|
||||
fn collect_exposure(
|
||||
supports: SupportMap<T::AccountId>,
|
||||
/// Consume a set of [`Supports`] from [`sp_npos_elections`] and collect them into a
|
||||
/// [`Exposure`].
|
||||
fn collect_exposures(
|
||||
supports: Supports<T::AccountId>,
|
||||
) -> Vec<(T::AccountId, Exposure<T::AccountId, BalanceOf<T>>)> {
|
||||
let total_issuance = T::Currency::total_issuance();
|
||||
let to_currency = |e: ExtendedBalance| T::CurrencyToVote::to_currency(e, total_issuance);
|
||||
@@ -3075,6 +3109,80 @@ impl<T: Config> Module<T> {
|
||||
}).collect::<Vec<(T::AccountId, Exposure<_, _>)>>()
|
||||
}
|
||||
|
||||
/// Process the output of the election.
|
||||
///
|
||||
/// This ensures enough validators have been elected, converts all supports to exposures and
|
||||
/// writes them to the associated storage.
|
||||
///
|
||||
/// Returns `Err(())` if less than [`MinimumValidatorCount`] validators have been elected, `Ok`
|
||||
/// otherwise.
|
||||
// TWO_PHASE_NOTE: remove the dead code.
|
||||
#[allow(dead_code)]
|
||||
pub fn process_election(
|
||||
flat_supports: sp_npos_elections::Supports<T::AccountId>,
|
||||
current_era: EraIndex,
|
||||
) -> Result<Vec<T::AccountId>, ()> {
|
||||
let exposures = Self::collect_exposures(flat_supports);
|
||||
let elected_stashes = exposures.iter().cloned().map(|(x, _)| x).collect::<Vec<_>>();
|
||||
|
||||
if (elected_stashes.len() as u32) <= Self::minimum_validator_count() {
|
||||
log!(
|
||||
warn,
|
||||
"chain does not have enough staking candidates to operate for era {:?}",
|
||||
current_era,
|
||||
);
|
||||
return Err(());
|
||||
}
|
||||
|
||||
// Populate Stakers and write slot stake.
|
||||
let mut total_stake: BalanceOf<T> = Zero::zero();
|
||||
exposures.into_iter().for_each(|(stash, exposure)| {
|
||||
total_stake = total_stake.saturating_add(exposure.total);
|
||||
<ErasStakers<T>>::insert(current_era, &stash, &exposure);
|
||||
|
||||
let mut exposure_clipped = exposure;
|
||||
let clipped_max_len = T::MaxNominatorRewardedPerValidator::get() as usize;
|
||||
if exposure_clipped.others.len() > clipped_max_len {
|
||||
exposure_clipped.others.sort_by(|a, b| a.value.cmp(&b.value).reverse());
|
||||
exposure_clipped.others.truncate(clipped_max_len);
|
||||
}
|
||||
<ErasStakersClipped<T>>::insert(¤t_era, &stash, exposure_clipped);
|
||||
});
|
||||
|
||||
// Insert current era staking information
|
||||
<ErasTotalStake<T>>::insert(¤t_era, total_stake);
|
||||
|
||||
// collect the pref of all winners
|
||||
for stash in &elected_stashes {
|
||||
let pref = Self::validators(stash);
|
||||
<ErasValidatorPrefs<T>>::insert(¤t_era, stash, pref);
|
||||
}
|
||||
|
||||
// emit event
|
||||
// TWO_PHASE_NOTE: remove the inner value.
|
||||
Self::deposit_event(RawEvent::StakingElection(ElectionCompute::Signed));
|
||||
|
||||
log!(
|
||||
info,
|
||||
"new validator set of size {:?} has been processed for era {:?}",
|
||||
elected_stashes.len(),
|
||||
current_era,
|
||||
);
|
||||
|
||||
Ok(elected_stashes)
|
||||
}
|
||||
|
||||
/// Enact and process the election using the `ElectionProvider` type.
|
||||
///
|
||||
/// This will also process the election, as noted in [`process_election`].
|
||||
fn enact_election(_current_era: EraIndex) -> Option<Vec<T::AccountId>> {
|
||||
let _outcome = T::ElectionProvider::elect().map(|_| ());
|
||||
log!(debug, "Experimental election provider outputted {:?}", _outcome);
|
||||
// TWO_PHASE_NOTE: This code path shall not return anything for now. Later on, redirect the
|
||||
// results to `process_election`.
|
||||
None
|
||||
}
|
||||
|
||||
/// Remove all associated data of a stash account from the staking system.
|
||||
///
|
||||
/// Assumes storage is upgraded before calling.
|
||||
@@ -3167,7 +3275,11 @@ impl<T: Config> Module<T> {
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
pub fn add_era_stakers(current_era: EraIndex, controller: T::AccountId, exposure: Exposure<T::AccountId, BalanceOf<T>>) {
|
||||
pub fn add_era_stakers(
|
||||
current_era: EraIndex,
|
||||
controller: T::AccountId,
|
||||
exposure: Exposure<T::AccountId, BalanceOf<T>>,
|
||||
) {
|
||||
<ErasStakers<T>>::insert(¤t_era, &controller, &exposure);
|
||||
}
|
||||
|
||||
@@ -3180,6 +3292,109 @@ impl<T: Config> Module<T> {
|
||||
pub fn set_slash_reward_fraction(fraction: Perbill) {
|
||||
SlashRewardFraction::put(fraction);
|
||||
}
|
||||
|
||||
/// Get all of the voters that are eligible for the npos election.
|
||||
///
|
||||
/// This will use all on-chain nominators, and all the validators will inject a self vote.
|
||||
///
|
||||
/// ### Slashing
|
||||
///
|
||||
/// All nominations that have been submitted before the last non-zero slash of the validator are
|
||||
/// auto-chilled.
|
||||
///
|
||||
/// Note that this is VERY expensive. Use with care.
|
||||
pub fn get_npos_voters() -> Vec<(T::AccountId, VoteWeight, Vec<T::AccountId>)> {
|
||||
let weight_of = Self::slashable_balance_of_fn();
|
||||
let mut all_voters = Vec::new();
|
||||
|
||||
for (validator, _) in <Validators<T>>::iter() {
|
||||
// append self vote
|
||||
let self_vote = (validator.clone(), weight_of(&validator), vec![validator.clone()]);
|
||||
all_voters.push(self_vote);
|
||||
}
|
||||
|
||||
for (nominator, nominations) in <Nominators<T>>::iter() {
|
||||
let Nominations { submitted_in, mut targets, suppressed: _ } = nominations;
|
||||
|
||||
// Filter out nomination targets which were nominated before the most recent
|
||||
// slashing span.
|
||||
targets.retain(|stash| {
|
||||
Self::slashing_spans(&stash)
|
||||
.map_or(true, |spans| submitted_in >= spans.last_nonzero_slash())
|
||||
});
|
||||
|
||||
let vote_weight = weight_of(&nominator);
|
||||
all_voters.push((nominator, vote_weight, targets))
|
||||
}
|
||||
|
||||
all_voters
|
||||
}
|
||||
|
||||
pub fn get_npos_targets() -> Vec<T::AccountId> {
|
||||
<Validators<T>>::iter().map(|(v, _)| v).collect::<Vec<_>>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> sp_election_providers::ElectionDataProvider<T::AccountId, T::BlockNumber>
|
||||
for Module<T>
|
||||
{
|
||||
fn desired_targets() -> u32 {
|
||||
Self::validator_count()
|
||||
}
|
||||
|
||||
fn voters() -> Vec<(T::AccountId, VoteWeight, Vec<T::AccountId>)> {
|
||||
Self::get_npos_voters()
|
||||
}
|
||||
|
||||
fn targets() -> Vec<T::AccountId> {
|
||||
Self::get_npos_targets()
|
||||
}
|
||||
|
||||
fn next_election_prediction(now: T::BlockNumber) -> T::BlockNumber {
|
||||
let current_era = Self::current_era().unwrap_or(0);
|
||||
let current_session = Self::current_planned_session();
|
||||
let current_era_start_session_index =
|
||||
Self::eras_start_session_index(current_era).unwrap_or(0);
|
||||
let era_length = current_session
|
||||
.saturating_sub(current_era_start_session_index)
|
||||
.min(T::SessionsPerEra::get());
|
||||
|
||||
let session_length = T::NextNewSession::average_session_length();
|
||||
|
||||
let until_this_session_end = T::NextNewSession::estimate_next_new_session(now)
|
||||
.unwrap_or_default()
|
||||
.saturating_sub(now);
|
||||
|
||||
let sessions_left: T::BlockNumber = T::SessionsPerEra::get()
|
||||
.saturating_sub(era_length)
|
||||
// one session is computed in this_session_end.
|
||||
.saturating_sub(1)
|
||||
.into();
|
||||
|
||||
now.saturating_add(
|
||||
until_this_session_end.saturating_add(sessions_left.saturating_mul(session_length)),
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "runtime-benchmarks", test))]
|
||||
fn put_snapshot(
|
||||
voters: Vec<(T::AccountId, VoteWeight, Vec<T::AccountId>)>,
|
||||
targets: Vec<T::AccountId>,
|
||||
) {
|
||||
targets.into_iter().for_each(|v| {
|
||||
<Validators<T>>::insert(
|
||||
v,
|
||||
ValidatorPrefs { commission: Perbill::zero(), blocked: false },
|
||||
);
|
||||
});
|
||||
|
||||
voters.into_iter().for_each(|(v, _s, t)| {
|
||||
<Nominators<T>>::insert(
|
||||
v,
|
||||
Nominations { targets: t, submitted_in: 0, suppressed: false },
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// In this implementation `new_session(session)` must be called before `end_session(session-1)`
|
||||
@@ -3195,6 +3410,7 @@ impl<T: Config> pallet_session::SessionManager<T::AccountId> for Module<T> {
|
||||
<frame_system::Module<T>>::block_number(),
|
||||
new_index
|
||||
);
|
||||
CurrentPlannedSession::put(new_index);
|
||||
Self::new_session(new_index)
|
||||
}
|
||||
fn start_session(start_index: SessionIndex) {
|
||||
@@ -3217,10 +3433,12 @@ impl<T: Config> pallet_session::SessionManager<T::AccountId> for Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> historical::SessionManager<T::AccountId, Exposure<T::AccountId, BalanceOf<T>>> for Module<T> {
|
||||
fn new_session(new_index: SessionIndex)
|
||||
-> Option<Vec<(T::AccountId, Exposure<T::AccountId, BalanceOf<T>>)>>
|
||||
{
|
||||
impl<T: Config> historical::SessionManager<T::AccountId, Exposure<T::AccountId, BalanceOf<T>>>
|
||||
for Module<T>
|
||||
{
|
||||
fn new_session(
|
||||
new_index: SessionIndex,
|
||||
) -> Option<Vec<(T::AccountId, Exposure<T::AccountId, BalanceOf<T>>)>> {
|
||||
<Self as pallet_session::SessionManager<_>>::new_session(new_index).map(|validators| {
|
||||
let current_era = Self::current_era()
|
||||
// Must be some as a new era has been created.
|
||||
@@ -3245,8 +3463,8 @@ impl<T: Config> historical::SessionManager<T::AccountId, Exposure<T::AccountId,
|
||||
/// * 2 points to the block producer for each reference to a previously unreferenced uncle, and
|
||||
/// * 1 point to the producer of each referenced uncle block.
|
||||
impl<T> pallet_authorship::EventHandler<T::AccountId, T::BlockNumber> for Module<T>
|
||||
where
|
||||
T: Config + pallet_authorship::Config + pallet_session::Config
|
||||
where
|
||||
T: Config + pallet_authorship::Config + pallet_session::Config,
|
||||
{
|
||||
fn note_author(author: T::AccountId) {
|
||||
Self::reward_by_ids(vec![(author, 20)])
|
||||
@@ -3289,9 +3507,10 @@ impl<T: Config> Convert<T::AccountId, Option<Exposure<T::AccountId, BalanceOf<T>
|
||||
}
|
||||
|
||||
/// This is intended to be used with `FilterHistoricalOffences`.
|
||||
impl <T: Config>
|
||||
impl<T: Config>
|
||||
OnOffenceHandler<T::AccountId, pallet_session::historical::IdentificationTuple<T>, Weight>
|
||||
for Module<T> where
|
||||
for Module<T>
|
||||
where
|
||||
T: pallet_session::Config<ValidatorId = <T as frame_system::Config>::AccountId>,
|
||||
T: pallet_session::historical::Config<
|
||||
FullIdentification = Exposure<<T as frame_system::Config>::AccountId, BalanceOf<T>>,
|
||||
@@ -3305,12 +3524,15 @@ for Module<T> where
|
||||
>,
|
||||
{
|
||||
fn on_offence(
|
||||
offenders: &[OffenceDetails<T::AccountId, pallet_session::historical::IdentificationTuple<T>>],
|
||||
offenders: &[OffenceDetails<
|
||||
T::AccountId,
|
||||
pallet_session::historical::IdentificationTuple<T>,
|
||||
>],
|
||||
slash_fraction: &[Perbill],
|
||||
slash_session: SessionIndex,
|
||||
) -> Result<Weight, ()> {
|
||||
if !Self::can_report() {
|
||||
return Err(())
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let reward_proportion = SlashRewardFraction::get();
|
||||
@@ -3421,6 +3643,7 @@ for Module<T> where
|
||||
}
|
||||
|
||||
fn can_report() -> bool {
|
||||
// TWO_PHASE_NOTE: we can get rid of this API
|
||||
Self::era_election_status().is_closed()
|
||||
}
|
||||
}
|
||||
@@ -3431,7 +3654,8 @@ pub struct FilterHistoricalOffences<T, R> {
|
||||
}
|
||||
|
||||
impl<T, Reporter, Offender, R, O> ReportOffence<Reporter, Offender, O>
|
||||
for FilterHistoricalOffences<Module<T>, R> where
|
||||
for FilterHistoricalOffences<Module<T>, R>
|
||||
where
|
||||
T: Config,
|
||||
R: ReportOffence<Reporter, Offender, O>,
|
||||
O: Offence<Offender>,
|
||||
@@ -3488,7 +3712,7 @@ impl<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
|
||||
return invalid.into();
|
||||
}
|
||||
|
||||
log!(debug, "💸 validateUnsigned succeeded for a solution at era {}.", era);
|
||||
log!(debug, "validateUnsigned succeeded for a solution at era {}.", era);
|
||||
|
||||
ValidTransaction::with_tag_prefix("StakingOffchain")
|
||||
// The higher the score[0], the better a solution is.
|
||||
|
||||
@@ -28,7 +28,7 @@ use frame_support::{
|
||||
use sp_core::H256;
|
||||
use sp_io;
|
||||
use sp_npos_elections::{
|
||||
to_support_map, EvaluateSupport, reduce, ExtendedBalance, StakedAssignment, ElectionScore,
|
||||
to_supports, reduce, ExtendedBalance, StakedAssignment, ElectionScore, EvaluateSupport,
|
||||
};
|
||||
use sp_runtime::{
|
||||
curve::PiecewiseLinear,
|
||||
@@ -37,6 +37,7 @@ use sp_runtime::{
|
||||
};
|
||||
use sp_staking::offence::{OffenceDetails, OnOffenceHandler};
|
||||
use std::{cell::RefCell, collections::HashSet};
|
||||
use sp_election_providers::onchain;
|
||||
|
||||
pub const INIT_TIMESTAMP: u64 = 30_000;
|
||||
pub const BLOCK_TIME: u64 = 1000;
|
||||
@@ -239,6 +240,12 @@ impl OnUnbalanced<NegativeImbalanceOf<Test>> for RewardRemainderMock {
|
||||
}
|
||||
}
|
||||
|
||||
impl onchain::Config for Test {
|
||||
type AccountId = AccountId;
|
||||
type BlockNumber = BlockNumber;
|
||||
type Accuracy = Perbill;
|
||||
type DataProvider = Staking;
|
||||
}
|
||||
impl Config for Test {
|
||||
type Currency = Balances;
|
||||
type UnixTime = Timestamp;
|
||||
@@ -261,6 +268,7 @@ impl Config for Test {
|
||||
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
|
||||
type UnsignedPriority = UnsignedPriority;
|
||||
type OffchainSolutionWeightLimit = OffchainSolutionWeightLimit;
|
||||
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
@@ -760,7 +768,7 @@ pub(crate) fn add_slash(who: &AccountId) {
|
||||
on_offence_now(
|
||||
&[
|
||||
OffenceDetails {
|
||||
offender: (who.clone(), Staking::eras_stakers(Staking::active_era().unwrap().index, who.clone())),
|
||||
offender: (who.clone(), Staking::eras_stakers(active_era(), who.clone())),
|
||||
reporters: vec![],
|
||||
},
|
||||
],
|
||||
@@ -841,7 +849,7 @@ pub(crate) fn horrible_npos_solution(
|
||||
let score = {
|
||||
let (_, _, better_score) = prepare_submission_with(true, true, 0, |_| {});
|
||||
|
||||
let support = to_support_map::<AccountId>(&winners, &staked_assignment).unwrap();
|
||||
let support = to_supports::<AccountId>(&winners, &staked_assignment).unwrap();
|
||||
let score = support.evaluate();
|
||||
|
||||
assert!(sp_npos_elections::is_score_better::<Perbill>(
|
||||
@@ -941,7 +949,7 @@ pub(crate) fn prepare_submission_with(
|
||||
Staking::slashable_balance_of_fn(),
|
||||
);
|
||||
|
||||
let support_map = to_support_map::<AccountId>(
|
||||
let support_map = to_supports(
|
||||
winners.as_slice(),
|
||||
staked.as_slice(),
|
||||
).unwrap();
|
||||
@@ -962,9 +970,8 @@ pub(crate) fn prepare_submission_with(
|
||||
|
||||
/// Make all validator and nominator request their payment
|
||||
pub(crate) fn make_all_reward_payment(era: EraIndex) {
|
||||
let validators_with_reward = ErasRewardPoints::<Test>::get(era).individual.keys()
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
let validators_with_reward =
|
||||
ErasRewardPoints::<Test>::get(era).individual.keys().cloned().collect::<Vec<_>>();
|
||||
|
||||
// reward validators
|
||||
for validator_controller in validators_with_reward.iter().filter_map(Staking::bonded) {
|
||||
@@ -988,10 +995,10 @@ macro_rules! assert_session_era {
|
||||
$session,
|
||||
);
|
||||
assert_eq!(
|
||||
Staking::active_era().unwrap().index,
|
||||
Staking::current_era().unwrap(),
|
||||
$era,
|
||||
"wrong active era {} != {}",
|
||||
Staking::active_era().unwrap().index,
|
||||
"wrong current era {} != {}",
|
||||
Staking::current_era().unwrap(),
|
||||
$era,
|
||||
);
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@ use codec::Decode;
|
||||
use frame_support::{traits::Get, weights::Weight, IterableStorageMap};
|
||||
use frame_system::offchain::SubmitTransaction;
|
||||
use sp_npos_elections::{
|
||||
to_support_map, EvaluateSupport, reduce, Assignment, ElectionResult, ElectionScore,
|
||||
to_supports, EvaluateSupport, reduce, Assignment, ElectionResult, ElectionScore,
|
||||
ExtendedBalance, CompactSolution,
|
||||
};
|
||||
use sp_runtime::{
|
||||
@@ -127,7 +127,7 @@ pub(crate) fn compute_offchain_election<T: Config>() -> Result<(), OffchainElect
|
||||
|
||||
crate::log!(
|
||||
info,
|
||||
"💸 prepared a seq-phragmen solution with {} balancing iterations and score {:?}",
|
||||
"prepared a seq-phragmen solution with {} balancing iterations and score {:?}",
|
||||
iters,
|
||||
score,
|
||||
);
|
||||
@@ -284,7 +284,7 @@ where
|
||||
if compact.remove_voter(index) {
|
||||
crate::log!(
|
||||
trace,
|
||||
"💸 removed a voter at index {} with stake {:?} from compact to reduce the size",
|
||||
"removed a voter at index {} with stake {:?} from compact to reduce the size",
|
||||
index,
|
||||
_stake,
|
||||
);
|
||||
@@ -297,19 +297,17 @@ where
|
||||
}
|
||||
|
||||
crate::log!(
|
||||
warn,
|
||||
"💸 {} nominators out of {} had to be removed from compact solution due to size limits.",
|
||||
removed,
|
||||
compact.voter_count() + removed,
|
||||
);
|
||||
warn,
|
||||
"{} nominators out of {} had to be removed from compact solution due to size \
|
||||
limits.",
|
||||
removed,
|
||||
compact.voter_count() + removed,
|
||||
);
|
||||
Ok(compact)
|
||||
}
|
||||
_ => {
|
||||
// nada, return as-is
|
||||
crate::log!(
|
||||
info,
|
||||
"💸 Compact solution did not get trimmed due to block weight limits.",
|
||||
);
|
||||
crate::log!(info, "Compact solution did not get trimmed due to block weight limits.",);
|
||||
Ok(compact)
|
||||
}
|
||||
}
|
||||
@@ -390,13 +388,16 @@ pub fn prepare_submission<T: Config>(
|
||||
let maximum_allowed_voters =
|
||||
maximum_compact_len::<T::WeightInfo>(winners.len() as u32, size, maximum_weight);
|
||||
|
||||
crate::log!(debug, "💸 Maximum weight = {:?} // current weight = {:?} // maximum voters = {:?} // current votes = {:?}",
|
||||
crate::log!(
|
||||
debug,
|
||||
"Maximum weight = {:?} // current weight = {:?} // maximum voters = {:?} // current votes \
|
||||
= {:?}",
|
||||
maximum_weight,
|
||||
T::WeightInfo::submit_solution_better(
|
||||
size.validators.into(),
|
||||
size.nominators.into(),
|
||||
compact.voter_count() as u32,
|
||||
winners.len() as u32,
|
||||
size.validators.into(),
|
||||
size.nominators.into(),
|
||||
compact.voter_count() as u32,
|
||||
winners.len() as u32,
|
||||
),
|
||||
maximum_allowed_voters,
|
||||
compact.voter_count(),
|
||||
@@ -415,7 +416,7 @@ pub fn prepare_submission<T: Config>(
|
||||
<Module<T>>::slashable_balance_of_fn(),
|
||||
);
|
||||
|
||||
let support_map = to_support_map::<T::AccountId>(&winners, &staked)
|
||||
let support_map = to_supports::<T::AccountId>(&winners, &staked)
|
||||
.map_err(|_| OffchainElectionError::ElectionFailed)?;
|
||||
support_map.evaluate()
|
||||
};
|
||||
|
||||
@@ -247,7 +247,7 @@ pub fn get_weak_solution<T: Config>(
|
||||
);
|
||||
|
||||
let support_map =
|
||||
to_support_map::<T::AccountId>(winners.as_slice(), staked.as_slice()).unwrap();
|
||||
to_supports::<T::AccountId>(winners.as_slice(), staked.as_slice()).unwrap();
|
||||
support_map.evaluate()
|
||||
};
|
||||
|
||||
|
||||
@@ -1833,6 +1833,7 @@ fn bond_with_duplicate_vote_should_be_ignored_by_npos_election() {
|
||||
}
|
||||
|
||||
assert_ok!(Staking::bond(Origin::signed(1), 2, 1000, RewardDestination::Controller));
|
||||
// 11 should not be elected. All of these count as ONE vote.
|
||||
assert_ok!(Staking::nominate(Origin::signed(2), vec![11, 11, 11, 21, 31,]));
|
||||
|
||||
assert_ok!(Staking::bond(Origin::signed(3), 4, 1000, RewardDestination::Controller));
|
||||
@@ -1886,7 +1887,6 @@ fn bond_with_duplicate_vote_should_be_ignored_by_npos_election_elected() {
|
||||
assert_ok!(Staking::nominate(Origin::signed(4), vec![21, 31]));
|
||||
|
||||
// winners should be 21 and 31. Otherwise this election is taking duplicates into account.
|
||||
|
||||
let sp_npos_elections::ElectionResult {
|
||||
winners,
|
||||
assignments,
|
||||
@@ -2029,7 +2029,7 @@ fn reward_from_authorship_event_handler_works() {
|
||||
fn add_reward_points_fns_works() {
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
// Not mandatory but must be coherent with rewards
|
||||
assert_eq!(Session::validators(), vec![21, 11]);
|
||||
assert_eq_uvec!(Session::validators(), vec![21, 11]);
|
||||
|
||||
<Module<Test>>::reward_by_ids(vec![
|
||||
(21, 1),
|
||||
@@ -3048,7 +3048,7 @@ mod offchain_election {
|
||||
assert_eq!(Staking::era_election_status(), ElectionStatus::Open(37));
|
||||
|
||||
run_to_block(40);
|
||||
assert_session_era!(4, 0);
|
||||
assert_session_era!(4, 1);
|
||||
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
|
||||
assert!(Staking::snapshot_nominators().is_none());
|
||||
assert!(Staking::snapshot_validators().is_none());
|
||||
@@ -3066,7 +3066,7 @@ mod offchain_election {
|
||||
assert!(Staking::snapshot_validators().is_some());
|
||||
|
||||
run_to_block(90);
|
||||
assert_session_era!(9, 1);
|
||||
assert_session_era!(9, 2);
|
||||
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
|
||||
assert!(Staking::snapshot_nominators().is_none());
|
||||
assert!(Staking::snapshot_validators().is_none());
|
||||
@@ -5015,3 +5015,92 @@ fn do_not_die_when_active_is_ed() {
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
mod election_data_provider {
|
||||
use super::*;
|
||||
use sp_election_providers::ElectionDataProvider;
|
||||
|
||||
#[test]
|
||||
fn voters_include_self_vote() {
|
||||
ExtBuilder::default().nominate(false).build().execute_with(|| {
|
||||
assert!(<Validators<Test>>::iter().map(|(x, _)| x).all(|v| Staking::voters()
|
||||
.into_iter()
|
||||
.find(|(w, _, t)| { v == *w && t[0] == *w })
|
||||
.is_some()))
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn voters_exclude_slashed() {
|
||||
ExtBuilder::default().build().execute_with(|| {
|
||||
assert_eq!(Staking::nominators(101).unwrap().targets, vec![11, 21]);
|
||||
assert_eq!(
|
||||
<Staking as ElectionDataProvider<AccountId, BlockNumber>>::voters()
|
||||
.iter()
|
||||
.find(|x| x.0 == 101)
|
||||
.unwrap()
|
||||
.2,
|
||||
vec![11, 21]
|
||||
);
|
||||
|
||||
start_active_era(1);
|
||||
add_slash(&11);
|
||||
|
||||
// 11 is gone.
|
||||
start_active_era(2);
|
||||
assert_eq!(
|
||||
<Staking as ElectionDataProvider<AccountId, BlockNumber>>::voters()
|
||||
.iter()
|
||||
.find(|x| x.0 == 101)
|
||||
.unwrap()
|
||||
.2,
|
||||
vec![21]
|
||||
);
|
||||
|
||||
// resubmit and it is back
|
||||
assert_ok!(Staking::nominate(Origin::signed(100), vec![11, 21]));
|
||||
assert_eq!(
|
||||
<Staking as ElectionDataProvider<AccountId, BlockNumber>>::voters()
|
||||
.iter()
|
||||
.find(|x| x.0 == 101)
|
||||
.unwrap()
|
||||
.2,
|
||||
vec![11, 21]
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn estimate_next_election_works() {
|
||||
ExtBuilder::default().session_per_era(5).period(5).build().execute_with(|| {
|
||||
// first session is always length 0.
|
||||
for b in 1..20 {
|
||||
run_to_block(b);
|
||||
assert_eq!(Staking::next_election_prediction(System::block_number()), 20);
|
||||
}
|
||||
|
||||
// election
|
||||
run_to_block(20);
|
||||
assert_eq!(Staking::next_election_prediction(System::block_number()), 45);
|
||||
assert_eq!(staking_events().len(), 1);
|
||||
assert_eq!(
|
||||
*staking_events().last().unwrap(),
|
||||
RawEvent::StakingElection(ElectionCompute::OnChain)
|
||||
);
|
||||
|
||||
for b in 21..45 {
|
||||
run_to_block(b);
|
||||
assert_eq!(Staking::next_election_prediction(System::block_number()), 45);
|
||||
}
|
||||
|
||||
// election
|
||||
run_to_block(45);
|
||||
assert_eq!(Staking::next_election_prediction(System::block_number()), 70);
|
||||
assert_eq!(staking_events().len(), 3);
|
||||
assert_eq!(
|
||||
*staking_events().last().unwrap(),
|
||||
RawEvent::StakingElection(ElectionCompute::OnChain)
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
//! Autogenerated weights for pallet_staking
|
||||
//!
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.1
|
||||
//! DATE: 2021-01-19, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: []
|
||||
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
|
||||
//! DATE: 2021-02-13, STEPS: [50, ], REPEAT: 20, LOW RANGE: [], HIGH RANGE: []
|
||||
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128
|
||||
|
||||
// Executed Command:
|
||||
@@ -75,171 +75,171 @@ pub trait WeightInfo {
|
||||
pub struct SubstrateWeight<T>(PhantomData<T>);
|
||||
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
|
||||
fn bond() -> Weight {
|
||||
(76_281_000 as Weight)
|
||||
(81_642_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(5 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn bond_extra() -> Weight {
|
||||
(62_062_000 as Weight)
|
||||
(66_025_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn unbond() -> Weight {
|
||||
(57_195_000 as Weight)
|
||||
(60_810_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(5 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn withdraw_unbonded_update(s: u32, ) -> Weight {
|
||||
(58_043_000 as Weight)
|
||||
(61_537_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((52_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add((60_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(5 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn withdraw_unbonded_kill(s: u32, ) -> Weight {
|
||||
(89_920_000 as Weight)
|
||||
// Standard Error: 3_000
|
||||
.saturating_add((2_526_000 as Weight).saturating_mul(s as Weight))
|
||||
(95_741_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((2_754_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(7 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(8 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight)))
|
||||
}
|
||||
fn validate() -> Weight {
|
||||
(20_228_000 as Weight)
|
||||
(21_009_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn kick(k: u32, ) -> Weight {
|
||||
(31_066_000 as Weight)
|
||||
// Standard Error: 11_000
|
||||
.saturating_add((17_754_000 as Weight).saturating_mul(k as Weight))
|
||||
(31_832_000 as Weight)
|
||||
// Standard Error: 15_000
|
||||
.saturating_add((19_418_000 as Weight).saturating_mul(k as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(k as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(k as Weight)))
|
||||
}
|
||||
fn nominate(n: u32, ) -> Weight {
|
||||
(33_494_000 as Weight)
|
||||
// Standard Error: 23_000
|
||||
.saturating_add((5_253_000 as Weight).saturating_mul(n as Weight))
|
||||
(34_304_000 as Weight)
|
||||
// Standard Error: 20_000
|
||||
.saturating_add((5_643_000 as Weight).saturating_mul(n as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(n as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn chill() -> Weight {
|
||||
(19_396_000 as Weight)
|
||||
(20_103_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn set_payee() -> Weight {
|
||||
(13_449_000 as Weight)
|
||||
(13_858_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_controller() -> Weight {
|
||||
(29_184_000 as Weight)
|
||||
(30_269_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn set_validator_count() -> Weight {
|
||||
(2_266_000 as Weight)
|
||||
(2_444_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_no_eras() -> Weight {
|
||||
(2_462_000 as Weight)
|
||||
(2_766_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_new_era() -> Weight {
|
||||
(2_483_000 as Weight)
|
||||
(2_724_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_new_era_always() -> Weight {
|
||||
(2_495_000 as Weight)
|
||||
(2_702_000 as Weight)
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_invulnerables(v: u32, ) -> Weight {
|
||||
(2_712_000 as Weight)
|
||||
(2_914_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((9_000 as Weight).saturating_mul(v as Weight))
|
||||
.saturating_add((35_000 as Weight).saturating_mul(v as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_unstake(s: u32, ) -> Weight {
|
||||
(60_508_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((2_525_000 as Weight).saturating_mul(s as Weight))
|
||||
(64_032_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((2_787_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(8 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight)))
|
||||
}
|
||||
fn cancel_deferred_slash(s: u32, ) -> Weight {
|
||||
(5_886_772_000 as Weight)
|
||||
// Standard Error: 393_000
|
||||
.saturating_add((34_849_000 as Weight).saturating_mul(s as Weight))
|
||||
(5_903_394_000 as Weight)
|
||||
// Standard Error: 391_000
|
||||
.saturating_add((34_834_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn payout_stakers_dead_controller(n: u32, ) -> Weight {
|
||||
(127_627_000 as Weight)
|
||||
// Standard Error: 27_000
|
||||
.saturating_add((49_354_000 as Weight).saturating_mul(n as Weight))
|
||||
(141_724_000 as Weight)
|
||||
// Standard Error: 24_000
|
||||
.saturating_add((53_018_000 as Weight).saturating_mul(n as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(11 as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(n as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(n as Weight)))
|
||||
}
|
||||
fn payout_stakers_alive_staked(n: u32, ) -> Weight {
|
||||
(156_838_000 as Weight)
|
||||
// Standard Error: 24_000
|
||||
.saturating_add((62_653_000 as Weight).saturating_mul(n as Weight))
|
||||
(159_994_000 as Weight)
|
||||
// Standard Error: 28_000
|
||||
.saturating_add((67_746_000 as Weight).saturating_mul(n as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(12 as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((5 as Weight).saturating_mul(n as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes(3 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(n as Weight)))
|
||||
}
|
||||
fn rebond(l: u32, ) -> Weight {
|
||||
(40_110_000 as Weight)
|
||||
(42_177_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((78_000 as Weight).saturating_mul(l as Weight))
|
||||
.saturating_add((82_000 as Weight).saturating_mul(l as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn set_history_depth(e: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 70_000
|
||||
.saturating_add((32_883_000 as Weight).saturating_mul(e as Weight))
|
||||
// Standard Error: 65_000
|
||||
.saturating_add((34_151_000 as Weight).saturating_mul(e as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes((7 as Weight).saturating_mul(e as Weight)))
|
||||
}
|
||||
fn reap_stash(s: u32, ) -> Weight {
|
||||
(64_605_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((2_506_000 as Weight).saturating_mul(s as Weight))
|
||||
(68_377_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((2_757_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(8 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes((1 as Weight).saturating_mul(s as Weight)))
|
||||
}
|
||||
fn new_era(v: u32, n: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 926_000
|
||||
.saturating_add((548_212_000 as Weight).saturating_mul(v as Weight))
|
||||
// Standard Error: 46_000
|
||||
.saturating_add((78_343_000 as Weight).saturating_mul(n as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(7 as Weight))
|
||||
// Standard Error: 908_000
|
||||
.saturating_add((588_562_000 as Weight).saturating_mul(v as Weight))
|
||||
// Standard Error: 45_000
|
||||
.saturating_add((83_485_000 as Weight).saturating_mul(n as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(9 as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(v as Weight)))
|
||||
.saturating_add(T::DbWeight::get().reads((3 as Weight).saturating_mul(n as Weight)))
|
||||
.saturating_add(T::DbWeight::get().writes(8 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes(13 as Weight))
|
||||
.saturating_add(T::DbWeight::get().writes((3 as Weight).saturating_mul(v as Weight)))
|
||||
}
|
||||
fn submit_solution_better(v: u32, n: u32, a: u32, w: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 48_000
|
||||
.saturating_add((937_000 as Weight).saturating_mul(v as Weight))
|
||||
// Standard Error: 19_000
|
||||
.saturating_add((657_000 as Weight).saturating_mul(n as Weight))
|
||||
// Standard Error: 48_000
|
||||
.saturating_add((70_669_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 101_000
|
||||
.saturating_add((7_658_000 as Weight).saturating_mul(w as Weight))
|
||||
// Standard Error: 52_000
|
||||
.saturating_add((750_000 as Weight).saturating_mul(v as Weight))
|
||||
// Standard Error: 20_000
|
||||
.saturating_add((556_000 as Weight).saturating_mul(n as Weight))
|
||||
// Standard Error: 52_000
|
||||
.saturating_add((76_201_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 108_000
|
||||
.saturating_add((7_271_000 as Weight).saturating_mul(w as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads(6 as Weight))
|
||||
.saturating_add(T::DbWeight::get().reads((4 as Weight).saturating_mul(a as Weight)))
|
||||
.saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(w as Weight)))
|
||||
@@ -250,171 +250,171 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
|
||||
// For backwards compatibility and tests
|
||||
impl WeightInfo for () {
|
||||
fn bond() -> Weight {
|
||||
(76_281_000 as Weight)
|
||||
(81_642_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
|
||||
}
|
||||
fn bond_extra() -> Weight {
|
||||
(62_062_000 as Weight)
|
||||
(66_025_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn unbond() -> Weight {
|
||||
(57_195_000 as Weight)
|
||||
(60_810_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn withdraw_unbonded_update(s: u32, ) -> Weight {
|
||||
(58_043_000 as Weight)
|
||||
(61_537_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((52_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add((60_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(5 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn withdraw_unbonded_kill(s: u32, ) -> Weight {
|
||||
(89_920_000 as Weight)
|
||||
// Standard Error: 3_000
|
||||
.saturating_add((2_526_000 as Weight).saturating_mul(s as Weight))
|
||||
(95_741_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((2_754_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(7 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(8 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(s as Weight)))
|
||||
}
|
||||
fn validate() -> Weight {
|
||||
(20_228_000 as Weight)
|
||||
(21_009_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn kick(k: u32, ) -> Weight {
|
||||
(31_066_000 as Weight)
|
||||
// Standard Error: 11_000
|
||||
.saturating_add((17_754_000 as Weight).saturating_mul(k as Weight))
|
||||
(31_832_000 as Weight)
|
||||
// Standard Error: 15_000
|
||||
.saturating_add((19_418_000 as Weight).saturating_mul(k as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(k as Weight)))
|
||||
.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(k as Weight)))
|
||||
}
|
||||
fn nominate(n: u32, ) -> Weight {
|
||||
(33_494_000 as Weight)
|
||||
// Standard Error: 23_000
|
||||
.saturating_add((5_253_000 as Weight).saturating_mul(n as Weight))
|
||||
(34_304_000 as Weight)
|
||||
// Standard Error: 20_000
|
||||
.saturating_add((5_643_000 as Weight).saturating_mul(n as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(n as Weight)))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn chill() -> Weight {
|
||||
(19_396_000 as Weight)
|
||||
(20_103_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
|
||||
}
|
||||
fn set_payee() -> Weight {
|
||||
(13_449_000 as Weight)
|
||||
(13_858_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_controller() -> Weight {
|
||||
(29_184_000 as Weight)
|
||||
(30_269_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().reads(3 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn set_validator_count() -> Weight {
|
||||
(2_266_000 as Weight)
|
||||
(2_444_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_no_eras() -> Weight {
|
||||
(2_462_000 as Weight)
|
||||
(2_766_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_new_era() -> Weight {
|
||||
(2_483_000 as Weight)
|
||||
(2_724_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_new_era_always() -> Weight {
|
||||
(2_495_000 as Weight)
|
||||
(2_702_000 as Weight)
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn set_invulnerables(v: u32, ) -> Weight {
|
||||
(2_712_000 as Weight)
|
||||
(2_914_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((9_000 as Weight).saturating_mul(v as Weight))
|
||||
.saturating_add((35_000 as Weight).saturating_mul(v as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn force_unstake(s: u32, ) -> Weight {
|
||||
(60_508_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((2_525_000 as Weight).saturating_mul(s as Weight))
|
||||
(64_032_000 as Weight)
|
||||
// Standard Error: 2_000
|
||||
.saturating_add((2_787_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(8 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(s as Weight)))
|
||||
}
|
||||
fn cancel_deferred_slash(s: u32, ) -> Weight {
|
||||
(5_886_772_000 as Weight)
|
||||
// Standard Error: 393_000
|
||||
.saturating_add((34_849_000 as Weight).saturating_mul(s as Weight))
|
||||
(5_903_394_000 as Weight)
|
||||
// Standard Error: 391_000
|
||||
.saturating_add((34_834_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
|
||||
}
|
||||
fn payout_stakers_dead_controller(n: u32, ) -> Weight {
|
||||
(127_627_000 as Weight)
|
||||
// Standard Error: 27_000
|
||||
.saturating_add((49_354_000 as Weight).saturating_mul(n as Weight))
|
||||
(141_724_000 as Weight)
|
||||
// Standard Error: 24_000
|
||||
.saturating_add((53_018_000 as Weight).saturating_mul(n as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(11 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(n as Weight)))
|
||||
.saturating_add(RocksDbWeight::get().writes(2 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(n as Weight)))
|
||||
}
|
||||
fn payout_stakers_alive_staked(n: u32, ) -> Weight {
|
||||
(156_838_000 as Weight)
|
||||
// Standard Error: 24_000
|
||||
.saturating_add((62_653_000 as Weight).saturating_mul(n as Weight))
|
||||
(159_994_000 as Weight)
|
||||
// Standard Error: 28_000
|
||||
.saturating_add((67_746_000 as Weight).saturating_mul(n as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(12 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads((5 as Weight).saturating_mul(n as Weight)))
|
||||
.saturating_add(RocksDbWeight::get().writes(3 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(n as Weight)))
|
||||
}
|
||||
fn rebond(l: u32, ) -> Weight {
|
||||
(40_110_000 as Weight)
|
||||
(42_177_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((78_000 as Weight).saturating_mul(l as Weight))
|
||||
.saturating_add((82_000 as Weight).saturating_mul(l as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(3 as Weight))
|
||||
}
|
||||
fn set_history_depth(e: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 70_000
|
||||
.saturating_add((32_883_000 as Weight).saturating_mul(e as Weight))
|
||||
// Standard Error: 65_000
|
||||
.saturating_add((34_151_000 as Weight).saturating_mul(e as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(2 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(4 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes((7 as Weight).saturating_mul(e as Weight)))
|
||||
}
|
||||
fn reap_stash(s: u32, ) -> Weight {
|
||||
(64_605_000 as Weight)
|
||||
// Standard Error: 1_000
|
||||
.saturating_add((2_506_000 as Weight).saturating_mul(s as Weight))
|
||||
(68_377_000 as Weight)
|
||||
// Standard Error: 0
|
||||
.saturating_add((2_757_000 as Weight).saturating_mul(s as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(4 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(8 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes((1 as Weight).saturating_mul(s as Weight)))
|
||||
}
|
||||
fn new_era(v: u32, n: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 926_000
|
||||
.saturating_add((548_212_000 as Weight).saturating_mul(v as Weight))
|
||||
// Standard Error: 46_000
|
||||
.saturating_add((78_343_000 as Weight).saturating_mul(n as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(7 as Weight))
|
||||
// Standard Error: 908_000
|
||||
.saturating_add((588_562_000 as Weight).saturating_mul(v as Weight))
|
||||
// Standard Error: 45_000
|
||||
.saturating_add((83_485_000 as Weight).saturating_mul(n as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(9 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(v as Weight)))
|
||||
.saturating_add(RocksDbWeight::get().reads((3 as Weight).saturating_mul(n as Weight)))
|
||||
.saturating_add(RocksDbWeight::get().writes(8 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes(13 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().writes((3 as Weight).saturating_mul(v as Weight)))
|
||||
}
|
||||
fn submit_solution_better(v: u32, n: u32, a: u32, w: u32, ) -> Weight {
|
||||
(0 as Weight)
|
||||
// Standard Error: 48_000
|
||||
.saturating_add((937_000 as Weight).saturating_mul(v as Weight))
|
||||
// Standard Error: 19_000
|
||||
.saturating_add((657_000 as Weight).saturating_mul(n as Weight))
|
||||
// Standard Error: 48_000
|
||||
.saturating_add((70_669_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 101_000
|
||||
.saturating_add((7_658_000 as Weight).saturating_mul(w as Weight))
|
||||
// Standard Error: 52_000
|
||||
.saturating_add((750_000 as Weight).saturating_mul(v as Weight))
|
||||
// Standard Error: 20_000
|
||||
.saturating_add((556_000 as Weight).saturating_mul(n as Weight))
|
||||
// Standard Error: 52_000
|
||||
.saturating_add((76_201_000 as Weight).saturating_mul(a as Weight))
|
||||
// Standard Error: 108_000
|
||||
.saturating_add((7_271_000 as Weight).saturating_mul(w as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads(6 as Weight))
|
||||
.saturating_add(RocksDbWeight::get().reads((4 as Weight).saturating_mul(a as Weight)))
|
||||
.saturating_add(RocksDbWeight::get().reads((1 as Weight).saturating_mul(w as Weight)))
|
||||
|
||||
Reference in New Issue
Block a user