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

Commit

Permalink
Decouple Stkaing and Election - Part1: Support traits (#7908)
Browse files Browse the repository at this point in the history
* Base features and traits.

* Fix the build

* Remove unused boxing

* Self review cleanup

* Fix build
  • Loading branch information
kianenigma authored Jan 18, 2021
1 parent d42240b commit 4ac74e9
Show file tree
Hide file tree
Showing 23 changed files with 921 additions and 337 deletions.
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 @@ -2105,7 +2106,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 @@ -2139,7 +2140,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 @@ -2601,13 +2602,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 @@ -2863,7 +2862,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 @@ -2902,7 +2901,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 @@ -2952,7 +2951,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 @@ -860,8 +860,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 @@ -960,11 +960,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

0 comments on commit 4ac74e9

Please sign in to comment.