From 252b146b43e3877aefae6afd5c9a9e6093c5d7a9 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 5 Jun 2020 17:33:13 +0200 Subject: [PATCH] Rename all the election operations (#6245) * Rename and move sp-phragmen * More renames for equalise * Update main module doc * Fix line width * Line width --- .maintain/rename-crates-for-2.0.sh | 2 +- Cargo.lock | 54 +++---- Cargo.toml | 6 +- bin/node/runtime/src/lib.rs | 4 +- docs/CODEOWNERS | 2 +- frame/elections-phragmen/Cargo.toml | 6 +- frame/elections-phragmen/src/lib.rs | 18 +-- frame/staking/Cargo.toml | 4 +- frame/staking/fuzzer/Cargo.lock | 10 +- frame/staking/fuzzer/Cargo.toml | 2 +- frame/staking/src/benchmarking.rs | 2 +- frame/staking/src/lib.rs | 146 +++++++++--------- frame/staking/src/mock.rs | 26 ++-- frame/staking/src/offchain_election.rs | 38 ++--- frame/staking/src/testing_utils.rs | 10 +- frame/staking/src/tests.rs | 43 +----- primitives/arithmetic/src/rational128.rs | 2 +- .../{phragmen => npos-elections}/Cargo.toml | 8 +- .../benches/phragmen.rs | 24 ++- .../compact/Cargo.toml | 4 +- .../compact/src/assignment.rs | 8 +- .../compact/src/lib.rs | 12 +- .../compact/src/staked.rs | 4 +- .../fuzzer/.gitignore | 0 .../fuzzer/Cargo.lock | 10 +- .../fuzzer/Cargo.toml | 10 +- .../fuzzer/src/balance_solution.rs} | 25 +-- .../fuzzer/src/common.rs | 0 .../fuzzer/src/reduce.rs | 2 +- .../src/helpers.rs | 2 +- .../{phragmen => npos-elections}/src/lib.rs | 65 ++++---- .../{phragmen => npos-elections}/src/mock.rs | 6 +- .../{phragmen => npos-elections}/src/node.rs | 0 .../src/reduce.rs | 0 .../{phragmen => npos-elections}/src/tests.rs | 39 ++--- 35 files changed, 284 insertions(+), 310 deletions(-) rename primitives/{phragmen => npos-elections}/Cargo.toml (81%) rename primitives/{phragmen => npos-elections}/benches/phragmen.rs (92%) rename primitives/{phragmen => npos-elections}/compact/Cargo.toml (85%) rename primitives/{phragmen => npos-elections}/compact/src/assignment.rs (97%) rename primitives/{phragmen => npos-elections}/compact/src/lib.rs (95%) rename primitives/{phragmen => npos-elections}/compact/src/staked.rs (97%) rename primitives/{phragmen => npos-elections}/fuzzer/.gitignore (100%) rename primitives/{phragmen => npos-elections}/fuzzer/Cargo.lock (99%) rename primitives/{phragmen => npos-elections}/fuzzer/Cargo.toml (74%) rename primitives/{phragmen/fuzzer/src/equalize.rs => npos-elections/fuzzer/src/balance_solution.rs} (87%) rename primitives/{phragmen => npos-elections}/fuzzer/src/common.rs (100%) rename primitives/{phragmen => npos-elections}/fuzzer/src/reduce.rs (98%) rename primitives/{phragmen => npos-elections}/src/helpers.rs (98%) rename primitives/{phragmen => npos-elections}/src/lib.rs (92%) rename primitives/{phragmen => npos-elections}/src/mock.rs (98%) rename primitives/{phragmen => npos-elections}/src/node.rs (100%) rename primitives/{phragmen => npos-elections}/src/reduce.rs (100%) rename primitives/{phragmen => npos-elections}/src/tests.rs (95%) diff --git a/.maintain/rename-crates-for-2.0.sh b/.maintain/rename-crates-for-2.0.sh index 5d873d26cdfca..01d559448438b 100755 --- a/.maintain/rename-crates-for-2.0.sh +++ b/.maintain/rename-crates-for-2.0.sh @@ -64,7 +64,7 @@ TO_RENAME=( "substrate-keyring sp-keyring" "substrate-offchain-primitives sp-offchain" "substrate-panic-handler sp-panic-handler" - "substrate-phragmen sp-phragmen" + "substrate-phragmen sp-npos-elections" "substrate-rpc-primitives sp-rpc" "substrate-runtime-interface sp-runtime-interface" "substrate-runtime-interface-proc-macro sp-runtime-interface-proc-macro" diff --git a/Cargo.lock b/Cargo.lock index 2e7fbb14cf9e9..0ad5033f139df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4044,7 +4044,7 @@ dependencies = [ "serde", "sp-core", "sp-io", - "sp-phragmen", + "sp-npos-elections", "sp-runtime", "sp-std", "substrate-test-utils", @@ -4435,7 +4435,7 @@ dependencies = [ "sp-application-crypto", "sp-core", "sp-io", - "sp-phragmen", + "sp-npos-elections", "sp-runtime", "sp-staking", "sp-std", @@ -4460,7 +4460,7 @@ dependencies = [ "parity-scale-codec", "sp-core", "sp-io", - "sp-phragmen", + "sp-npos-elections", "sp-runtime", "sp-std", ] @@ -7474,40 +7474,22 @@ dependencies = [ ] [[package]] -name = "sp-offchain" -version = "2.0.0-rc2" -dependencies = [ - "sp-api", - "sp-core", - "sp-runtime", - "sp-state-machine", -] - -[[package]] -name = "sp-panic-handler" -version = "2.0.0-rc2" -dependencies = [ - "backtrace", - "log", -] - -[[package]] -name = "sp-phragmen" +name = "sp-npos-elections" version = "2.0.0-rc2" dependencies = [ "parity-scale-codec", "rand 0.7.3", "serde", "sp-arithmetic", - "sp-phragmen", - "sp-phragmen-compact", + "sp-npos-elections", + "sp-npos-elections-compact", "sp-runtime", "sp-std", "substrate-test-utils", ] [[package]] -name = "sp-phragmen-compact" +name = "sp-npos-elections-compact" version = "2.0.0-rc2" dependencies = [ "proc-macro-crate", @@ -7517,16 +7499,34 @@ dependencies = [ ] [[package]] -name = "sp-phragmen-fuzzer" +name = "sp-npos-elections-fuzzer" version = "2.0.0-alpha.5" dependencies = [ "honggfuzz", "rand 0.7.3", - "sp-phragmen", + "sp-npos-elections", "sp-runtime", "sp-std", ] +[[package]] +name = "sp-offchain" +version = "2.0.0-rc2" +dependencies = [ + "sp-api", + "sp-core", + "sp-runtime", + "sp-state-machine", +] + +[[package]] +name = "sp-panic-handler" +version = "2.0.0-rc2" +dependencies = [ + "backtrace", + "log", +] + [[package]] name = "sp-rpc" version = "2.0.0-rc2" diff --git a/Cargo.toml b/Cargo.toml index d367302f797f3..650124877cc87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -137,9 +137,9 @@ members = [ "primitives/keyring", "primitives/offchain", "primitives/panic-handler", - "primitives/phragmen", - "primitives/phragmen/fuzzer", - "primitives/phragmen/compact", + "primitives/npos-elections", + "primitives/npos-elections/fuzzer", + "primitives/npos-elections/compact", "primitives/rpc", "primitives/runtime-interface", "primitives/runtime-interface/proc-macro", diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 7a036ddf5f1ed..148b4199d10b8 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -470,7 +470,7 @@ parameter_types! { pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect"; } -// Make sure that there are no more than `MAX_MEMBERS` members elected via phragmen. +// Make sure that there are no more than `MAX_MEMBERS` members elected via elections-phragmen. const_assert!(DesiredMembers::get() <= pallet_collective::MAX_MEMBERS); impl pallet_elections_phragmen::Trait for Runtime { @@ -580,7 +580,7 @@ impl pallet_sudo::Trait for Runtime { parameter_types! { pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_SLOTS as _; pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value(); - /// We prioritize im-online heartbeats over phragmen solution submission. + /// We prioritize im-online heartbeats over election solution submission. pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2; } diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index 7559a9ee2b27f..2e1557b4ea5d8 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -67,7 +67,7 @@ /frame/staking/ @kianenigma /frame/elections/ @kianenigma /frame/elections-phragmen/ @kianenigma -/primitives/phragmen/ @kianenigma +/primitives/npos-elections/ @kianenigma # Fixed point arithmetic /primitives/sp-arithmetic/ @kianenigma diff --git a/frame/elections-phragmen/Cargo.toml b/frame/elections-phragmen/Cargo.toml index bea1e0dfc4173..81833abf85164 100644 --- a/frame/elections-phragmen/Cargo.toml +++ b/frame/elections-phragmen/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -description = "FRAME election pallet for PHRAGMEN" +description = "FRAME pallet based on seq-Phragmén election method." [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] @@ -15,7 +15,7 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true } sp-runtime = { version = "2.0.0-rc2", default-features = false, path = "../../primitives/runtime" } -sp-phragmen = { version = "2.0.0-rc2", default-features = false, path = "../../primitives/phragmen" } +sp-npos-elections = { version = "2.0.0-rc2", default-features = false, path = "../../primitives/npos-elections" } frame-support = { version = "2.0.0-rc2", default-features = false, path = "../support" } frame-system = { version = "2.0.0-rc2", default-features = false, path = "../system" } sp-std = { version = "2.0.0-rc2", default-features = false, path = "../../primitives/std" } @@ -35,7 +35,7 @@ std = [ "codec/std", "frame-support/std", "sp-runtime/std", - "sp-phragmen/std", + "sp-npos-elections/std", "frame-system/std", "sp-std/std", ] diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 5d7d2bf503bc2..c155c08cafef2 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # Phragmen Election Module. +//! # Phragmén Election Module. //! //! An election module based on sequential phragmen. //! @@ -100,7 +100,7 @@ use frame_support::{ ContainsLengthBound, } }; -use sp_phragmen::{build_support_map, ExtendedBalance, VoteWeight, PhragmenResult}; +use sp_npos_elections::{build_support_map, ExtendedBalance, VoteWeight, ElectionResult}; use frame_system::{self as system, ensure_signed, ensure_root}; mod benchmarking; @@ -245,7 +245,6 @@ decl_storage! { } decl_error! { - /// Error for the elections-phragmen module. pub enum Error for Module { /// Cannot vote when no candidates or members exist. UnableToVote, @@ -610,7 +609,7 @@ decl_module! { /// the outgoing member is slashed. /// /// If a runner-up is available, then the best runner-up will be removed and replaces the - /// outgoing member. Otherwise, a new phragmen round is started. + /// outgoing member. Otherwise, a new phragmen election is started. /// /// Note that this does not affect the designated block number of the next election. /// @@ -840,13 +839,10 @@ impl Module { /// Run the phragmen election with all required side processes and state updates. /// - /// Calls the appropriate `ChangeMembers` function variant internally. + /// Calls the appropriate [`ChangeMembers`] function variant internally. /// - /// # - /// #### State /// Reads: O(C + V*E) where C = candidates, V voters and E votes per voter exits. /// Writes: O(M + R) with M desired members and R runners_up. - /// # fn do_phragmen() { let desired_seats = Self::desired_members() as usize; let desired_runners_up = Self::desired_runners_up() as usize; @@ -876,14 +872,14 @@ impl Module { let voters_and_votes = Voting::::iter() .map(|(voter, (stake, targets))| { (voter, to_votes(stake), targets) }) .collect::>(); - let maybe_phragmen_result = sp_phragmen::elect::( + let maybe_phragmen_result = sp_npos_elections::seq_phragmen::( num_to_elect, 0, candidates, voters_and_votes.clone(), ); - if let Some(PhragmenResult { winners, assignments }) = maybe_phragmen_result { + if let Some(ElectionResult { winners, assignments }) = maybe_phragmen_result { let old_members_ids = >::take().into_iter() .map(|(m, _)| m) .collect::>(); @@ -907,7 +903,7 @@ impl Module { // exposed candidates, cleaning any previous members, and so on. For now, in favour of // readability and veracity, we keep it simple. - let staked_assignments = sp_phragmen::assignment_ratio_to_staked( + let staked_assignments = sp_npos_elections::assignment_ratio_to_staked( assignments, stake_of, ); diff --git a/frame/staking/Cargo.toml b/frame/staking/Cargo.toml index 916e5676dad19..70d3e0461054b 100644 --- a/frame/staking/Cargo.toml +++ b/frame/staking/Cargo.toml @@ -16,7 +16,7 @@ static_assertions = "1.1.0" serde = { version = "1.0.101", optional = true } codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] } sp-std = { version = "2.0.0-rc2", default-features = false, path = "../../primitives/std" } -sp-phragmen = { version = "2.0.0-rc2", default-features = false, path = "../../primitives/phragmen" } +sp-npos-elections = { version = "2.0.0-rc2", default-features = false, path = "../../primitives/npos-elections" } sp-io ={ version = "2.0.0-rc2", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "2.0.0-rc2", default-features = false, path = "../../primitives/runtime" } sp-staking = { version = "2.0.0-rc2", default-features = false, path = "../../primitives/staking" } @@ -49,7 +49,7 @@ std = [ "serde", "codec/std", "sp-std/std", - "sp-phragmen/std", + "sp-npos-elections/std", "sp-io/std", "frame-support/std", "sp-runtime/std", diff --git a/frame/staking/fuzzer/Cargo.lock b/frame/staking/fuzzer/Cargo.lock index f6cb65aa5cd19..55f76eb6b395f 100644 --- a/frame/staking/fuzzer/Cargo.lock +++ b/frame/staking/fuzzer/Cargo.lock @@ -1003,7 +1003,7 @@ dependencies = [ "sp-application-crypto", "sp-core", "sp-io", - "sp-phragmen", + "sp-npos-elections", "sp-runtime", "sp-staking", "sp-std", @@ -1027,7 +1027,7 @@ dependencies = [ "rand 0.7.3", "sp-core", "sp-io", - "sp-phragmen", + "sp-npos-elections", "sp-runtime", "sp-std", ] @@ -1751,18 +1751,18 @@ dependencies = [ ] [[package]] -name = "sp-phragmen" +name = "sp-npos-elections" version = "2.0.0-alpha.5" dependencies = [ "parity-scale-codec", "serde", - "sp-phragmen-compact", + "sp-npos-elections-compact", "sp-runtime", "sp-std", ] [[package]] -name = "sp-phragmen-compact" +name = "sp-npos-elections-compact" version = "2.0.0-rc2" dependencies = [ "proc-macro-crate", diff --git a/frame/staking/fuzzer/Cargo.toml b/frame/staking/fuzzer/Cargo.toml index f4a31ff11a891..e9cb09ade3a8c 100644 --- a/frame/staking/fuzzer/Cargo.toml +++ b/frame/staking/fuzzer/Cargo.toml @@ -26,7 +26,7 @@ frame-support = { version = "2.0.0-rc2", path = "../../support" } sp-std = { version = "2.0.0-rc2", path = "../../../primitives/std" } sp-io ={ version = "2.0.0-rc2", path = "../../../primitives/io" } sp-core = { version = "2.0.0-rc2", path = "../../../primitives/core" } -sp-phragmen = { version = "2.0.0-rc2", path = "../../../primitives/phragmen" } +sp-npos-elections = { version = "2.0.0-rc2", path = "../../../primitives/npos-elections" } sp-runtime = { version = "2.0.0-rc2", path = "../../../primitives/runtime" } [[bin]] diff --git a/frame/staking/src/benchmarking.rs b/frame/staking/src/benchmarking.rs index d3723dce1cc11..44fc90240380c 100644 --- a/frame/staking/src/benchmarking.rs +++ b/frame/staking/src/benchmarking.rs @@ -565,7 +565,7 @@ benchmarks! { let caller: T::AccountId = account("caller", n, SEED); let era = >::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::(true); assert!( diff --git a/frame/staking/src/lib.rs b/frame/staking/src/lib.rs index 8eb734d8c888d..2a791bfa7ea7b 100644 --- a/frame/staking/src/lib.rs +++ b/frame/staking/src/lib.rs @@ -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 //! //! //! - 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 for enum Call where origin: T::Origin { -//! /// Reward a validator. -//! #[weight = 0] -//! pub fn reward_myself(origin) -> dispatch::DispatchResult { -//! let reported = ensure_signed(origin)?; -//! >::reward_by_ids(vec![(reported, 10)]); -//! Ok(()) -//! } -//! } +//! pub struct Module for enum Call where origin: T::Origin { +//! /// Reward a validator. +//! #[weight = 0] +//! pub fn reward_myself(origin) -> dispatch::DispatchResult { +//! let reported = ensure_signed(origin)?; +//! >::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, } -/// 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> { /// 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, VoteWeight> + Convert>; /// Tokens have been minted and are unused for validator-reward. @@ -864,9 +865,9 @@ pub trait Trait: frame_system::Trait + SendTransactionTypes> { /// Number of eras that staked funds must remain bonded for. type BondingDuration: Get; - /// 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; /// The origin which can cancel a deferred slash. Root can always do this. @@ -882,16 +883,19 @@ pub trait Trait: frame_system::Trait + SendTransactionTypes> { /// Something that can estimate the next session change, accurately or as a best effort guess. type NextNewSession: EstimateNextNewSession; - /// 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; /// The overarching call type. type Call: Dispatchable + From> + IsSubType, 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; /// 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>>; /// The score of the current [`QueuedElected`]. - pub QueuedScore get(fn queued_score): Option; + pub QueuedScore get(fn queued_score): Option; /// 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::() { - 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, compact: CompactAssignments, - score: PhragmenScore, + score: ElectionScore, era: EraIndex, size: ElectionSize, ) -> DispatchResultWithPostInfo { @@ -2148,7 +2152,7 @@ decl_module! { origin, winners: Vec, compact: CompactAssignments, - score: PhragmenScore, + score: ElectionScore, era: EraIndex, size: ElectionSize, ) -> DispatchResultWithPostInfo { @@ -2413,7 +2417,7 @@ impl Module { /// /// 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 Module { winners: Vec, compact_assignments: CompactAssignments, compute: ElectionCompute, - claimed_score: PhragmenScore, + claimed_score: ElectionScore, era: EraIndex, election_size: ElectionSize, ) -> DispatchResultWithPostInfo { @@ -2576,7 +2580,7 @@ impl Module { } // 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 Module { 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 Module { } /// 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>> { - // a phragmen result from either a stored submission or locally executed one. + fn try_do_election() -> Option>> { + // an election result from either a stored submission or locally executed one. let next_result = >::take().or_else(|| Self::do_phragmen_with_post_processing::(ElectionCompute::OnChain) ); @@ -2827,11 +2831,11 @@ impl Module { 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(compute: ElectionCompute) @@ -2846,7 +2850,7 @@ impl Module { .collect::>(); 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 Module { } } - /// 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() -> Option> { + fn do_phragmen() -> Option> { let mut all_nominators: Vec<(T::AccountId, VoteWeight, Vec)> = Vec::new(); let mut all_validators = Vec::new(); for (validator, _) in >::iter() { @@ -2912,7 +2916,7 @@ impl Module { (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 Module { ) } - /// 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) -> Vec<(T::AccountId, Exposure>)> { let to_balance = |e: ExtendedBalance| >>::convert(e); diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 6c52ccd6628ec..ef3d2c43bc34b 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -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, PhragmenScore) { +) -> (CompactAssignments, Vec, ElectionScore) { let mut backing_stake_of: BTreeMap = BTreeMap::new(); // self stake @@ -855,7 +855,7 @@ pub(crate) fn horrible_phragmen_with_post_processing( let support = build_support_map::(&winners, &staked_assignment).0; let score = evaluate_support(&support); - assert!(sp_phragmen::is_score_better::( + assert!(sp_npos_elections::is_score_better::( 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::(staked_assignment); + sp_npos_elections::assignment_staked_to_ratio::(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>), -) -> (CompactAssignments, Vec, PhragmenScore) { - // run phragmen on the default stuff. - let sp_phragmen::PhragmenResult { +) -> (CompactAssignments, Vec, ElectionScore) { + // run election on the default stuff. + let sp_npos_elections::ElectionResult { winners, assignments, } = Staking::do_phragmen::().unwrap(); - let winners = sp_phragmen::to_without_backing(winners); + let winners = sp_npos_elections::to_without_backing(winners); let stake_of = |who: &AccountId| -> 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::(&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, ); diff --git a/frame/staking/src/offchain_election.rs b/frame/staking/src/offchain_election.rs index ce9b77aef7c62..23453e0524aa4 100644 --- a/frame/staking/src/offchain_election.rs +++ b/frame/staking/src/offchain_election.rs @@ -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 for OffchainElectionError { - fn from(e: sp_phragmen::Error) -> Self { - Self::PhragmenError(e) +impl From 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( /// unsigned transaction, without any signature. pub(crate) fn compute_offchain_election() -> Result<(), OffchainElectionError> { // compute raw solution. Note that we use `OffchainAccuracy`. - let PhragmenResult { + let ElectionResult { winners, assignments, } = >::do_phragmen::() @@ -133,7 +133,7 @@ pub(crate) fn compute_offchain_election() -> 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( @@ -143,7 +143,7 @@ pub fn prepare_submission( ) -> Result<( Vec, CompactAssignments, - PhragmenScore, + ElectionScore, ElectionSize, ), OffchainElectionError> where ExtendedBalance: From<::Inner>, @@ -169,26 +169,26 @@ pub fn prepare_submission( }; // 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, >::slashable_balance_of_vote_weight, ); let (mut support_map, _) = build_support_map::(&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 = ::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( } // 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( // 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(), >::slashable_balance_of_vote_weight, ); diff --git a/frame/staking/src/testing_utils.rs b/frame/staking/src/testing_utils.rs index 2a38f47f4e8da..86d137ac30aba 100644 --- a/frame/staking/src/testing_utils.rs +++ b/frame/staking/src/testing_utils.rs @@ -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( /// which has a less score than the seq-phragmen. pub fn get_weak_solution( do_reduce: bool, -) -> (Vec, CompactAssignments, PhragmenScore, ElectionSize) { +) -> (Vec, CompactAssignments, ElectionScore, ElectionSize) { let mut backing_stake_of: BTreeMap> = BTreeMap::new(); // self stake @@ -252,8 +252,8 @@ pub fn get_weak_solution( /// worker code. pub fn get_seq_phragmen_solution( do_reduce: bool, -) -> (Vec, CompactAssignments, PhragmenScore, ElectionSize) { - let sp_phragmen::PhragmenResult { +) -> (Vec, CompactAssignments, ElectionScore, ElectionSize) { + let sp_npos_elections::ElectionResult { winners, assignments, } = >::do_phragmen::().unwrap(); @@ -264,7 +264,7 @@ pub fn get_seq_phragmen_solution( /// Returns a solution in which only one winner is elected with just a self vote. pub fn get_single_winner_solution( winner: T::AccountId -) -> Result<(Vec, CompactAssignments, PhragmenScore, ElectionSize), &'static str> { +) -> Result<(Vec, CompactAssignments, ElectionScore, ElectionSize), &'static str> { let snapshot_validators = >::snapshot_validators().unwrap(); let snapshot_nominators = >::snapshot_nominators().unwrap(); diff --git a/frame/staking/src/tests.rs b/frame/staking/src/tests.rs index bb5030034b8d8..8a7ae011c9134 100644 --- a/frame/staking/src/tests.rs +++ b/frame/staking/src/tests.rs @@ -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, 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()], diff --git a/primitives/arithmetic/src/rational128.rs b/primitives/arithmetic/src/rational128.rs index 709af1d3b97c3..947c7bc537d19 100644 --- a/primitives/arithmetic/src/rational128.rs +++ b/primitives/arithmetic/src/rational128.rs @@ -215,7 +215,7 @@ mod tests { assert_eq!(r(MAX128 - 10, MAX128).to_den(10), Ok(r(10, 10))); assert_eq!(r(MAX128 / 2, MAX128).to_den(10), Ok(r(5, 10))); - // large to perbill. This is very well needed for phragmen. + // large to perbill. This is very well needed for npos-elections. assert_eq!( r(MAX128 / 2, MAX128).to_den(1000_000_000), Ok(r(500_000_000, 1000_000_000)) diff --git a/primitives/phragmen/Cargo.toml b/primitives/npos-elections/Cargo.toml similarity index 81% rename from primitives/phragmen/Cargo.toml rename to primitives/npos-elections/Cargo.toml index d2b8e56dc0dbb..c8de0ac46f964 100644 --- a/primitives/phragmen/Cargo.toml +++ b/primitives/npos-elections/Cargo.toml @@ -1,12 +1,12 @@ [package] -name = "sp-phragmen" +name = "sp-npos-elections" version = "2.0.0-rc2" authors = ["Parity Technologies "] edition = "2018" license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -description = "Phragmen primitives" +description = "NPoS election algorithm primitives" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] @@ -15,13 +15,13 @@ targets = ["x86_64-unknown-linux-gnu"] codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] } serde = { version = "1.0.101", optional = true, features = ["derive"] } sp-std = { version = "2.0.0-rc2", default-features = false, path = "../std" } -sp-phragmen-compact = { version = "2.0.0-rc2", path = "./compact" } +sp-npos-elections-compact = { version = "2.0.0-rc2", path = "./compact" } sp-arithmetic = { version = "2.0.0-rc2", default-features = false, path = "../arithmetic" } [dev-dependencies] substrate-test-utils = { version = "2.0.0-rc2", path = "../../test-utils" } rand = "0.7.3" -sp-phragmen = { version = "2.0.0-rc2", path = "." } +sp-npos-elections = { version = "2.0.0-rc2", path = "." } sp-runtime = { version = "2.0.0-rc2", path = "../../primitives/runtime" } [features] diff --git a/primitives/phragmen/benches/phragmen.rs b/primitives/npos-elections/benches/phragmen.rs similarity index 92% rename from primitives/phragmen/benches/phragmen.rs rename to primitives/npos-elections/benches/phragmen.rs index c01d9f400d69d..7e46b9dce1d0b 100644 --- a/primitives/phragmen/benches/phragmen.rs +++ b/primitives/npos-elections/benches/phragmen.rs @@ -25,10 +25,15 @@ extern crate test; use test::Bencher; use rand::{self, Rng}; -use sp_phragmen::{PhragmenResult, VoteWeight}; +use sp_npos_elections::{ElectionResult, VoteWeight}; use std::collections::BTreeMap; -use sp_runtime::{Perbill, traits::Zero}; +use sp_runtime::{Perbill, PerThing, traits::Zero}; +use sp_npos_elections::{ + balance_solution, assignment_ratio_to_staked, build_support_map, to_without_backing, VoteWeight, + ExtendedBalance, Assignment, StakedAssignment, IdentifierT, assignment_ratio_to_staked, + seq_phragmen, +}; // default params. Each will be scaled by the benchmarks individually. const VALIDATORS: u64 = 100; @@ -42,13 +47,7 @@ const PREFIX: AccountId = 1000_000; type AccountId = u64; mod bench_closure_and_slice { - use sp_phragmen::{ - VoteWeight, ExtendedBalance, Assignment, StakedAssignment, IdentifierT, - assignment_ratio_to_staked, - }; - use sp_runtime::{Perbill, PerThing}; - use rand::{self, Rng, RngCore}; - use test::Bencher; + use super::*; fn random_assignment() -> Assignment { let mut rng = rand::thread_rng(); @@ -135,7 +134,7 @@ fn do_phragmen( }); b.iter(|| { - let PhragmenResult { winners, assignments } = sp_phragmen::elect::( + let ElectionResult { winners, assignments } = seq_phragmen::( to_elect, Zero::zero(), candidates.clone(), @@ -146,14 +145,13 @@ fn do_phragmen( *stake_of_tree.get(who).unwrap() }; - // Do the benchmarking with equalize. + // Do the benchmarking with balancing. if eq_iters > 0 { - use sp_phragmen::{equalize, assignment_ratio_to_staked, build_support_map, to_without_backing}; let staked = assignment_ratio_to_staked(assignments, &stake_of); let winners = to_without_backing(winners); let mut support = build_support_map(winners.as_ref(), staked.as_ref()).0; - equalize( + balance_solution( staked.into_iter().map(|a| (a.clone(), stake_of(&a.who))).collect(), &mut support, eq_tolerance, diff --git a/primitives/phragmen/compact/Cargo.toml b/primitives/npos-elections/compact/Cargo.toml similarity index 85% rename from primitives/phragmen/compact/Cargo.toml rename to primitives/npos-elections/compact/Cargo.toml index 8fb9789d99c54..d14405619a370 100644 --- a/primitives/phragmen/compact/Cargo.toml +++ b/primitives/npos-elections/compact/Cargo.toml @@ -1,12 +1,12 @@ [package] -name = "sp-phragmen-compact" +name = "sp-npos-elections-compact" version = "2.0.0-rc2" authors = ["Parity Technologies "] edition = "2018" license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" -description = "Phragmen Compact Solution" +description = "NPoS Compact Solution Type" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] diff --git a/primitives/phragmen/compact/src/assignment.rs b/primitives/npos-elections/compact/src/assignment.rs similarity index 97% rename from primitives/phragmen/compact/src/assignment.rs rename to primitives/npos-elections/compact/src/assignment.rs index a48cbd937913b..fb3d4330b06e8 100644 --- a/primitives/phragmen/compact/src/assignment.rs +++ b/primitives/npos-elections/compact/src/assignment.rs @@ -57,7 +57,13 @@ fn from_impl(count: usize) -> TokenStream2 { let last = quote!(index_of_target(&distribution[#last_index].0).ok_or(_phragmen::Error::CompactInvalidIndex)?); quote!( - #c => compact.#field_name.push((index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, [#inner], #last)), + #c => compact.#field_name.push( + ( + index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, + [#inner], + #last, + ) + ), ) }).collect::(); diff --git a/primitives/phragmen/compact/src/lib.rs b/primitives/npos-elections/compact/src/lib.rs similarity index 95% rename from primitives/phragmen/compact/src/lib.rs rename to primitives/npos-elections/compact/src/lib.rs index 735e0abaa66cd..022782a7dd9cf 100644 --- a/primitives/phragmen/compact/src/lib.rs +++ b/primitives/npos-elections/compact/src/lib.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Proc macro for phragmen compact assignment. +//! Proc macro for a npos compact assignment. use proc_macro::TokenStream; use proc_macro2::{TokenStream as TokenStream2, Span, Ident}; @@ -29,7 +29,7 @@ mod staked; // prefix used for struct fields in compact. const PREFIX: &'static str = "votes"; -/// Generates a struct to store the phragmen assignments in a compact way. The struct can only store +/// Generates a struct to store the election assignments in a compact way. The struct can only store /// distributions up to the given input count. The given count must be greater than 2. /// /// ```ignore @@ -176,7 +176,7 @@ fn struct_def( }).collect::(); Ok(quote! ( - /// A struct to encode a Phragmen assignment in a compact way. + /// A struct to encode a election assignment in a compact way. #[derive( Default, PartialEq, @@ -224,9 +224,9 @@ fn struct_def( } fn imports() -> Result { - let sp_phragmen_imports = match crate_name("sp-phragmen") { - Ok(sp_phragmen) => { - let ident = syn::Ident::new(&sp_phragmen, Span::call_site()); + let sp_phragmen_imports = match crate_name("sp-npos-elections") { + Ok(sp_npos_elections) => { + let ident = syn::Ident::new(&sp_npos_elections, Span::call_site()); quote!( extern crate #ident as _phragmen; ) } Err(e) => return Err(syn::Error::new(Span::call_site(), &e)), diff --git a/primitives/phragmen/compact/src/staked.rs b/primitives/npos-elections/compact/src/staked.rs similarity index 97% rename from primitives/phragmen/compact/src/staked.rs rename to primitives/npos-elections/compact/src/staked.rs index cb1675219580a..e2680e18b6326 100644 --- a/primitives/phragmen/compact/src/staked.rs +++ b/primitives/npos-elections/compact/src/staked.rs @@ -57,7 +57,9 @@ fn from_impl(count: usize) -> TokenStream2 { let last = quote!(index_of_target(&distribution[#last_index].0).ok_or(_phragmen::Error::CompactInvalidIndex)?); quote!( - #c => compact.#field_name.push((index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, [#inner], #last)), + #c => compact.#field_name.push( + (index_of_voter(&who).ok_or(_phragmen::Error::CompactInvalidIndex)?, [#inner], #last) + ), ) }).collect::(); diff --git a/primitives/phragmen/fuzzer/.gitignore b/primitives/npos-elections/fuzzer/.gitignore similarity index 100% rename from primitives/phragmen/fuzzer/.gitignore rename to primitives/npos-elections/fuzzer/.gitignore diff --git a/primitives/phragmen/fuzzer/Cargo.lock b/primitives/npos-elections/fuzzer/Cargo.lock similarity index 99% rename from primitives/phragmen/fuzzer/Cargo.lock rename to primitives/npos-elections/fuzzer/Cargo.lock index a57bfa39206fc..c1d7ba945f5a2 100644 --- a/primitives/phragmen/fuzzer/Cargo.lock +++ b/primitives/npos-elections/fuzzer/Cargo.lock @@ -1234,19 +1234,19 @@ dependencies = [ ] [[package]] -name = "sp-phragmen" +name = "sp-npos-elections" version = "2.0.0-alpha.3" dependencies = [ "parity-scale-codec", "serde", "sp-core", - "sp-phragmen-compact", + "sp-npos-elections-compact", "sp-runtime", "sp-std", ] [[package]] -name = "sp-phragmen-compact" +name = "sp-npos-elections-compact" version = "2.0.0-rc2" dependencies = [ "proc-macro-crate", @@ -1256,12 +1256,12 @@ dependencies = [ ] [[package]] -name = "sp-phragmen-fuzzer" +name = "sp-npos-elections-fuzzer" version = "2.0.0" dependencies = [ "honggfuzz", "rand 0.7.3", - "sp-phragmen", + "sp-npos-elections", ] [[package]] diff --git a/primitives/phragmen/fuzzer/Cargo.toml b/primitives/npos-elections/fuzzer/Cargo.toml similarity index 74% rename from primitives/phragmen/fuzzer/Cargo.toml rename to primitives/npos-elections/fuzzer/Cargo.toml index 2846841e1c11b..e9ca6c6fd9120 100644 --- a/primitives/phragmen/fuzzer/Cargo.toml +++ b/primitives/npos-elections/fuzzer/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "sp-phragmen-fuzzer" +name = "sp-npos-elections-fuzzer" version = "2.0.0-alpha.5" authors = ["Parity Technologies "] edition = "2018" @@ -7,14 +7,14 @@ license = "Apache-2.0" homepage = "https://substrate.dev" repository = "https://github.com/paritytech/substrate/" description = "Fuzzer for phragmén implementation." -documentation = "https://docs.rs/sp-phragmen-fuzzer" +documentation = "https://docs.rs/sp-npos-elections-fuzzer" publish = false [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [dependencies] -sp-phragmen = { version = "2.0.0-rc2", path = ".." } +sp-npos-elections = { version = "2.0.0-rc2", path = ".." } sp-std = { version = "2.0.0-rc2", path = "../../std" } sp-runtime = { version = "2.0.0-rc2", path = "../../runtime" } honggfuzz = "0.5" @@ -25,5 +25,5 @@ name = "reduce" path = "src/reduce.rs" [[bin]] -name = "equalize" -path = "src/equalize.rs" +name = "balance_solution" +path = "src/balance_solution.rs" diff --git a/primitives/phragmen/fuzzer/src/equalize.rs b/primitives/npos-elections/fuzzer/src/balance_solution.rs similarity index 87% rename from primitives/phragmen/fuzzer/src/equalize.rs rename to primitives/npos-elections/fuzzer/src/balance_solution.rs index a46e479b5a1b1..e1bd3bd0a07dd 100644 --- a/primitives/phragmen/fuzzer/src/equalize.rs +++ b/primitives/npos-elections/fuzzer/src/balance_solution.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Fuzzing fro the equalize algorithm +//! Fuzzing fro the balance_solution algorithm //! //! It ensures that any solution which gets equalized will lead into a better or equally scored //! one. @@ -23,9 +23,9 @@ mod common; use common::to_range; use honggfuzz::fuzz; -use sp_phragmen::{ - equalize, assignment_ratio_to_staked, build_support_map, to_without_backing, elect, - PhragmenResult, VoteWeight, evaluate_support, is_score_better, +use sp_npos_elections::{ + balance_solution, assignment_ratio_to_staked, build_support_map, to_without_backing, seq_phragmen, + ElectionResult, VoteWeight, evaluate_support, is_score_better, }; use sp_std::collections::btree_map::BTreeMap; use sp_runtime::Perbill; @@ -39,7 +39,7 @@ fn generate_random_phragmen_result( to_elect: usize, edge_per_voter: u64, mut rng: impl RngCore, -) -> (PhragmenResult, BTreeMap) { +) -> (ElectionResult, BTreeMap) { let prefix = 100_000; // Note, it is important that stakes are always bigger than ed and let base_stake: u64 = 1_000_000_000; @@ -73,7 +73,7 @@ fn generate_random_phragmen_result( }); ( - elect::( + seq_phragmen::( to_elect, 0, candidates, @@ -86,7 +86,14 @@ fn generate_random_phragmen_result( fn main() { loop { fuzz!(|data: (usize, usize, usize, usize, usize, u64)| { - let (mut target_count, mut voter_count, mut iterations, mut edge_per_voter, mut to_elect, seed) = data; + let ( + mut target_count, + mut voter_count, + mut iterations, + mut edge_per_voter, + mut to_elect, + seed, + ) = data; let rng = rand::rngs::SmallRng::seed_from_u64(seed); target_count = to_range(target_count, 50, 2000); voter_count = to_range(voter_count, 50, 1000); @@ -95,7 +102,7 @@ fn main() { edge_per_voter = to_range(edge_per_voter, 1, target_count); println!("++ [{} / {} / {} / {}]", voter_count, target_count, to_elect, iterations); - let (PhragmenResult { winners, assignments }, stake_of_tree) = generate_random_phragmen_result( + let (ElectionResult { winners, assignments }, stake_of_tree) = generate_random_phragmen_result( voter_count as u64, target_count as u64, to_elect, @@ -117,7 +124,7 @@ fn main() { return; } - let i = equalize( + let i = balance_solution( &mut staked, &mut support, 10, diff --git a/primitives/phragmen/fuzzer/src/common.rs b/primitives/npos-elections/fuzzer/src/common.rs similarity index 100% rename from primitives/phragmen/fuzzer/src/common.rs rename to primitives/npos-elections/fuzzer/src/common.rs diff --git a/primitives/phragmen/fuzzer/src/reduce.rs b/primitives/npos-elections/fuzzer/src/reduce.rs similarity index 98% rename from primitives/phragmen/fuzzer/src/reduce.rs rename to primitives/npos-elections/fuzzer/src/reduce.rs index 7ac15dd5443b2..d08a440a6291f 100644 --- a/primitives/phragmen/fuzzer/src/reduce.rs +++ b/primitives/npos-elections/fuzzer/src/reduce.rs @@ -34,7 +34,7 @@ use honggfuzz::fuzz; mod common; use common::to_range; -use sp_phragmen::{StakedAssignment, ExtendedBalance, build_support_map, reduce}; +use sp_npos_elections::{StakedAssignment, ExtendedBalance, build_support_map, reduce}; use rand::{self, Rng, SeedableRng, RngCore}; type Balance = u128; diff --git a/primitives/phragmen/src/helpers.rs b/primitives/npos-elections/src/helpers.rs similarity index 98% rename from primitives/phragmen/src/helpers.rs rename to primitives/npos-elections/src/helpers.rs index 2674bc445de37..1c96300c66224 100644 --- a/primitives/phragmen/src/helpers.rs +++ b/primitives/npos-elections/src/helpers.rs @@ -15,7 +15,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Helper methods for phragmen. +//! Helper methods for npos-elections. use crate::{Assignment, ExtendedBalance, VoteWeight, IdentifierT, StakedAssignment, WithApprovalOf}; use sp_arithmetic::PerThing; diff --git a/primitives/phragmen/src/lib.rs b/primitives/npos-elections/src/lib.rs similarity index 92% rename from primitives/phragmen/src/lib.rs rename to primitives/npos-elections/src/lib.rs index 6b2686e5438f2..72eddf9a1d20c 100644 --- a/primitives/phragmen/src/lib.rs +++ b/primitives/npos-elections/src/lib.rs @@ -15,22 +15,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Rust implementation of the Phragmén election algorithm. This is used in several pallets to -//! optimally distribute the weight of a set of voters among an elected set of candidates. In the -//! context of staking this is mapped to validators and nominators. +//! A set of election algorithms to be used with a substrate runtime, typically within the staking +//! sub-system. Notable implementation include //! -//! The algorithm has two phases: -//! - Sequential phragmen: performed in [`elect`] function which is first pass of the distribution -//! The results are not optimal but the execution time is less. -//! - Equalize post-processing: tries to further distribute the weight fairly among candidates. -//! Incurs more execution time. +//! - [`seq_phragmen`]: Implements the Phragmén Sequential Method. An un-ranked, relatively fast +//! election method that ensures PJR, but does not provide a constant factor approximation of the +//! maximin problem. +//! - [`balance_solution`]: Implements the star balancing algorithm. This iterative process can +//! increase a solutions score, as described in [`evaluate_support`]. //! -//! The main objective of the assignments done by phragmen is to maximize the minimum backed -//! candidate in the elected set. -//! -//! Reference implementation: https://github.com/w3f/consensus -//! Further details: -//! https://research.web3.foundation/en/latest/polkadot/NPoS/4.%20Sequential%20Phragm%C3%A9n%E2%80%99s%20method/ +//! More information can be found at: https://arxiv.org/abs/2004.12990 #![cfg_attr(not(feature = "std"), no_std)] @@ -67,7 +61,7 @@ pub use codec; pub use sp_arithmetic; // re-export the compact solution type. -pub use sp_phragmen_compact::generate_compact_solution_type; +pub use sp_npos_elections_compact::generate_compact_solution_type; /// A trait to limit the number of votes per voter. The generated compact type will implement this. pub trait VotingLimit { @@ -100,7 +94,7 @@ pub type VoteWeight = u64; pub type ExtendedBalance = u128; /// The score of an assignment. This can be computed from the support map via [`evaluate_support`]. -pub type PhragmenScore = [ExtendedBalance; 3]; +pub type ElectionScore = [ExtendedBalance; 3]; /// A winner, with their respective approval stake. pub type WithApprovalOf = (A, ExtendedBalance); @@ -110,7 +104,7 @@ pub type WithApprovalOf = (A, ExtendedBalance); /// bigger than u64::max_value() is needed. For maximum accuracy we simply use u128; const DEN: u128 = u128::max_value(); -/// A candidate entity for phragmen election. +/// A candidate entity for the election. #[derive(Clone, Default, Debug)] struct Candidate { /// Identifier. @@ -147,9 +141,9 @@ struct Edge { candidate_index: usize, } -/// Final result of the phragmen election. +/// Final result of the election. #[derive(Debug)] -pub struct PhragmenResult { +pub struct ElectionResult { /// Just winners zipped with their approval stake. Note that the approval stake is merely the /// sub of their received stake and could be used for very basic sorting and approval voting. pub winners: Vec>, @@ -298,10 +292,10 @@ impl StakedAssignment { } } -/// A structure to demonstrate the phragmen result from the perspective of the candidate, i.e. how +/// A structure to demonstrate the election result from the perspective of the candidate, i.e. how /// much support each candidate is receiving. /// -/// This complements the [`PhragmenResult`] and is needed to run the equalize post-processing. +/// This complements the [`ElectionResult`] and is needed to run the balancing post-processing. /// /// This, at the current version, resembles the `Exposure` defined in the Staking pallet, yet /// they do not necessarily have to be the same. @@ -332,12 +326,12 @@ pub type SupportMap = BTreeMap>; /// responsibility of the caller to make sure only those candidates who have a sensible economic /// value are passed in. From the perspective of this function, a candidate can easily be among the /// winner with no backing stake. -pub fn elect( +pub fn seq_phragmen( candidate_count: usize, minimum_candidate_count: usize, initial_candidates: Vec, initial_voters: Vec<(AccountId, VoteWeight, Vec)>, -) -> Option> where +) -> Option> where AccountId: Default + Ord + Clone, R: PerThing, { @@ -388,7 +382,6 @@ pub fn elect( // we have already checked that we have more candidates than minimum_candidate_count. - // run phragmen. let to_elect = candidate_count.min(candidates.len()); elected_candidates = Vec::with_capacity(candidate_count); assigned = Vec::with_capacity(candidate_count); @@ -524,13 +517,13 @@ pub fn elect( } } - Some(PhragmenResult { + Some(ElectionResult { winners: elected_candidates, assignments: assigned, }) } -/// Build the support map from the given phragmen result. It maps a flat structure like +/// Build the support map from the given election result. It maps a flat structure like /// /// ```nocompile /// assignments: vec![ @@ -588,7 +581,7 @@ pub fn build_support_map( (supports, errors) } -/// Evaluate a phragmen result, given the support map. The returned tuple contains: +/// Evaluate a support map. The returned tuple contains: /// /// - Minimum support. This value must be **maximized**. /// - Sum of all supports. This value must be **maximized**. @@ -597,7 +590,7 @@ pub fn build_support_map( /// `O(E)` where `E` is the total number of edges. pub fn evaluate_support( support: &SupportMap, -) -> PhragmenScore { +) -> ElectionScore { let mut min_support = ExtendedBalance::max_value(); let mut sum: ExtendedBalance = Zero::zero(); // NOTE: The third element might saturate but fine for now since this will run on-chain and need @@ -614,14 +607,14 @@ pub fn evaluate_support( [min_support, sum, sum_squared] } -/// Compares two sets of phragmen scores based on desirability and returns true if `this` is +/// Compares two sets of election scores based on desirability and returns true if `this` is /// better than `that`. /// /// Evaluation is done in a lexicographic manner, and if each element of `this` is `that * epsilon` /// greater or less than `that`. /// /// Note that the third component should be minimized. -pub fn is_score_better(this: PhragmenScore, that: PhragmenScore, epsilon: P) -> bool +pub fn is_score_better(this: ElectionScore, that: ElectionScore, epsilon: P) -> bool where ExtendedBalance: From> { match this @@ -648,17 +641,17 @@ pub fn is_score_better(this: PhragmenScore, that: PhragmenScore, ep } } -/// Performs equalize post-processing to the output of the election algorithm. This happens in +/// Performs balancing post-processing to the output of the election algorithm. This happens in /// rounds. The number of rounds and the maximum diff-per-round tolerance can be tuned through input /// parameters. /// /// Returns the number of iterations that were preformed. /// -/// - `assignments`: exactly the same is the output of phragmen. +/// - `assignments`: exactly the same as the output of [`seq_phragmen`]. /// - `supports`: mutable reference to s `SupportMap`. This parameter is updated. /// - `tolerance`: maximum difference that can occur before an early quite happens. /// - `iterations`: maximum number of iterations that will be processed. -pub fn equalize( +pub fn balance_solution( assignments: &mut Vec>, supports: &mut SupportMap, tolerance: ExtendedBalance, @@ -672,7 +665,7 @@ pub fn equalize( for assignment in assignments.iter_mut() { let voter_budget = assignment.total(); let StakedAssignment { who, distribution } = assignment; - let diff = do_equalize( + let diff = do_balancing( who, voter_budget, distribution, @@ -689,9 +682,9 @@ pub fn equalize( } } -/// actually perform equalize. same interface is `equalize`. Just called in loops with a check for +/// actually perform balancing. same interface is `balance_solution`. Just called in loops with a check for /// maximum difference. -fn do_equalize( +fn do_balancing( voter: &AccountId, budget: ExtendedBalance, elected_edges: &mut Vec<(AccountId, ExtendedBalance)>, diff --git a/primitives/phragmen/src/mock.rs b/primitives/npos-elections/src/mock.rs similarity index 98% rename from primitives/phragmen/src/mock.rs rename to primitives/npos-elections/src/mock.rs index fb801125158bc..b9c2396b08bb0 100644 --- a/primitives/phragmen/src/mock.rs +++ b/primitives/npos-elections/src/mock.rs @@ -15,11 +15,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Mock file for phragmen. +//! Mock file for npos-elections. #![cfg(test)] -use crate::{elect, PhragmenResult, Assignment, VoteWeight, ExtendedBalance}; +use crate::{seq_phragmen, ElectionResult, Assignment, VoteWeight, ExtendedBalance}; use sp_arithmetic::{PerThing, traits::{SaturatedConversion, Zero, One}}; use sp_std::collections::btree_map::BTreeMap; use sp_runtime::assert_eq_error_rate; @@ -326,7 +326,7 @@ pub(crate) fn run_and_compare( min_to_elect: usize, ) { // run fixed point code. - let PhragmenResult { winners, assignments } = elect::<_, Output>( + let ElectionResult { winners, assignments } = seq_phragmen::<_, Output>( to_elect, min_to_elect, candidates.clone(), diff --git a/primitives/phragmen/src/node.rs b/primitives/npos-elections/src/node.rs similarity index 100% rename from primitives/phragmen/src/node.rs rename to primitives/npos-elections/src/node.rs diff --git a/primitives/phragmen/src/reduce.rs b/primitives/npos-elections/src/reduce.rs similarity index 100% rename from primitives/phragmen/src/reduce.rs rename to primitives/npos-elections/src/reduce.rs diff --git a/primitives/phragmen/src/tests.rs b/primitives/npos-elections/src/tests.rs similarity index 95% rename from primitives/phragmen/src/tests.rs rename to primitives/npos-elections/src/tests.rs index a8bc069147b9b..47d619339be5d 100644 --- a/primitives/phragmen/src/tests.rs +++ b/primitives/npos-elections/src/tests.rs @@ -15,14 +15,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Tests for phragmen. +//! Tests for npos-elections. #![cfg(test)] use crate::mock::*; use crate::{ - elect, equalize, build_support_map, is_score_better, helpers::*, - Support, StakedAssignment, Assignment, PhragmenResult, ExtendedBalance, + seq_phragmen, balance_solution, build_support_map, is_score_better, helpers::*, + Support, StakedAssignment, Assignment, ElectionResult, ExtendedBalance, }; use substrate_test_utils::assert_eq_uvec; use sp_arithmetic::{Perbill, Permill, Percent, PerU16}; @@ -83,7 +83,7 @@ fn phragmen_poc_works() { ]; let stake_of = create_stake_of(&[(10, 10), (20, 20), (30, 30)]); - let PhragmenResult { winners, assignments } = elect::<_, Perbill>( + let ElectionResult { winners, assignments } = seq_phragmen::<_, Perbill>( 2, 2, candidates, @@ -146,7 +146,7 @@ fn phragmen_poc_works() { Support:: { total: 35, voters: vec![(20, 20), (30, 15)] }, ); - equalize( + balance_solution( &mut staked, &mut support_map, 0, @@ -240,11 +240,14 @@ fn phragmen_accuracy_on_large_scale_only_validators() { (5, (u64::max_value() - 2).into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, Perbill>( + let ElectionResult { winners, assignments } = seq_phragmen::<_, Perbill>( 2, 2, candidates.clone(), - auto_generate_self_voters(&candidates).iter().map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())).collect::>(), + auto_generate_self_voters(&candidates) + .iter() + .map(|(ref v, ref vs)| (v.clone(), stake_of(v), vs.clone())) + .collect::>(), ).unwrap(); assert_eq_uvec!(winners, vec![(1, 18446744073709551614u128), (5, 18446744073709551613u128)]); @@ -270,7 +273,7 @@ fn phragmen_accuracy_on_large_scale_validators_and_nominators() { (14, u64::max_value().into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, Perbill>( + let ElectionResult { winners, assignments } = seq_phragmen::<_, Perbill>( 2, 2, candidates, @@ -313,7 +316,7 @@ fn phragmen_accuracy_on_small_scale_self_vote() { (30, 1), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, Perbill>( + let ElectionResult { winners, assignments: _ } = seq_phragmen::<_, Perbill>( 3, 3, candidates, @@ -343,7 +346,7 @@ fn phragmen_accuracy_on_small_scale_no_self_vote() { (3, 1), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, Perbill>( + let ElectionResult { winners, assignments: _ } = seq_phragmen::<_, Perbill>( 3, 3, candidates, @@ -376,7 +379,7 @@ fn phragmen_large_scale_test() { (50, 990000000000000000), ]); - let PhragmenResult { winners, assignments } = elect::<_, Perbill>( + let ElectionResult { winners, assignments } = seq_phragmen::<_, Perbill>( 2, 2, candidates, @@ -402,7 +405,7 @@ fn phragmen_large_scale_test_2() { (50, nom_budget.into()), ]); - let PhragmenResult { winners, assignments } = elect::<_, Perbill>( + let ElectionResult { winners, assignments } = seq_phragmen::<_, Perbill>( 2, 2, candidates, @@ -478,7 +481,7 @@ fn elect_has_no_entry_barrier() { (2, 10), ]); - let PhragmenResult { winners, assignments: _ } = elect::<_, Perbill>( + let ElectionResult { winners, assignments: _ } = seq_phragmen::<_, Perbill>( 3, 3, candidates, @@ -505,7 +508,7 @@ fn minimum_to_elect_is_respected() { (2, 10), ]); - let maybe_result = elect::<_, Perbill>( + let maybe_result = seq_phragmen::<_, Perbill>( 10, 10, candidates, @@ -531,7 +534,7 @@ fn self_votes_should_be_kept() { (1, 8), ]); - let result = elect::<_, Perbill>( + let result = seq_phragmen::<_, Perbill>( 2, 2, candidates, @@ -570,7 +573,7 @@ fn self_votes_should_be_kept() { &Support { total: 24u128, voters: vec![(20u64, 20u128), (1u64, 4u128)] }, ); - equalize( + balance_solution( &mut staked_assignments, &mut supports, 0, @@ -771,8 +774,8 @@ mod compact { use codec::{Decode, Encode}; use crate::{generate_compact_solution_type, VoteWeight}; use super::{AccountId}; - // these need to come from the same dev-dependency `sp-phragmen`, not from the crate. - use sp_phragmen::{Assignment, StakedAssignment, Error as PhragmenError, ExtendedBalance}; + // these need to come from the same dev-dependency `sp-npos-elections`, not from the crate. + use sp_npos_elections::{Assignment, StakedAssignment, Error as PhragmenError, ExtendedBalance}; use sp_std::{convert::{TryInto, TryFrom}, fmt::Debug}; use sp_arithmetic::Percent;