Rename all the election operations (#6245)

* Rename and move sp-phragmen

* More renames for equalise

* Update main module doc

* Fix line width

* Line width
This commit is contained in:
Kian Paimani
2020-06-05 17:33:13 +02:00
committed by GitHub
parent d63b8e0da0
commit 8a8b4f99c3
35 changed files with 296 additions and 322 deletions
+1 -1
View File
@@ -565,7 +565,7 @@ benchmarks! {
let caller: T::AccountId = account("caller", n, SEED);
let era = <Staking<T>>::current_era().unwrap_or(0);
// submit a seq-phragmen with all the good stuff on chain
// submit a seq-phragmen with all the good stuff on chain.
{
let (winners, compact, score, size) = get_seq_phragmen_solution::<T>(true);
assert!(
+75 -71
View File
@@ -25,25 +25,25 @@
//!
//! ## Overview
//!
//! The Staking module is the means by which a set of network maintainers (known as _authorities_
//! in some contexts and _validators_ in others) are chosen based upon those who voluntarily place
//! funds under deposit. Under deposit, those funds are rewarded under normal operation but are
//! held at pain of _slash_ (expropriation) should the staked maintainer be found not to be
//! discharging its duties properly.
//! The Staking module is the means by which a set of network maintainers (known as _authorities_ in
//! some contexts and _validators_ in others) are chosen based upon those who voluntarily place
//! funds under deposit. Under deposit, those funds are rewarded under normal operation but are held
//! at pain of _slash_ (expropriation) should the staked maintainer be found not to be discharging
//! its duties properly.
//!
//! ### Terminology
//! <!-- Original author of paragraph: @gavofyork -->
//!
//! - Staking: The process of locking up funds for some time, placing them at risk of slashing
//! (loss) in order to become a rewarded maintainer of the network.
//! (loss) in order to become a rewarded maintainer of the network.
//! - Validating: The process of running a node to actively maintain the network, either by
//! producing blocks or guaranteeing finality of the chain.
//! producing blocks or guaranteeing finality of the chain.
//! - Nominating: The process of placing staked funds behind one or more validators in order to
//! share in any reward, and punishment, they take.
//! share in any reward, and punishment, they take.
//! - Stash account: The account holding an owner's funds used for staking.
//! - Controller account: The account that controls an owner's funds for staking.
//! - Era: A (whole) number of sessions, which is the period that the validator set (and each
//! validator's active nominator set) is recalculated and where rewards are paid out.
//! validator's active nominator set) is recalculated and where rewards are paid out.
//! - Slash: The punishment of a staker by reducing its funds.
//!
//! ### Goals
@@ -106,10 +106,10 @@
//! valid behavior_ while _punishing any misbehavior or lack of availability_.
//!
//! Rewards must be claimed for each era before it gets too old by `$HISTORY_DEPTH` using the
//! `payout_stakers` call. Any account can call `payout_stakers`, which pays the reward to
//! the validator as well as its nominators.
//! Only the [`Trait::MaxNominatorRewardedPerValidator`] biggest stakers can claim their reward. This
//! is to limit the i/o cost to mutate storage for each nominator's account.
//! `payout_stakers` call. Any account can call `payout_stakers`, which pays the reward to the
//! validator as well as its nominators. Only the [`Trait::MaxNominatorRewardedPerValidator`]
//! biggest stakers can claim their reward. This is to limit the i/o cost to mutate storage for each
//! nominator's account.
//!
//! Slashing can occur at any point in time, once misbehavior is reported. Once slashing is
//! determined, a value is deducted from the balance of the validator and all the nominators who
@@ -118,8 +118,8 @@
//! Slashing logic is further described in the documentation of the `slashing` module.
//!
//! Similar to slashing, rewards are also shared among a validator and its associated nominators.
//! Yet, the reward funds are not always transferred to the stash account and can be configured.
//! See [Reward Calculation](#reward-calculation) for more details.
//! Yet, the reward funds are not always transferred to the stash account and can be configured. See
//! [Reward Calculation](#reward-calculation) for more details.
//!
//! #### Chilling
//!
@@ -157,15 +157,15 @@
//! pub trait Trait: staking::Trait {}
//!
//! decl_module! {
//! pub struct Module<T: Trait> for enum Call where origin: T::Origin {
//! /// Reward a validator.
//! #[weight = 0]
//! pub fn reward_myself(origin) -> dispatch::DispatchResult {
//! let reported = ensure_signed(origin)?;
//! <staking::Module<T>>::reward_by_ids(vec![(reported, 10)]);
//! Ok(())
//! }
//! }
//! pub struct Module<T: Trait> for enum Call where origin: T::Origin {
//! /// Reward a validator.
//! #[weight = 0]
//! pub fn reward_myself(origin) -> dispatch::DispatchResult {
//! let reported = ensure_signed(origin)?;
//! <staking::Module<T>>::reward_by_ids(vec![(reported, 10)]);
//! Ok(())
//! }
//! }
//! }
//! # fn main() { }
//! ```
@@ -208,8 +208,8 @@
//! The validator and its nominator split their reward as following:
//!
//! The validator can declare an amount, named
//! [`commission`](./struct.ValidatorPrefs.html#structfield.commission), that does not
//! get shared with the nominators at each reward payout through its
//! [`commission`](./struct.ValidatorPrefs.html#structfield.commission), that does not get shared
//! with the nominators at each reward payout through its
//! [`ValidatorPrefs`](./struct.ValidatorPrefs.html). This value gets deducted from the total reward
//! that is paid to the validator and its nominators. The remaining portion is split among the
//! validator and all of the nominators that nominated the validator, proportional to the value
@@ -218,8 +218,8 @@
//! [`others`](./struct.Exposure.html#structfield.others) by
//! [`total`](./struct.Exposure.html#structfield.total) in [`Exposure`](./struct.Exposure.html)).
//!
//! All entities who receive a reward have the option to choose their reward destination
//! through the [`Payee`](./struct.Payee.html) storage item (see
//! All entities who receive a reward have the option to choose their reward destination through the
//! [`Payee`](./struct.Payee.html) storage item (see
//! [`set_payee`](enum.Call.html#variant.set_payee)), to be one of the following:
//!
//! - Controller account, (obviously) not increasing the staked value.
@@ -244,9 +244,8 @@
//!
//! ### Election Algorithm
//!
//! The current election algorithm is implemented based on Phragmén.
//! The reference implementation can be found
//! [here](https://github.com/w3f/consensus/tree/master/NPoS).
//! The current election algorithm is implemented based on Phragmén. The reference implementation
//! can be found [here](https://github.com/w3f/consensus/tree/master/NPoS).
//!
//! The election algorithm, aside from electing the validators with the most stake value and votes,
//! tries to divide the nominator votes among candidates in an equal manner. To further assure this,
@@ -256,8 +255,8 @@
//!
//! ## GenesisConfig
//!
//! The Staking module depends on the [`GenesisConfig`](./struct.GenesisConfig.html).
//! The `GenesisConfig` is optional and allow to set some initial stakers.
//! The Staking module depends on the [`GenesisConfig`](./struct.GenesisConfig.html). The
//! `GenesisConfig` is optional and allow to set some initial stakers.
//!
//! ## Related Modules
//!
@@ -325,9 +324,10 @@ use frame_system::{
self as system, ensure_signed, ensure_root, ensure_none,
offchain::SendTransactionTypes,
};
use sp_phragmen::{
ExtendedBalance, Assignment, PhragmenScore, PhragmenResult, build_support_map, evaluate_support,
elect, generate_compact_solution_type, is_score_better, VotingLimit, SupportMap, VoteWeight,
use sp_npos_elections::{
ExtendedBalance, Assignment, ElectionScore, ElectionResult as PrimitiveElectionResult,
build_support_map, evaluate_support, seq_phragmen, generate_compact_solution_type,
is_score_better, VotingLimit, SupportMap, VoteWeight,
};
const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4;
@@ -383,10 +383,10 @@ pub struct ActiveEraInfo {
start: Option<u64>,
}
/// Accuracy used for on-chain phragmen.
/// Accuracy used for on-chain election.
pub type ChainAccuracy = Perbill;
/// Accuracy used for off-chain phragmen. This better be small.
/// Accuracy used for off-chain election. This better be small.
pub type OffchainAccuracy = PerU16;
/// The balance type of this module.
@@ -841,8 +841,9 @@ pub trait Trait: frame_system::Trait + SendTransactionTypes<Call<Self>> {
/// Convert a balance into a number used for election calculation. This must fit into a `u64`
/// but is allowed to be sensibly lossy. The `u64` is used to communicate with the
/// [`sp_phragmen`] crate which accepts u64 numbers and does operations in 128. Consequently,
/// the backward convert is used convert the u128s from phragmen back to a [`BalanceOf`].
/// [`sp_npos_elections`] crate which accepts u64 numbers and does operations in 128.
/// Consequently, the backward convert is used convert the u128s from sp-elections back to a
/// [`BalanceOf`].
type CurrencyToVote: Convert<BalanceOf<Self>, VoteWeight> + Convert<u128, BalanceOf<Self>>;
/// Tokens have been minted and are unused for validator-reward.
@@ -864,9 +865,9 @@ pub trait Trait: frame_system::Trait + SendTransactionTypes<Call<Self>> {
/// Number of eras that staked funds must remain bonded for.
type BondingDuration: Get<EraIndex>;
/// Number of eras that slashes are deferred by, after computation. This
/// should be less than the bonding duration. Set to 0 if slashes should be
/// applied immediately, without opportunity for intervention.
/// Number of eras that slashes are deferred by, after computation. This should be less than the
/// bonding duration. Set to 0 if slashes should be applied immediately, without opportunity for
/// intervention.
type SlashDeferDuration: Get<EraIndex>;
/// The origin which can cancel a deferred slash. Root can always do this.
@@ -882,16 +883,19 @@ pub trait Trait: frame_system::Trait + SendTransactionTypes<Call<Self>> {
/// Something that can estimate the next session change, accurately or as a best effort guess.
type NextNewSession: EstimateNextNewSession<Self::BlockNumber>;
/// How many blocks ahead of the era, within the last do we try to run the phragmen offchain?
/// The number of blocks before the end of the era from which election submissions are allowed.
/// Setting this to zero will disable the offchain compute and only on-chain seq-phragmen will
/// be used.
///
/// This is bounded by being within the last session. Hence, setting it to a value more than the
/// length of a session will be pointless.
type ElectionLookahead: Get<Self::BlockNumber>;
/// The overarching call type.
type Call: Dispatchable + From<Call<Self>> + IsSubType<Module<Self>, Self> + Clone;
/// Maximum number of equalise iterations to run in the offchain submission. If set to 0,
/// equalize will not be executed at all.
/// Maximum number of balancing iterations to run in the offchain submission. If set to 0,
/// balance_solution will not be executed at all.
type MaxIterations: Get<u32>;
/// The threshold of improvement that should be provided for a new solution to be accepted.
@@ -951,9 +955,9 @@ decl_storage! {
///
/// Information is kept for eras in `[current_era - history_depth; current_era]`.
///
/// Must be more than the number of eras delayed by session otherwise.
/// I.e. active era must always be in history.
/// I.e. `active_era > current_era - history_depth` must be guaranteed.
/// Must be more than the number of eras delayed by session otherwise. I.e. active era must
/// always be in history. I.e. `active_era > current_era - history_depth` must be
/// guaranteed.
HistoryDepth get(fn history_depth) config(): u32 = 84;
/// The ideal number of staking participants.
@@ -1113,7 +1117,7 @@ decl_storage! {
pub QueuedElected get(fn queued_elected): Option<ElectionResult<T::AccountId, BalanceOf<T>>>;
/// The score of the current [`QueuedElected`].
pub QueuedScore get(fn queued_score): Option<PhragmenScore>;
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.
@@ -1356,7 +1360,7 @@ decl_module! {
log!(debug, "skipping offchain worker in open election window due to [{}]", why);
} else {
if let Err(e) = compute_offchain_election::<T>() {
log!(error, "💸 Error in phragmen offchain worker: {:?}", e);
log!(error, "💸 Error in election offchain worker: {:?}", e);
} else {
log!(debug, "Executed offchain worker thread without errors.");
}
@@ -2067,7 +2071,7 @@ decl_module! {
T::Currency::remove_lock(STAKING_ID, &stash);
}
/// Submit a phragmen result to the chain. If the solution:
/// Submit an election result to the chain. If the solution:
///
/// 1. is valid.
/// 2. has a better score than a potentially existing solution on chain.
@@ -2080,7 +2084,7 @@ decl_module! {
/// 2. `assignments`: the compact version of an assignment vector that encodes the edge
/// weights.
///
/// Both of which may be computed using [`phragmen`], or any other algorithm.
/// Both of which may be computed using _phragmen_, or any other algorithm.
///
/// Additionally, the submitter must provide:
///
@@ -2119,7 +2123,7 @@ decl_module! {
origin,
winners: Vec<ValidatorIndex>,
compact: CompactAssignments,
score: PhragmenScore,
score: ElectionScore,
era: EraIndex,
size: ElectionSize,
) -> DispatchResultWithPostInfo {
@@ -2148,7 +2152,7 @@ decl_module! {
origin,
winners: Vec<ValidatorIndex>,
compact: CompactAssignments,
score: PhragmenScore,
score: ElectionScore,
era: EraIndex,
size: ElectionSize,
) -> DispatchResultWithPostInfo {
@@ -2413,7 +2417,7 @@ impl<T: Trait> Module<T> {
///
/// This function does weight refund in case of errors, which is based upon the fact that it is
/// called at the very beginning of the call site's function.
pub fn pre_dispatch_checks(score: PhragmenScore, era: EraIndex) -> DispatchResultWithPostInfo {
pub fn pre_dispatch_checks(score: ElectionScore, era: EraIndex) -> DispatchResultWithPostInfo {
// discard solutions that are not in-time
// check window open
ensure!(
@@ -2446,7 +2450,7 @@ impl<T: Trait> Module<T> {
winners: Vec<ValidatorIndex>,
compact_assignments: CompactAssignments,
compute: ElectionCompute,
claimed_score: PhragmenScore,
claimed_score: ElectionScore,
era: EraIndex,
election_size: ElectionSize,
) -> DispatchResultWithPostInfo {
@@ -2576,7 +2580,7 @@ impl<T: Trait> Module<T> {
}
// convert into staked assignments.
let staked_assignments = sp_phragmen::assignment_ratio_to_staked(
let staked_assignments = sp_npos_elections::assignment_ratio_to_staked(
assignments,
Self::slashable_balance_of_vote_weight,
);
@@ -2764,7 +2768,7 @@ impl<T: Trait> Module<T> {
elected_stashes,
exposures,
compute,
}) = Self::try_do_phragmen() {
}) = Self::try_do_election() {
// Totally close the election round and data.
Self::close_election_window();
@@ -2810,12 +2814,12 @@ impl<T: Trait> Module<T> {
}
/// Select a new validator set from the assembled stakers and their role preferences. It tries
/// first to peek into [`QueuedElected`]. Otherwise, it runs a new phragmen.
/// first to peek into [`QueuedElected`]. Otherwise, it runs a new on-chain phragmen election.
///
/// If [`QueuedElected`] and [`QueuedScore`] exists, they are both removed. No further storage
/// is updated.
fn try_do_phragmen() -> Option<ElectionResult<T::AccountId, BalanceOf<T>>> {
// a phragmen result from either a stored submission or locally executed one.
fn try_do_election() -> Option<ElectionResult<T::AccountId, BalanceOf<T>>> {
// an election result from either a stored submission or locally executed one.
let next_result = <QueuedElected<T>>::take().or_else(||
Self::do_phragmen_with_post_processing::<ChainAccuracy>(ElectionCompute::OnChain)
);
@@ -2827,11 +2831,11 @@ impl<T: Trait> Module<T> {
next_result
}
/// Execute phragmen and return the new results. The edge weights are processed into support
/// Execute election and return the new results. The edge weights are processed into support
/// values.
///
/// This is basically a wrapper around [`do_phragmen`] which translates `PhragmenResult` into
/// `ElectionResult`.
/// This is basically a wrapper around [`do_phragmen`] which translates
/// `PrimitiveElectionResult` into `ElectionResult`.
///
/// No storage item is updated.
fn do_phragmen_with_post_processing<Accuracy: PerThing>(compute: ElectionCompute)
@@ -2846,7 +2850,7 @@ impl<T: Trait> Module<T> {
.collect::<Vec<T::AccountId>>();
let assignments = phragmen_result.assignments;
let staked_assignments = sp_phragmen::assignment_ratio_to_staked(
let staked_assignments = sp_npos_elections::assignment_ratio_to_staked(
assignments,
Self::slashable_balance_of_vote_weight,
);
@@ -2877,13 +2881,13 @@ impl<T: Trait> Module<T> {
}
}
/// Execute phragmen and return the new results. No post-processing is applied and the raw edge
/// weights are returned.
/// Execute phragmen election and return the new results. No post-processing is applied and the
/// raw edge weights are returned.
///
/// Self votes are added and nominations before the most recent slashing span are reaped.
///
/// No storage item is updated.
fn do_phragmen<Accuracy: PerThing>() -> Option<PhragmenResult<T::AccountId, Accuracy>> {
fn do_phragmen<Accuracy: PerThing>() -> Option<PrimitiveElectionResult<T::AccountId, Accuracy>> {
let mut all_nominators: Vec<(T::AccountId, VoteWeight, Vec<T::AccountId>)> = Vec::new();
let mut all_validators = Vec::new();
for (validator, _) in <Validators<T>>::iter() {
@@ -2912,7 +2916,7 @@ impl<T: Trait> Module<T> {
(n, s, ns)
}));
elect::<_, Accuracy>(
seq_phragmen::<_, Accuracy>(
Self::validator_count() as usize,
Self::minimum_validator_count().max(1) as usize,
all_validators,
@@ -2920,7 +2924,7 @@ impl<T: Trait> Module<T> {
)
}
/// Consume a set of [`Supports`] from [`sp_phragmen`] and collect them into a [`Exposure`]
/// Consume a set of [`Supports`] from [`sp_npos_elections`] and collect them into a [`Exposure`]
fn collect_exposure(supports: SupportMap<T::AccountId>) -> Vec<(T::AccountId, Exposure<T::AccountId, BalanceOf<T>>)> {
let to_balance = |e: ExtendedBalance|
<T::CurrencyToVote as Convert<ExtendedBalance, BalanceOf<T>>>::convert(e);
+13 -13
View File
@@ -31,8 +31,8 @@ use frame_support::{
weights::{Weight, constants::RocksDbWeight},
};
use sp_io;
use sp_phragmen::{
build_support_map, evaluate_support, reduce, ExtendedBalance, StakedAssignment, PhragmenScore,
use sp_npos_elections::{
build_support_map, evaluate_support, reduce, ExtendedBalance, StakedAssignment, ElectionScore,
VoteWeight,
};
use crate::*;
@@ -783,7 +783,7 @@ pub(crate) fn add_slash(who: &AccountId) {
// distributed evenly.
pub(crate) fn horrible_phragmen_with_post_processing(
do_reduce: bool,
) -> (CompactAssignments, Vec<ValidatorIndex>, PhragmenScore) {
) -> (CompactAssignments, Vec<ValidatorIndex>, ElectionScore) {
let mut backing_stake_of: BTreeMap<AccountId, Balance> = BTreeMap::new();
// self stake
@@ -855,7 +855,7 @@ pub(crate) fn horrible_phragmen_with_post_processing(
let support = build_support_map::<AccountId>(&winners, &staked_assignment).0;
let score = evaluate_support(&support);
assert!(sp_phragmen::is_score_better::<Perbill>(
assert!(sp_npos_elections::is_score_better::<Perbill>(
better_score,
score,
MinSolutionScoreBump::get(),
@@ -879,7 +879,7 @@ pub(crate) fn horrible_phragmen_with_post_processing(
// convert back to ratio assignment. This takes less space.
let assignments_reduced =
sp_phragmen::assignment_staked_to_ratio::<AccountId, OffchainAccuracy>(staked_assignment);
sp_npos_elections::assignment_staked_to_ratio::<AccountId, OffchainAccuracy>(staked_assignment);
let compact =
CompactAssignments::from_assignment(assignments_reduced, nominator_index, validator_index)
@@ -897,13 +897,13 @@ pub(crate) fn prepare_submission_with(
do_reduce: bool,
iterations: usize,
tweak: impl FnOnce(&mut Vec<StakedAssignment<AccountId>>),
) -> (CompactAssignments, Vec<ValidatorIndex>, PhragmenScore) {
// run phragmen on the default stuff.
let sp_phragmen::PhragmenResult {
) -> (CompactAssignments, Vec<ValidatorIndex>, ElectionScore) {
// run election on the default stuff.
let sp_npos_elections::ElectionResult {
winners,
assignments,
} = Staking::do_phragmen::<OffchainAccuracy>().unwrap();
let winners = sp_phragmen::to_without_backing(winners);
let winners = sp_npos_elections::to_without_backing(winners);
let stake_of = |who: &AccountId| -> VoteWeight {
<CurrencyToVoteHandler as Convert<Balance, VoteWeight>>::convert(
@@ -911,11 +911,11 @@ pub(crate) fn prepare_submission_with(
)
};
let mut staked = sp_phragmen::assignment_ratio_to_staked(assignments, stake_of);
let mut staked = sp_npos_elections::assignment_ratio_to_staked(assignments, stake_of);
let (mut support_map, _) = build_support_map::<AccountId>(&winners, &staked);
if iterations > 0 {
sp_phragmen::equalize(
sp_npos_elections::balance_solution(
&mut staked,
&mut support_map,
Zero::zero(),
@@ -952,11 +952,11 @@ pub(crate) fn prepare_submission_with(
)
};
let assignments_reduced = sp_phragmen::assignment_staked_to_ratio(staked);
let assignments_reduced = sp_npos_elections::assignment_staked_to_ratio(staked);
// re-compute score by converting, yet again, into staked type
let score = {
let staked = sp_phragmen::assignment_ratio_to_staked(
let staked = sp_npos_elections::assignment_ratio_to_staked(
assignments_reduced.clone(),
Staking::slashable_balance_of_vote_weight,
);
@@ -23,9 +23,9 @@ use crate::{
ElectionSize,
};
use frame_system::offchain::SubmitTransaction;
use sp_phragmen::{
build_support_map, evaluate_support, reduce, Assignment, ExtendedBalance, PhragmenResult,
PhragmenScore, equalize,
use sp_npos_elections::{
build_support_map, evaluate_support, reduce, Assignment, ExtendedBalance, ElectionResult,
ElectionScore, balance_solution,
};
use sp_runtime::offchain::storage::StorageValueRef;
use sp_runtime::{PerThing, RuntimeDebug, traits::{TrailingZeroInput, Zero}};
@@ -35,22 +35,22 @@ use sp_std::{convert::TryInto, prelude::*};
/// Error types related to the offchain election machinery.
#[derive(RuntimeDebug)]
pub enum OffchainElectionError {
/// Phragmen election returned None. This means less candidate that minimum number of needed
/// election returned None. This means less candidate that minimum number of needed
/// validators were present. The chain is in trouble and not much that we can do about it.
ElectionFailed,
/// Submission to the transaction pool failed.
PoolSubmissionFailed,
/// The snapshot data is not available.
SnapshotUnavailable,
/// Error from phragmen crate. This usually relates to compact operation.
PhragmenError(sp_phragmen::Error),
/// Error from npos-election crate. This usually relates to compact operation.
InternalElectionError(sp_npos_elections::Error),
/// One of the computed winners is invalid.
InvalidWinner,
}
impl From<sp_phragmen::Error> for OffchainElectionError {
fn from(e: sp_phragmen::Error) -> Self {
Self::PhragmenError(e)
impl From<sp_npos_elections::Error> for OffchainElectionError {
fn from(e: sp_npos_elections::Error) -> Self {
Self::InternalElectionError(e)
}
}
@@ -107,7 +107,7 @@ pub(crate) fn set_check_offchain_execution_status<T: Trait>(
/// unsigned transaction, without any signature.
pub(crate) fn compute_offchain_election<T: Trait>() -> Result<(), OffchainElectionError> {
// compute raw solution. Note that we use `OffchainAccuracy`.
let PhragmenResult {
let ElectionResult {
winners,
assignments,
} = <Module<T>>::do_phragmen::<OffchainAccuracy>()
@@ -133,7 +133,7 @@ pub(crate) fn compute_offchain_election<T: Trait>() -> Result<(), OffchainElecti
}
/// Takes a phragmen result and spits out some data that can be submitted to the chain.
/// Takes an election result and spits out some data that can be submitted to the chain.
///
/// This does a lot of stuff; read the inline comments.
pub fn prepare_submission<T: Trait>(
@@ -143,7 +143,7 @@ pub fn prepare_submission<T: Trait>(
) -> Result<(
Vec<ValidatorIndex>,
CompactAssignments,
PhragmenScore,
ElectionScore,
ElectionSize,
), OffchainElectionError> where
ExtendedBalance: From<<OffchainAccuracy as PerThing>::Inner>,
@@ -169,26 +169,26 @@ pub fn prepare_submission<T: Trait>(
};
// Clean winners.
let winners = sp_phragmen::to_without_backing(winners);
let winners = sp_npos_elections::to_without_backing(winners);
// convert into absolute value and to obtain the reduced version.
let mut staked = sp_phragmen::assignment_ratio_to_staked(
let mut staked = sp_npos_elections::assignment_ratio_to_staked(
assignments,
<Module<T>>::slashable_balance_of_vote_weight,
);
let (mut support_map, _) = build_support_map::<T::AccountId>(&winners, &staked);
// equalize a random number of times.
// balance a random number of times.
let iterations_executed = match T::MaxIterations::get() {
0 => {
// Don't run equalize at all
// Don't run balance_solution at all
0
}
iterations @ _ => {
let seed = sp_io::offchain::random_seed();
let iterations = <u32>::decode(&mut TrailingZeroInput::new(seed.as_ref()))
.expect("input is padded with zeroes; qed") % iterations.saturating_add(1);
equalize(
balance_solution(
&mut staked,
&mut support_map,
Zero::zero(),
@@ -203,7 +203,7 @@ pub fn prepare_submission<T: Trait>(
}
// Convert back to ratio assignment. This takes less space.
let low_accuracy_assignment = sp_phragmen::assignment_staked_to_ratio(staked);
let low_accuracy_assignment = sp_npos_elections::assignment_staked_to_ratio(staked);
// convert back to staked to compute the score in the receiver's accuracy. This can be done
// nicer, for now we do it as such since this code is not time-critical. This ensure that the
@@ -214,7 +214,7 @@ pub fn prepare_submission<T: Trait>(
// assignment set is also all multiples of this value. After reduce, this no longer holds. Hence
// converting to ratio thereafter is not trivially reversible.
let score = {
let staked = sp_phragmen::assignment_ratio_to_staked(
let staked = sp_npos_elections::assignment_ratio_to_staked(
low_accuracy_assignment.clone(),
<Module<T>>::slashable_balance_of_vote_weight,
);
+5 -5
View File
@@ -24,7 +24,7 @@ use frame_benchmarking::{account};
use frame_system::RawOrigin;
use sp_io::hashing::blake2_256;
use rand_chacha::{rand_core::{RngCore, SeedableRng}, ChaChaRng};
use sp_phragmen::*;
use sp_npos_elections::*;
const SEED: u32 = 0;
@@ -138,7 +138,7 @@ pub fn create_validators_with_nominators_for_era<T: Trait>(
/// which has a less score than the seq-phragmen.
pub fn get_weak_solution<T: Trait>(
do_reduce: bool,
) -> (Vec<ValidatorIndex>, CompactAssignments, PhragmenScore, ElectionSize) {
) -> (Vec<ValidatorIndex>, CompactAssignments, ElectionScore, ElectionSize) {
let mut backing_stake_of: BTreeMap<T::AccountId, BalanceOf<T>> = BTreeMap::new();
// self stake
@@ -252,8 +252,8 @@ pub fn get_weak_solution<T: Trait>(
/// worker code.
pub fn get_seq_phragmen_solution<T: Trait>(
do_reduce: bool,
) -> (Vec<ValidatorIndex>, CompactAssignments, PhragmenScore, ElectionSize) {
let sp_phragmen::PhragmenResult {
) -> (Vec<ValidatorIndex>, CompactAssignments, ElectionScore, ElectionSize) {
let sp_npos_elections::ElectionResult {
winners,
assignments,
} = <Module<T>>::do_phragmen::<OffchainAccuracy>().unwrap();
@@ -264,7 +264,7 @@ pub fn get_seq_phragmen_solution<T: Trait>(
/// Returns a solution in which only one winner is elected with just a self vote.
pub fn get_single_winner_solution<T: Trait>(
winner: T::AccountId
) -> Result<(Vec<ValidatorIndex>, CompactAssignments, PhragmenScore, ElectionSize), &'static str> {
) -> Result<(Vec<ValidatorIndex>, CompactAssignments, ElectionScore, ElectionSize), &'static str> {
let snapshot_validators = <Module<T>>::snapshot_validators().unwrap();
let snapshot_nominators = <Module<T>>::snapshot_nominators().unwrap();
+4 -39
View File
@@ -406,41 +406,6 @@ fn no_candidate_emergency_condition() {
#[test]
fn nominating_and_rewards_should_work() {
// PHRAGMEN OUTPUT: running this test with the reference impl gives:
//
// Sequential Phragmén gives
// 10 is elected with stake 2200.0 and score 0.0003333333333333333
// 20 is elected with stake 1800.0 and score 0.0005555555555555556
// 10 has load 0.0003333333333333333 and supported
// 10 with stake 1000.0
// 20 has load 0.0005555555555555556 and supported
// 20 with stake 1000.0
// 30 has load 0 and supported
// 30 with stake 0
// 40 has load 0 and supported
// 40 with stake 0
// 2 has load 0.0005555555555555556 and supported
// 10 with stake 600.0 20 with stake 400.0 30 with stake 0.0
// 4 has load 0.0005555555555555556 and supported
// 10 with stake 600.0 20 with stake 400.0 40 with stake 0.0
// Sequential Phragmén with post processing gives
// 10 is elected with stake 2000.0 and score 0.0003333333333333333
// 20 is elected with stake 2000.0 and score 0.0005555555555555556
// 10 has load 0.0003333333333333333 and supported
// 10 with stake 1000.0
// 20 has load 0.0005555555555555556 and supported
// 20 with stake 1000.0
// 30 has load 0 and supported
// 30 with stake 0
// 40 has load 0 and supported
// 40 with stake 0
// 2 has load 0.0005555555555555556 and supported
// 10 with stake 400.0 20 with stake 600.0 30 with stake 0
// 4 has load 0.0005555555555555556 and supported
// 10 with stake 600.0 20 with stake 400.0 40 with stake 0.0
ExtBuilder::default()
.nominate(false)
.validator_pool(true)
@@ -477,7 +442,7 @@ fn nominating_and_rewards_should_work() {
mock::start_era(1);
// 10 and 20 have more votes, they will be chosen by phragmen.
// 10 and 20 have more votes, they will be chosen.
assert_eq_uvec!(validator_controllers(), vec![20, 10]);
// OLD validators must have already received some rewards.
@@ -2765,7 +2730,7 @@ mod offchain_phragmen {
OffchainExt, TransactionPoolExt,
};
use sp_io::TestExternalities;
use sp_phragmen::StakedAssignment;
use sp_npos_elections::StakedAssignment;
use frame_support::traits::OffchainWorker;
use std::sync::Arc;
use substrate_test_utils::assert_eq_uvec;
@@ -2822,7 +2787,7 @@ mod offchain_phragmen {
origin: Origin,
winners: Vec<ValidatorIndex>,
compact: CompactAssignments,
score: PhragmenScore,
score: ElectionScore,
) -> DispatchResultWithPostInfo {
Staking::submit_election_solution(
origin,
@@ -3355,7 +3320,7 @@ mod offchain_phragmen {
&inner,
),
TransactionValidity::Ok(ValidTransaction {
// the proposed slot stake, with equalize.
// the proposed slot stake, with balance_solution.
priority: UnsignedPriority::get() + 1250,
requires: vec![],
provides: vec![("StakingOffchain", active_era()).encode()],