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

Implement PJR checker #8160

Merged
38 commits merged into from
Mar 11, 2021
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
58f4b61
Apply.
kianenigma Aug 31, 2020
202981b
Merge remote-tracking branch 'origin/master' into prgn-npos-pjr
coriolinus Feb 18, 2021
12f4636
get rid of glob import
coriolinus Feb 18, 2021
834e675
use meaningful generic type name
coriolinus Feb 18, 2021
963f48c
pjr_check operates on `Supports` struct used elsewhere
coriolinus Feb 19, 2021
81a788a
improve algorithmic complexity of `prepare_pjr_input`
coriolinus Feb 19, 2021
dd83c66
fix rustdoc warnings
coriolinus Feb 19, 2021
0e15efb
improve module docs
coriolinus Feb 19, 2021
46a519d
typo
coriolinus Feb 19, 2021
d63ed93
simplify debug assertion
coriolinus Feb 19, 2021
158d01a
add test finding the phase-change threshold value for a constructed s…
coriolinus Feb 19, 2021
902c2df
add more threshold scenarios to disambiguate plausible interpretations
coriolinus Feb 19, 2021
4cff663
add link to npos paper reference
coriolinus Feb 19, 2021
c47eba6
docs: staked_assignment -> supports
coriolinus Feb 19, 2021
a129534
add utility method for generating npos inputs
coriolinus Feb 22, 2021
8049fcf
add a fuzzer which asserts that all unbalanced seq_phragmen are PJR
coriolinus Feb 22, 2021
2451a86
assert in all cases, not just debug
coriolinus Feb 22, 2021
1d4e2db
leverage a native solution to choose candidates
coriolinus Feb 22, 2021
fc64ff5
use existing helper methods
coriolinus Feb 22, 2021
f2f11bb
add pjr-check and incorporate into the fuzzer
coriolinus Feb 22, 2021
8d63aa4
fix compilation errors
coriolinus Feb 23, 2021
ba36529
Enable manually setting iteration parameters in single run.
coriolinus Feb 23, 2021
32da70d
update comment verbiage for accuracy
coriolinus Feb 25, 2021
6419d17
it is valid in PJR for an elected candidate to have 0 support
coriolinus Feb 25, 2021
e582b14
Fix phragmen_pjr fuzzer
coriolinus Mar 1, 2021
2f977df
restart ci; it appears to be stalled
coriolinus Mar 1, 2021
8cda3af
use necessary import for no-std
coriolinus Mar 1, 2021
9f928e3
use a more realistic distribution of voters and candidates
coriolinus Mar 2, 2021
9c7fb95
identify specifically which PJR check may fail
coriolinus Mar 2, 2021
06c0e8a
move candidate collection comment into correct place
coriolinus Mar 2, 2021
cabce8f
standard_threshold: use a calculation method which cannot overflow
coriolinus Mar 2, 2021
b761631
Apply suggestions from code review (update comments)
coriolinus Mar 2, 2021
eb94375
clarify the effectiveness bounds for t-pjr check
coriolinus Mar 2, 2021
30d83da
Merge remote-tracking branch 'origin/master' into prgn-npos-pjr
coriolinus Mar 3, 2021
cf6a96b
how to spell "committee"
coriolinus Mar 3, 2021
44c73ef
reorganize: high -> low abstraction
coriolinus Mar 3, 2021
f1721e0
ensure standard threshold calc cannot panic
coriolinus Mar 3, 2021
a98208f
Apply suggestions from code review
coriolinus Mar 11, 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
2 changes: 1 addition & 1 deletion frame/staking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2709,8 +2709,8 @@ impl<T: Config> Module<T> {
// write new results.
<QueuedElected<T>>::put(ElectionResult {
elected_stashes: winners,
compute,
exposures,
compute,
});
QueuedScore::put(submitted_score);

Expand Down
46 changes: 34 additions & 12 deletions primitives/npos-elections/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
//! - [`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.
//! - [`phragmms()`]: Implements a hybrid approach inspired by Phragmén which is executed faster but
//! it can achieve a constant factor approximation of the maximin problem, similar to that of the
//! MMS algorithm.
//! - [`balance`]: Implements the star balancing algorithm. This iterative process can push a
//! solution toward being more `balances`, which in turn can increase its score.
//! - [`phragmms`](phragmms::phragmms): Implements a hybrid approach inspired by Phragmén which is
//! executed faster but it can achieve a constant factor approximation of the maximin problem,
//! similar to that of the MMS algorithm.
//! - [`balance`](balancing::balance): Implements the star balancing algorithm. This iterative
//! process can push a solution toward being more "balanced", which in turn can increase its
//! score.
//!
//! ### Terminology
//!
Expand Down Expand Up @@ -98,18 +99,20 @@ mod mock;
#[cfg(test)]
mod tests;

mod phragmen;
mod balancing;
mod phragmms;
mod node;
mod reduce;
mod helpers;
pub mod phragmen;
pub mod balancing;
pub mod phragmms;
pub mod node;
pub mod reduce;
pub mod helpers;
pub mod pjr;

pub use reduce::reduce;
pub use helpers::*;
pub use phragmen::*;
pub use phragmms::*;
pub use balancing::*;
pub use pjr::*;

// re-export the compact macro, with the dependencies of the macro.
#[doc(hidden)]
Expand Down Expand Up @@ -282,6 +285,12 @@ pub struct Candidate<AccountId> {
round: usize,
}

impl<AccountId> Candidate<AccountId> {
pub fn to_ptr(self) -> CandidatePtr<AccountId> {
Rc::new(RefCell::new(self))
}
}

/// A vote being casted by a [`Voter`] to a [`Candidate`] is an `Edge`.
#[derive(Clone, Default)]
pub struct Edge<AccountId> {
Expand Down Expand Up @@ -326,6 +335,19 @@ impl<A: IdentifierT> std::fmt::Debug for Voter<A> {
}

impl<AccountId: IdentifierT> Voter<AccountId> {
/// Create a new `Voter`.
pub fn new(who: AccountId) -> Self {
Self { who, ..Default::default() }
}

coriolinus marked this conversation as resolved.
Show resolved Hide resolved

/// Returns `true` if `self` votes for `target`.
///
/// Note that this does not take into account if `target` is elected (i.e. is *active*) or not.
pub fn votes_for(&self, target: &AccountId) -> bool {
self.edges.iter().any(|e| &e.who == target)
}

/// Returns none if this voter does not have any non-zero distributions.
///
/// Note that this might create _un-normalized_ assignments, due to accuracy loss of `P`. Call
Expand Down Expand Up @@ -746,7 +768,7 @@ pub(crate) fn setup_inputs<AccountId: IdentifierT>(
.enumerate()
.map(|(idx, who)| {
c_idx_cache.insert(who.clone(), idx);
Rc::new(RefCell::new(Candidate { who, ..Default::default() }))
Candidate { who, ..Default::default() }.to_ptr()
})
.collect::<Vec<CandidatePtr<AccountId>>>();

Expand Down
Loading