Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1b8afe7
Clean phragmen API and equalise()
kianenigma Mar 26, 2020
a7ebb44
Stabilize new api
kianenigma Mar 29, 2020
5e4daec
Fix phragmen fuzzers
kianenigma Mar 30, 2020
677a818
Master.into()
kianenigma Mar 30, 2020
fb4b183
More fixes
kianenigma Mar 30, 2020
be3333e
Master.into()
kianenigma Mar 31, 2020
11b020b
Make fuzzers reproducible
kianenigma Mar 31, 2020
ece1b27
improvements
kianenigma Mar 31, 2020
af8481e
Make equalize update assignments as well.
kianenigma Mar 31, 2020
2d6400a
total function for staked_assignment.
kianenigma Mar 31, 2020
4a37ce8
Merge branch 'master' of github.com:paritytech/substrate into kiz-cle…
kianenigma Apr 1, 2020
2ea5161
Fix fuzzer build
kianenigma Apr 1, 2020
877e095
Merge branch 'master' of github.com:paritytech/substrate into kiz-cle…
kianenigma Apr 2, 2020
f69f5ed
Merge branch 'master' of github.com:paritytech/substrate into kiz-cle…
kianenigma Apr 12, 2020
0058e30
remvoe TODO
kianenigma Apr 14, 2020
267254d
Fix a bunch more.
kianenigma Apr 14, 2020
7527bcc
Master.into()
kianenigma Apr 15, 2020
6bff5cf
clean stray debug stuff
kianenigma Apr 15, 2020
8e0cf52
Merge branch 'master' of github.com:paritytech/substrate into kiz-cle…
kianenigma Apr 16, 2020
763a28a
Update primitives/phragmen/src/lib.rs
kianenigma Apr 16, 2020
7a0f39e
fix range function
kianenigma Apr 16, 2020
cd91a0b
fix number generator
kianenigma Apr 16, 2020
f2fd743
Merge branch 'master' of github.com:paritytech/substrate into kiz-cle…
kianenigma Apr 17, 2020
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
23 changes: 22 additions & 1 deletion 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 @@ -133,6 +133,7 @@ members = [
"primitives/offchain",
"primitives/panic-handler",
"primitives/phragmen",
"primitives/phragmen/fuzzer",
"primitives/phragmen/compact",
"primitives/rpc",
"primitives/runtime-interface",
Expand Down
32 changes: 18 additions & 14 deletions frame/elections-phragmen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ use frame_support::{
ChangeMembers, OnUnbalanced, WithdrawReason, Contains, BalanceStatus, InitializeMembers,
}
};
use sp_phragmen::{build_support_map, ExtendedBalance};
use sp_phragmen::{build_support_map, ExtendedBalance, VoteWeight, PhragmenResult};
use frame_system::{self as system, ensure_signed, ensure_root};

const MODULE_ID: LockIdentifier = *b"phrelect";
Expand Down Expand Up @@ -123,7 +123,7 @@ pub trait Trait: frame_system::Trait {

/// Convert a balance into a number used for election calculation.
/// This must fit into a `u64` but is allowed to be sensibly lossy.
type CurrencyToVote: Convert<BalanceOf<Self>, u64> + Convert<u128, BalanceOf<Self>>;
type CurrencyToVote: Convert<BalanceOf<Self>, VoteWeight> + Convert<ExtendedBalance, BalanceOf<Self>>;

/// How much should be locked up in order to submit one's candidacy.
type CandidacyBond: Get<BalanceOf<Self>>;
Expand Down Expand Up @@ -703,17 +703,25 @@ impl<T: Trait> Module<T> {
// previous runners_up are also always candidates for the next round.
candidates.append(&mut Self::runners_up_ids());

// helper closures to deal with balance/stake.
let to_votes = |b: BalanceOf<T>| -> VoteWeight {
<T::CurrencyToVote as Convert<BalanceOf<T>, VoteWeight>>::convert(b)
};
let to_balance = |e: ExtendedBalance| -> BalanceOf<T> {
<T::CurrencyToVote as Convert<ExtendedBalance, BalanceOf<T>>>::convert(e)
};

let voters_and_votes = Voting::<T>::iter()
.map(|(voter, (stake, targets))| { (voter, stake, targets) })
.collect::<Vec<_>>();
let maybe_phragmen_result = sp_phragmen::elect::<_, _, T::CurrencyToVote, Perbill>(
let maybe_phragmen_result = sp_phragmen::elect::<T::AccountId, Perbill>(
num_to_elect,
0,
candidates,
voters_and_votes.clone(),
voters_and_votes.iter().cloned().map(|(v, s, t)| (v, to_votes(s), t)).collect::<Vec<_>>(),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gavofyork if it is okay to move your prime election code to use u64 (VoteWeight) instead of BalanceOf<T> then this extra clone of all voters can be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed it for now, correct me if it is wrong.

);

if let Some(phragmen_result) = maybe_phragmen_result {
if let Some(PhragmenResult { winners, assignments }) = maybe_phragmen_result {
let old_members_ids = <Members<T>>::take().into_iter()
.map(|(m, _)| m)
.collect::<Vec<T::AccountId>>();
Expand All @@ -726,26 +734,22 @@ impl<T: Trait> Module<T> {
// vote are still considered by phragmen and when good candidates are scarce, then these
// cheap ones might get elected. We might actually want to remove the filter and allow
// zero-voted candidates to also make it to the membership set.
let new_set_with_approval = phragmen_result.winners;
let new_set_with_approval = winners;
let new_set = new_set_with_approval
.into_iter()
.filter_map(|(m, a)| if a.is_zero() { None } else { Some(m) } )
.collect::<Vec<T::AccountId>>();

let stake_of = |who: &T::AccountId| -> ExtendedBalance {
<T::CurrencyToVote as Convert<BalanceOf<T>, u64>>::convert(
Self::locked_stake_of(who)
) as ExtendedBalance
let stake_of = |who: &T::AccountId| -> u64 {
to_votes(Self::locked_stake_of(who))
};
let staked_assignments = sp_phragmen::assignment_ratio_to_staked(
phragmen_result.assignments,
assignments,
stake_of,
);

let (support_map, _) = build_support_map::<T::AccountId>(&new_set, &staked_assignments);

let to_balance = |e: ExtendedBalance|
<T::CurrencyToVote as Convert<ExtendedBalance, BalanceOf<T>>>::convert(e);
let new_set_with_stake = new_set
.into_iter()
.map(|ref m| {
Expand All @@ -766,7 +770,7 @@ impl<T: Trait> Module<T> {
// save the members, sorted based on account id.
new_members.sort_by(|i, j| i.0.cmp(&j.0));

let mut prime_votes: Vec<_> = new_members.iter().map(|c| (&c.0, BalanceOf::<T>::zero())).collect();
let mut prime_votes: Vec<_> = new_members.iter().map(|c| (&c.0, <BalanceOf<T>>::zero())).collect();
for (_, stake, targets) in voters_and_votes.into_iter() {
for (votes, who) in targets.iter()
.enumerate()
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 @@ -307,7 +307,7 @@ use frame_system::{
};
use sp_phragmen::{
ExtendedBalance, Assignment, PhragmenScore, PhragmenResult, build_support_map, evaluate_support,
elect, generate_compact_solution_type, is_score_better, VotingLimit, SupportMap,
elect, generate_compact_solution_type, is_score_better, VotingLimit, SupportMap, VoteWeight,
};

const DEFAULT_MINIMUM_VALIDATOR_COUNT: u32 = 4;
Expand Down Expand Up @@ -736,12 +736,11 @@ pub trait Trait: frame_system::Trait {
/// is not used.
type UnixTime: UnixTime;

/// Convert a balance into a number used for election calculation.
/// This must fit into a `u64` but is allowed to be sensibly lossy.
/// TODO: #1377
/// The backward convert should be removed as the new Phragmen API returns ratio.
/// The post-processing needs it but will be moved to off-chain. TODO: #2908
type CurrencyToVote: Convert<BalanceOf<Self>, u64> + Convert<u128, BalanceOf<Self>>;
/// Convert a balance into a number used for election calculation. This must fit into a `u64`
/// but is allowed to be sensibly lossy. The `u64` is used to communicate with the
/// [`sp_phragmen`] crate which accepts u64 numbers and does operations in 128. Consequently,
/// the backward convert is used convert the u128s from phragmen back to a balance.
type CurrencyToVote: Convert<BalanceOf<Self>, VoteWeight> + Convert<u128, BalanceOf<Self>>;

/// Tokens have been minted and are unused for validator-reward.
type RewardRemainder: OnUnbalanced<NegativeImbalanceOf<Self>>;
Expand Down Expand Up @@ -1852,7 +1851,7 @@ decl_module! {
/// - Memory: O(n + m) reads to map index to `AccountId` for un-compact.
///
/// - Storage: O(e) accountid reads from `Nomination` to read correct nominations.
/// - Storage: O(e) calls into `slashable_balance_of_extended` to convert ratio to staked.
/// - Storage: O(e) calls into `slashable_balance_of_vote_weight` to convert ratio to staked.
///
/// - Memory: build_support_map. O(e).
/// - Memory: evaluate_support: O(E).
Expand Down Expand Up @@ -1952,11 +1951,11 @@ impl<T: Trait> Module<T> {
Self::bonded(stash).and_then(Self::ledger).map(|l| l.active).unwrap_or_default()
}

/// internal impl of [`slashable_balance_of`] that returns [`ExtendedBalance`].
fn slashable_balance_of_extended(stash: &T::AccountId) -> ExtendedBalance {
<T::CurrencyToVote as Convert<BalanceOf<T>, u64>>::convert(
/// internal impl of [`slashable_balance_of`] that returns [`VoteWeight`].
fn slashable_balance_of_vote_weight(stash: &T::AccountId) -> VoteWeight {
<T::CurrencyToVote as Convert<BalanceOf<T>, VoteWeight>>::convert(
Self::slashable_balance_of(stash)
) as ExtendedBalance
)
}

/// Dump the list of validators and nominators into vectors and keep them on-chain.
Expand Down Expand Up @@ -2455,7 +2454,7 @@ impl<T: Trait> Module<T> {
// convert into staked assignments.
let staked_assignments = sp_phragmen::assignment_ratio_to_staked(
assignments,
Self::slashable_balance_of_extended,
Self::slashable_balance_of_vote_weight,
);

// build the support map thereof in order to evaluate.
Expand Down Expand Up @@ -2710,7 +2709,7 @@ impl<T: Trait> Module<T> {

let staked_assignments = sp_phragmen::assignment_ratio_to_staked(
assignments,
Self::slashable_balance_of_extended,
Self::slashable_balance_of_vote_weight,
);

let (supports, _) = build_support_map::<T::AccountId>(
Expand Down Expand Up @@ -2746,11 +2745,11 @@ impl<T: Trait> Module<T> {
///
/// No storage item is updated.
fn do_phragmen<Accuracy: PerThing>() -> Option<PhragmenResult<T::AccountId, Accuracy>> {
let mut all_nominators: Vec<(T::AccountId, BalanceOf<T>, Vec<T::AccountId>)> = Vec::new();
let mut all_nominators: Vec<(T::AccountId, VoteWeight, Vec<T::AccountId>)> = Vec::new();
let mut all_validators = Vec::new();
for (validator, _) in <Validators<T>>::iter() {
// append self vote
let self_vote = (validator.clone(), Self::slashable_balance_of(&validator), vec![validator.clone()]);
let self_vote = (validator.clone(), Self::slashable_balance_of_vote_weight(&validator), vec![validator.clone()]);
all_nominators.push(self_vote);
all_validators.push(validator);
}
Expand All @@ -2770,11 +2769,11 @@ impl<T: Trait> Module<T> {
(nominator, targets)
});
all_nominators.extend(nominator_votes.map(|(n, ns)| {
let s = Self::slashable_balance_of(&n);
let s = Self::slashable_balance_of_vote_weight(&n);
(n, s, ns)
}));

elect::<_, _, T::CurrencyToVote, Accuracy>(
elect::<_, Accuracy>(
Self::validator_count() as usize,
Self::minimum_validator_count().max(1) as usize,
all_validators,
Expand Down
9 changes: 5 additions & 4 deletions frame/staking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use frame_system::offchain::TransactionSubmitter;
use sp_io;
use sp_phragmen::{
build_support_map, evaluate_support, reduce, ExtendedBalance, StakedAssignment, PhragmenScore,
VoteWeight,
};
use crate::*;

Expand Down Expand Up @@ -837,10 +838,10 @@ pub(crate) fn prepare_submission_with(
} = Staking::do_phragmen::<OffchainAccuracy>().unwrap();
let winners = winners.into_iter().map(|(w, _)| w).collect::<Vec<AccountId>>();

let stake_of = |who: &AccountId| -> ExtendedBalance {
<CurrencyToVoteHandler as Convert<Balance, u64>>::convert(
let stake_of = |who: &AccountId| -> VoteWeight {
<CurrencyToVoteHandler as Convert<Balance, VoteWeight>>::convert(
Staking::slashable_balance_of(&who)
) as ExtendedBalance
)
};
let mut staked = sp_phragmen::assignment_ratio_to_staked(assignments, stake_of);

Expand Down Expand Up @@ -879,7 +880,7 @@ pub(crate) fn prepare_submission_with(
let score = {
let staked = sp_phragmen::assignment_ratio_to_staked(
assignments_reduced.clone(),
Staking::slashable_balance_of_extended,
Staking::slashable_balance_of_vote_weight,
);

let (support_map, _) = build_support_map::<AccountId>(
Expand Down
4 changes: 2 additions & 2 deletions frame/staking/src/offchain_election.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ pub fn prepare_submission<T: Trait>(
// convert into absolute value and to obtain the reduced version.
let mut staked = sp_phragmen::assignment_ratio_to_staked(
assignments,
<Module<T>>::slashable_balance_of_extended,
<Module<T>>::slashable_balance_of_vote_weight,
);

if do_reduce {
Expand All @@ -188,7 +188,7 @@ pub fn prepare_submission<T: Trait>(
let score = {
let staked = sp_phragmen::assignment_ratio_to_staked(
low_accuracy_assignment.clone(),
<Module<T>>::slashable_balance_of_extended,
<Module<T>>::slashable_balance_of_vote_weight,
);

let (support_map, _) = build_support_map::<T::AccountId>(&winners, &staked);
Expand Down
4 changes: 2 additions & 2 deletions primitives/phragmen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ description = "Phragmen primitives"
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-alpha.5", default-features = false, path = "../std" }
sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../../primitives/runtime" }
sp-runtime = { version = "2.0.0-alpha.5", default-features = false, path = "../runtime" }
sp-phragmen-compact = { version = "2.0.0-alpha.4", path = "./compact" }

[dev-dependencies]
substrate-test-utils = { version = "2.0.0-alpha.5", path = "../../test-utils" }
rand = "0.7.3"
rand = { version = "0.7.3" }
sp-phragmen = { path = "." }

[features]
Expand Down
Loading