mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 05:51:02 +00:00
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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user