Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Decouple Stkaing and Election - Part1: Support traits #7908

Merged
5 commits merged into from
Jan 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ members = [
"primitives/database",
"primitives/debug-derive",
"primitives/externalities",
"primitives/election-providers",
"primitives/finality-grandpa",
"primitives/inherents",
"primitives/io",
Expand Down
1 change: 1 addition & 0 deletions frame/staking/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use super::*;
use crate::Module as Staking;
use testing_utils::*;

use sp_npos_elections::CompactSolution;
use sp_runtime::traits::One;
use frame_system::RawOrigin;
pub use frame_benchmarking::{benchmarks, account, whitelisted_caller, whitelist_account};
Expand Down
35 changes: 17 additions & 18 deletions frame/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,11 @@
//!
//! The controller account can free a portion (or all) of the funds using the
//! [`unbond`](enum.Call.html#variant.unbond) call. Note that the funds are not immediately
//! accessible. Instead, a duration denoted by [`BondingDuration`](./trait.Config.html#associatedtype.BondingDuration)
//! (in number of eras) must pass until the funds can actually be removed. Once the
//! `BondingDuration` is over, the [`withdraw_unbonded`](./enum.Call.html#variant.withdraw_unbonded)
//! call can be used to actually withdraw the funds.
//! accessible. Instead, a duration denoted by
//! [`BondingDuration`](./trait.Config.html#associatedtype.BondingDuration) (in number of eras) must
//! pass until the funds can actually be removed. Once the `BondingDuration` is over, the
//! [`withdraw_unbonded`](./enum.Call.html#variant.withdraw_unbonded) call can be used to actually
//! withdraw the funds.
//!
//! Note that there is a limitation to the number of fund-chunks that can be scheduled to be
//! unlocked in the future via [`unbond`](enum.Call.html#variant.unbond). In case this maximum
Expand Down Expand Up @@ -304,7 +305,7 @@ use frame_support::{
};
use pallet_session::historical;
use sp_runtime::{
Percent, Perbill, PerU16, PerThing, InnerOf, RuntimeDebug, DispatchError,
Percent, Perbill, PerU16, InnerOf, RuntimeDebug, DispatchError,
curve::PiecewiseLinear,
traits::{
Convert, Zero, StaticLookup, CheckedSub, Saturating, SaturatedConversion,
Expand All @@ -327,14 +328,14 @@ use frame_system::{
};
use sp_npos_elections::{
ExtendedBalance, Assignment, ElectionScore, ElectionResult as PrimitiveElectionResult,
build_support_map, evaluate_support, seq_phragmen, generate_solution_type,
is_score_better, VotingLimit, SupportMap, VoteWeight,
to_support_map, EvaluateSupport, seq_phragmen, generate_solution_type, is_score_better,
SupportMap, VoteWeight, CompactSolution, PerThing128,
};
pub use weights::WeightInfo;

const STAKING_ID: LockIdentifier = *b"staking ";
pub const MAX_UNLOCKING_CHUNKS: usize = 32;
pub const MAX_NOMINATIONS: usize = <CompactAssignments as VotingLimit>::LIMIT;
pub const MAX_NOMINATIONS: usize = <CompactAssignments as CompactSolution>::LIMIT;

pub(crate) const LOG_TARGET: &'static str = "staking";

Expand Down Expand Up @@ -2102,7 +2103,7 @@ decl_module! {
#[weight = T::WeightInfo::submit_solution_better(
size.validators.into(),
size.nominators.into(),
compact.len() as u32,
compact.voter_count() as u32,
winners.len() as u32,
)]
pub fn submit_election_solution(
Expand Down Expand Up @@ -2136,7 +2137,7 @@ decl_module! {
#[weight = T::WeightInfo::submit_solution_better(
size.validators.into(),
size.nominators.into(),
compact.len() as u32,
compact.voter_count() as u32,
winners.len() as u32,
)]
pub fn submit_election_solution_unsigned(
Expand Down Expand Up @@ -2598,13 +2599,11 @@ impl<T: Config> Module<T> {
);

// build the support map thereof in order to evaluate.
let supports = build_support_map::<T::AccountId>(
&winners,
&staked_assignments,
).map_err(|_| Error::<T>::OffchainElectionBogusEdge)?;
let supports = to_support_map::<T::AccountId>(&winners, &staked_assignments)
.map_err(|_| Error::<T>::OffchainElectionBogusEdge)?;

// Check if the score is the same as the claimed one.
let submitted_score = evaluate_support(&supports);
let submitted_score = (&supports).evaluate();
ensure!(submitted_score == claimed_score, Error::<T>::OffchainElectionBogusScore);

// At last, alles Ok. Exposures and store the result.
Expand Down Expand Up @@ -2860,7 +2859,7 @@ impl<T: Config> Module<T> {
Self::slashable_balance_of_fn(),
);

let supports = build_support_map::<T::AccountId>(
let supports = to_support_map::<T::AccountId>(
&elected_stashes,
&staked_assignments,
)
Expand Down Expand Up @@ -2899,7 +2898,7 @@ impl<T: Config> Module<T> {
/// Self votes are added and nominations before the most recent slashing span are ignored.
///
/// No storage item is updated.
pub fn do_phragmen<Accuracy: PerThing>(
pub fn do_phragmen<Accuracy: PerThing128>(
iterations: usize,
) -> Option<PrimitiveElectionResult<T::AccountId, Accuracy>>
where
Expand Down Expand Up @@ -2949,7 +2948,7 @@ impl<T: Config> Module<T> {
all_nominators,
Some((iterations, 0)), // exactly run `iterations` rounds.
)
.map_err(|err| log!(error, "Call to seq-phragmen failed due to {}", err))
.map_err(|err| log!(error, "Call to seq-phragmen failed due to {:?}", err))
.ok()
}
}
Expand Down
10 changes: 5 additions & 5 deletions frame/staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use frame_support::{
use sp_core::H256;
use sp_io;
use sp_npos_elections::{
build_support_map, evaluate_support, reduce, ExtendedBalance, StakedAssignment, ElectionScore,
to_support_map, EvaluateSupport, reduce, ExtendedBalance, StakedAssignment, ElectionScore,
};
use sp_runtime::{
curve::PiecewiseLinear,
Expand Down Expand Up @@ -850,8 +850,8 @@ pub(crate) fn horrible_npos_solution(
let score = {
let (_, _, better_score) = prepare_submission_with(true, true, 0, |_| {});

let support = build_support_map::<AccountId>(&winners, &staked_assignment).unwrap();
let score = evaluate_support(&support);
let support = to_support_map::<AccountId>(&winners, &staked_assignment).unwrap();
let score = support.evaluate();

assert!(sp_npos_elections::is_score_better::<Perbill>(
better_score,
Expand Down Expand Up @@ -950,11 +950,11 @@ pub(crate) fn prepare_submission_with(
Staking::slashable_balance_of_fn(),
);

let support_map = build_support_map::<AccountId>(
let support_map = to_support_map::<AccountId>(
winners.as_slice(),
staked.as_slice(),
).unwrap();
evaluate_support::<AccountId>(&support_map)
support_map.evaluate()
} else {
Default::default()
};
Expand Down
23 changes: 9 additions & 14 deletions frame/staking/src/offchain_election.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ use codec::Decode;
use frame_support::{traits::Get, weights::Weight, IterableStorageMap};
use frame_system::offchain::SubmitTransaction;
use sp_npos_elections::{
build_support_map, evaluate_support, reduce, Assignment, ElectionResult, ElectionScore,
ExtendedBalance,
to_support_map, EvaluateSupport, reduce, Assignment, ElectionResult, ElectionScore,
ExtendedBalance, CompactSolution,
};
use sp_runtime::{
offchain::storage::StorageValueRef, traits::TrailingZeroInput, PerThing, RuntimeDebug,
Expand Down Expand Up @@ -265,7 +265,7 @@ pub fn trim_to_weight<T: Config, FN>(
where
for<'r> FN: Fn(&'r T::AccountId) -> Option<NominatorIndex>,
{
match compact.len().checked_sub(maximum_allowed_voters as usize) {
match compact.voter_count().checked_sub(maximum_allowed_voters as usize) {
Some(to_remove) if to_remove > 0 => {
// grab all voters and sort them by least stake.
let balance_of = <Module<T>>::slashable_balance_of_fn();
Expand Down Expand Up @@ -300,7 +300,7 @@ where
warn,
"💸 {} nominators out of {} had to be removed from compact solution due to size limits.",
removed,
compact.len() + removed,
compact.voter_count() + removed,
);
Ok(compact)
}
Expand All @@ -324,12 +324,7 @@ pub fn prepare_submission<T: Config>(
do_reduce: bool,
maximum_weight: Weight,
) -> Result<
(
Vec<ValidatorIndex>,
CompactAssignments,
ElectionScore,
ElectionSize,
),
(Vec<ValidatorIndex>, CompactAssignments, ElectionScore, ElectionSize),
OffchainElectionError,
>
where
Expand Down Expand Up @@ -403,11 +398,11 @@ where
T::WeightInfo::submit_solution_better(
size.validators.into(),
size.nominators.into(),
compact.len() as u32,
compact.voter_count() as u32,
winners.len() as u32,
),
maximum_allowed_voters,
compact.len(),
compact.voter_count(),
);

let compact = trim_to_weight::<T, _>(maximum_allowed_voters, compact, &nominator_index)?;
Expand All @@ -423,9 +418,9 @@ where
<Module<T>>::slashable_balance_of_fn(),
);

let support_map = build_support_map::<T::AccountId>(&winners, &staked)
let support_map = to_support_map::<T::AccountId>(&winners, &staked)
.map_err(|_| OffchainElectionError::ElectionFailed)?;
evaluate_support::<T::AccountId>(&support_map)
support_map.evaluate()
};

// winners to index. Use a simple for loop for a more expressive early exit in case of error.
Expand Down
8 changes: 3 additions & 5 deletions frame/staking/src/testing_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,11 +244,9 @@ pub fn get_weak_solution<T: Config>(
<Module<T>>::slashable_balance_of_fn(),
);

let support_map = build_support_map::<T::AccountId>(
winners.as_slice(),
staked.as_slice(),
).unwrap();
evaluate_support::<T::AccountId>(&support_map)
let support_map =
to_support_map::<T::AccountId>(winners.as_slice(), staked.as_slice()).unwrap();
support_map.evaluate()
};

// compact encode the assignment.
Expand Down
33 changes: 33 additions & 0 deletions primitives/election-providers/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[package]
name = "sp-election-providers"
version = "2.0.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"
license = "Apache-2.0"
homepage = "https://substrate.dev"
repository = "https://github.com/paritytech/substrate/"
description = "Primitive election providers"
readme = "README.md"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false, features = ["derive"] }
sp-std = { version = "2.0.1", default-features = false, path = "../std" }
sp-arithmetic = { version = "2.0.1", default-features = false, path = "../arithmetic" }
sp-npos-elections = { version = "2.0.1", default-features = false, path = "../npos-elections" }

[dev-dependencies]
sp-npos-elections = { version = "2.0.1", path = "../npos-elections" }
sp-runtime = { version = "2.0.1", path = "../runtime" }

[features]
default = ["std"]
runtime-benchmarks = []
std = [
"codec/std",
"sp-std/std",
"sp-npos-elections/std",
"sp-arithmetic/std",
]
Loading