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 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
476669d
build the template, hand it over to zeke now.
kianenigma Aug 29, 2021
1092963
Tests working
emostov Aug 30, 2021
45825e4
save wip
emostov Aug 31, 2021
7efe4ad
Merge branch 'master' of https://github.com/paritytech/substrate into…
emostov Aug 31, 2021
0396144
Some updates
emostov Aug 31, 2021
4081cd7
Merge branch 'master' of https://github.com/paritytech/substrate into…
emostov Aug 31, 2021
faf8647
Some cleanup
emostov Aug 31, 2021
68692f3
mo cleanin
emostov Aug 31, 2021
f404d4d
Link to issue
emostov Aug 31, 2021
8d34eba
Apply suggestions from code review
emostov Sep 1, 2021
a7f9a55
Apply suggestions from code review
emostov Sep 1, 2021
cac39c9
Apply suggestions from code review
emostov Sep 1, 2021
36915eb
Apply suggestions from code review
emostov Sep 1, 2021
bd3f4e9
Bound accuracy for prepare_election_result
emostov Sep 1, 2021
af52933
Use npos_election::Error for phragmms
emostov Sep 1, 2021
5b911ba
save
emostov Sep 1, 2021
bc43230
Apply suggestions from code review
emostov Sep 1, 2021
be84027
Simplify test to use Balancing::set
emostov Sep 1, 2021
d351624
Merge branch 'kiz-election-trait' of https://github.com/paritytech/su…
emostov Sep 1, 2021
f3a8de1
Try merge origin master
emostov Sep 5, 2021
7d726c8
Cargo.lock after build
emostov Sep 5, 2021
9c0a8e6
Revert "Cargo.lock after build"
emostov Sep 5, 2021
4622a9d
Try reduce cargo.lock diff
emostov Sep 5, 2021
44446e9
Update bin/node/runtime/src/lib.rs
emostov Sep 5, 2021
22678fd
Comment
emostov Sep 5, 2021
e749ce0
Apply suggestions from code review
emostov Sep 5, 2021
0cdda23
Set balancing directly
emostov Sep 7, 2021
68e6dae
Document som pub items
emostov Sep 7, 2021
b7ab21f
Merge branch 'kiz-election-trait' of https://github.com/paritytech/su…
emostov Sep 7, 2021
1fc657d
Update frame/election-provider-multi-phase/src/unsigned.rs
emostov Sep 7, 2021
0b1751c
Apply suggestions from code review
emostov Sep 7, 2021
f896242
Improve some comments
emostov Sep 7, 2021
e256252
Revert accidental change to random file
emostov Sep 7, 2021
4601b0b
Merge remote-tracking branch 'origin' into kiz-election-trait
emostov Sep 7, 2021
8a97010
Merge remote-tracking branch 'origin' into kiz-election-trait
emostov Sep 8, 2021
165db44
tiney
emostov Sep 9, 2021
65f5a51
revert
emostov Sep 9, 2021
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
Next Next commit
build the template, hand it over to zeke now.
  • Loading branch information
kianenigma committed Aug 29, 2021
commit 476669d75eb959ddb614e11b4e9c7f36429fddc6
73 changes: 72 additions & 1 deletion frame/election-provider-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,14 @@
#![cfg_attr(not(feature = "std"), no_std)]

pub mod onchain;
use frame_support::traits::Get;
use sp_std::{fmt::Debug, prelude::*};

/// Re-export some type as they are used in the interface.
pub use sp_arithmetic::PerThing;
pub use sp_npos_elections::{
Assignment, ExtendedBalance, PerThing128, Support, Supports, VoteWeight,
Assignment, ElectionResult, ExtendedBalance, IdentifierT, PerThing128, Support, Supports,
VoteWeight,
};

/// Types that are used by the data provider trait.
Expand Down Expand Up @@ -294,3 +296,72 @@ impl<AccountId, BlockNumber> ElectionProvider<AccountId, BlockNumber> for () {
Err("<() as ElectionProvider> cannot do anything.")
}
}

/// Anything that can compute the result to an NPoS solution
pub trait NposSolver {
/// The account identifier type of this solver.
type AccountId: sp_npos_elections::IdentifierT;
/// The accuracy of this solver. This will affect the accuracy of the output.
type Accuracy: PerThing128;
/// The error type of this implementation.
type Error;

/// Solve an npos solution with the given `voters`, `targets`, and select `to_elect` from
/// `targets`.
fn solve(
to_elect: usize,
targets: Vec<Self::AccountId>,
voters: Vec<(Self::AccountId, VoteWeight, Vec<Self::AccountId>)>,
) -> Result<ElectionResult<Self::AccountId, Self::Accuracy>, Self::Error>;
}

// TODO: zeke: get this to compile, then we need:

// 1. `type Solver: Solver` in `election-provider-multi-phase`
// 2. `fn mine_solution` and `mind_and_check` need to both become generic over `<S: Solver>` and use
// that instead of a hardcoded call into `seq_phragmen`
// 3. in offchain worker call path (`mine_checked_call` and above), use the `T::Solver` for this new
// generic. 4. in staking-miner, we call directly into `mine_solution` and `mine_and_check`, so we
// have the freedom to diverge from the runtime
// 5. proper companion and fixing of top level runtimes.
// 6. add very minimal config to the staking miner to be capable of running phragmms

/// A wrapper for [`sp_npos_elections::seq_phragmen`] that implements [`super::NposSolver`]. See the
/// documentation of [`sp_npos_elections::seq_phragmen`] for more info.
pub struct SequentialPhragmen<Balancing>(sp_std::marker::PhantomData<Balancing>);

impl<Balancing: Get<Option<(usize, ExtendedBalance)>>> NposSolver
for SequentialPhragmen<Balancing>
{
fn solve(
winners: usize,
targets: Vec<Self::AccountId>,
voters: Vec<(Self::AccountId, VoteWeight, Vec<Self::AccountId>)>,
) {
sp_npos_elections::seq_phragmen(winners, targets, voters, Balancing::get())
}
}

/// A wrapper for [`sp_npos_elections::phragmms`] that implements [`NposSolver`]. See the
/// documentation of [`sp_npos_elections::phragmms`] for more info.
pub struct PhragMMS<AccountId, Accuracy, Balancing>(
sp_std::marker::PhantomData<(AccountId, Accuracy, Balancing)>,
);

impl<
AccountId: IdentifierT,
Accuracy: PerThing128,
Balancing: Get<Option<(usize, ExtendedBalance)>>,
> NposSolver for PhragMMS<AccountId, Accuracy, Balancing>
{
type AccountId = AccountId;
type Accuracy = Accuracy;
type Error = &'static str; // TODO: probably best to move phragmms also into `sp_npos_elections::Error`
fn solve(
winners: usize,
targets: Vec<Self::AccountId>,
voters: Vec<(Self::AccountId, VoteWeight, Vec<Self::AccountId>)>,
) -> Result<ElectionResult<Self::AccountId, Self::Accuracy>, Self::Error> {
sp_npos_elections::phragmms(winners, targets, voters, Balancing::get())
}
}
2 changes: 1 addition & 1 deletion primitives/npos-elections/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ sp-std = { version = "4.0.0-dev", default-features = false, path = "../std" }
sp-npos-elections-solution-type = { version = "4.0.0-dev", path = "./solution-type" }
sp-arithmetic = { version = "4.0.0-dev", default-features = false, path = "../arithmetic" }
sp-core = { version = "4.0.0-dev", default-features = false, path = "../core" }
sp-runtime = { version = "4.0.0-dev", path = "../runtime" }

[dev-dependencies]
substrate-test-utils = { version = "4.0.0-dev", path = "../../test-utils" }
rand = "0.7.3"
sp-runtime = { version = "4.0.0-dev", path = "../runtime" }

[features]
default = ["std"]
Expand Down
20 changes: 10 additions & 10 deletions primitives/npos-elections/src/phragmen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,16 @@ const DEN: ExtendedBalance = ExtendedBalance::max_value();
/// check where t is the standard threshold. The underlying algorithm is sound, but the conversions
/// between numeric types can be lossy.
pub fn seq_phragmen<AccountId: IdentifierT, P: PerThing128>(
rounds: usize,
initial_candidates: Vec<AccountId>,
initial_voters: Vec<(AccountId, VoteWeight, Vec<AccountId>)>,
balance: Option<(usize, ExtendedBalance)>,
to_elect: usize,
candidates: Vec<AccountId>,
voters: Vec<(AccountId, VoteWeight, Vec<AccountId>)>,
balancing: Option<(usize, ExtendedBalance)>,
) -> Result<ElectionResult<AccountId, P>, crate::Error> {
let (candidates, voters) = setup_inputs(initial_candidates, initial_voters);
let (candidates, voters) = setup_inputs(candidates, voters);

let (candidates, mut voters) = seq_phragmen_core::<AccountId>(rounds, candidates, voters)?;
let (candidates, mut voters) = seq_phragmen_core::<AccountId>(to_elect, candidates, voters)?;

if let Some((iterations, tolerance)) = balance {
if let Some((iterations, tolerance)) = balancing {
// NOTE: might create zero-edges, but we will strip them again when we convert voter into
// assignment.
let _iters = balancing::balance::<AccountId>(&mut voters, iterations, tolerance);
Expand All @@ -87,7 +87,7 @@ pub fn seq_phragmen<AccountId: IdentifierT, P: PerThing128>(
.into_iter()
.filter(|c_ptr| c_ptr.borrow().elected)
// defensive only: seq-phragmen-core returns only up to rounds.
.take(rounds)
.take(to_elect)
.collect::<Vec<_>>();

// sort winners based on desirability.
Expand Down Expand Up @@ -116,12 +116,12 @@ pub fn seq_phragmen<AccountId: IdentifierT, P: PerThing128>(
/// This can only fail if the normalization fails.
// To create the inputs needed for this function, see [`crate::setup_inputs`].
pub fn seq_phragmen_core<AccountId: IdentifierT>(
rounds: usize,
to_elect: usize,
candidates: Vec<CandidatePtr<AccountId>>,
mut voters: Vec<Voter<AccountId>>,
) -> Result<(Vec<CandidatePtr<AccountId>>, Vec<Voter<AccountId>>), crate::Error> {
// we have already checked that we have more candidates than minimum_candidate_count.
let to_elect = rounds.min(candidates.len());
let to_elect = to_elect.min(candidates.len());

// main election loop
for round in 0..to_elect {
Expand Down
10 changes: 5 additions & 5 deletions primitives/npos-elections/src/phragmms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ use sp_std::{prelude::*, rc::Rc};
/// `expect` this to return `Ok`.
pub fn phragmms<AccountId: IdentifierT, P: PerThing128>(
to_elect: usize,
initial_candidates: Vec<AccountId>,
initial_voters: Vec<(AccountId, VoteWeight, Vec<AccountId>)>,
balancing_config: Option<(usize, ExtendedBalance)>,
candidates: Vec<AccountId>,
voters: Vec<(AccountId, VoteWeight, Vec<AccountId>)>,
balancing: Option<(usize, ExtendedBalance)>,
) -> Result<ElectionResult<AccountId, P>, &'static str> {
let (candidates, mut voters) = setup_inputs(initial_candidates, initial_voters);
let (candidates, mut voters) = setup_inputs(candidates, voters);

let mut winners = vec![];
for round in 0..to_elect {
Expand All @@ -58,7 +58,7 @@ pub fn phragmms<AccountId: IdentifierT, P: PerThing128>(
round_winner.borrow_mut().elected = true;
winners.push(round_winner);

if let Some((iterations, tolerance)) = balancing_config {
if let Some((iterations, tolerance)) = balancing {
balance(&mut voters, iterations, tolerance);
}
} else {
Expand Down