Skip to content

Commit 53047c4

Browse files
kianenigmaen
authored andcommitted
srml-module: Phragmen election (paritytech#3364)
* phragmen election module. * Add new files. * Some doc update * Update weights. * bump and a few nits. * Performance improvement. * Master.into() * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood <[email protected]> * Fix build * Some fixes. * Fix build. * Proper outgoing and runner-up managment. * Bit more sensical weight values. * Update srml/elections-phragmen/src/lib.rs * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood <[email protected]> * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood <[email protected]> * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood <[email protected]> * fix lock file * Fix build. * Remove runner-ups * Some refactors. * Add support for reporting voters. * Fix member check. * Remove equlize.rs * Update srml/elections-phragmen/src/lib.rs * Update srml/elections-phragmen/src/lib.rs * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood <[email protected]> * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood <[email protected]> * Bring back runner ups. * use decode_len * Better weight values. * Update bogus doc * Bump. * Update srml/elections-phragmen/src/lib.rs Co-Authored-By: Gavin Wood <[email protected]> * Review comments. * One more test * Fix tests * Fix build * .. and fix benchmarks. * Update srml/elections-phragmen/src/lib.rs * Version bump
1 parent 68e538e commit 53047c4

File tree

12 files changed

+1715
-45
lines changed

12 files changed

+1715
-45
lines changed

Cargo.lock

Lines changed: 42 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ members = [
8080
"srml/collective",
8181
"srml/democracy",
8282
"srml/elections",
83+
"srml/elections-phragmen",
8384
"srml/example",
8485
"srml/executive",
8586
"srml/finality-tracker",

core/phragmen/benches/phragmen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ fn do_phragmen(
110110
let mut supports = <SupportMap<u64>>::new();
111111
elected_stashes
112112
.iter()
113-
.map(|e| (e, to_votes(slashable_balance(e))))
113+
.map(|(e, _)| (e, to_votes(slashable_balance(e))))
114114
.for_each(|(e, s)| {
115115
let item = Support { own: s, total: s, ..Default::default() };
116116
supports.insert(e.clone(), item);

core/phragmen/src/lib.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,11 @@ pub struct Edge<AccountId> {
106106
pub type PhragmenAssignment<AccountId> = (AccountId, ExtendedBalance);
107107

108108
/// Final result of the phragmen election.
109+
#[cfg_attr(feature = "std", derive(Debug))]
109110
pub struct PhragmenResult<AccountId> {
110-
/// Just winners.
111-
pub winners: Vec<AccountId>,
111+
/// Just winners zipped with their approval stake. Note that the approval stake is merely the
112+
/// sub of their received stake and could be used for very basic sorting and approval voting.
113+
pub winners: Vec<(AccountId, ExtendedBalance)>,
112114
/// Individual assignments. for each tuple, the first elements is a voter and the second
113115
/// is the list of candidates that it supports.
114116
pub assignments: Vec<(AccountId, Vec<PhragmenAssignment<AccountId>>)>
@@ -166,7 +168,7 @@ pub fn elect<AccountId, Balance, FS, C>(
166168
<C as Convert<Balance, u64>>::convert(b) as ExtendedBalance;
167169

168170
// return structures
169-
let mut elected_candidates: Vec<AccountId>;
171+
let mut elected_candidates: Vec<(AccountId, ExtendedBalance)>;
170172
let mut assigned: Vec<(AccountId, Vec<PhragmenAssignment<AccountId>>)>;
171173

172174
// used to cache and access candidates index.
@@ -282,7 +284,7 @@ pub fn elect<AccountId, Balance, FS, C>(
282284
}
283285
}
284286

285-
elected_candidates.push(winner.who.clone());
287+
elected_candidates.push((winner.who.clone(), winner.approval_stake));
286288
} else {
287289
break
288290
}
@@ -292,8 +294,8 @@ pub fn elect<AccountId, Balance, FS, C>(
292294
for n in &mut voters {
293295
let mut assignment = (n.who.clone(), vec![]);
294296
for e in &mut n.edges {
295-
if let Some(c) = elected_candidates.iter().cloned().find(|c| *c == e.who) {
296-
if c != n.who {
297+
if let Some(c) = elected_candidates.iter().cloned().find(|(c, _)| *c == e.who) {
298+
if c.0 != n.who {
297299
let ratio = {
298300
// Full support. No need to calculate.
299301
if *n.load == *e.load { ACCURACY }

core/phragmen/src/mock.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub(crate) type AccountId = u64;
6969

7070
#[derive(Debug, Clone)]
7171
pub(crate) struct _PhragmenResult<A: Clone> {
72-
pub winners: Vec<A>,
72+
pub winners: Vec<(A, Balance)>,
7373
pub assignments: Vec<(A, Vec<_PhragmenAssignment<A>>)>
7474
}
7575

@@ -84,7 +84,7 @@ pub(crate) fn elect_float<A, FS>(
8484
A: Default + Ord + Member + Copy,
8585
for<'r> FS: Fn(&'r A) -> Balance,
8686
{
87-
let mut elected_candidates: Vec<A>;
87+
let mut elected_candidates: Vec<(A, Balance)>;
8888
let mut assigned: Vec<(A, Vec<_PhragmenAssignment<A>>)>;
8989
let mut c_idx_cache = BTreeMap::<A, usize>::new();
9090
let num_voters = initial_candidates.len() + initial_voters.len();
@@ -178,7 +178,7 @@ pub(crate) fn elect_float<A, FS>(
178178
}
179179
}
180180

181-
elected_candidates.push(winner.who.clone());
181+
elected_candidates.push((winner.who.clone(), winner.approval_stake as Balance));
182182
} else {
183183
break
184184
}
@@ -187,7 +187,7 @@ pub(crate) fn elect_float<A, FS>(
187187
for n in &mut voters {
188188
let mut assignment = (n.who.clone(), vec![]);
189189
for e in &mut n.edges {
190-
if let Some(c) = elected_candidates.iter().cloned().find(|c| *c == e.who) {
190+
if let Some(c) = elected_candidates.iter().cloned().map(|(c, _)| c).find(|c| *c == e.who) {
191191
if c != n.who {
192192
let ratio = e.load / n.load;
193193
assignment.1.push((e.who.clone(), ratio));
@@ -397,7 +397,7 @@ pub(crate) fn build_support_map<FS>(
397397
let mut supports = <_SupportMap<AccountId>>::new();
398398
result.winners
399399
.iter()
400-
.map(|e| (e, stake_of(e) as f64))
400+
.map(|(e, _)| (e, stake_of(e) as f64))
401401
.for_each(|(e, s)| {
402402
let item = _Support { own: s, total: s, ..Default::default() };
403403
supports.insert(e.clone(), item);

core/phragmen/src/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn float_phragmen_poc_works() {
3535
let winners = phragmen_result.clone().winners;
3636
let assignments = phragmen_result.clone().assignments;
3737

38-
assert_eq_uvec!(winners, vec![2, 3]);
38+
assert_eq_uvec!(winners, vec![(2, 40), (3, 50)]);
3939
assert_eq_uvec!(
4040
assignments,
4141
vec![
@@ -86,7 +86,7 @@ fn phragmen_poc_works() {
8686
false,
8787
).unwrap();
8888

89-
assert_eq_uvec!(winners, vec![2, 3]);
89+
assert_eq_uvec!(winners, vec![(2, 40), (3, 50)]);
9090
assert_eq_uvec!(
9191
assignments,
9292
vec![

node/runtime/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
8282
// and set impl_version to equal spec_version. If only runtime
8383
// implementation changes and behavior does not, then leave spec_version as
8484
// is and increment impl_version.
85-
spec_version: 158,
86-
impl_version: 160,
85+
spec_version: 159,
86+
impl_version: 159,
8787
apis: RUNTIME_API_VERSIONS,
8888
};
8989

srml/elections-phragmen/Cargo.toml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[package]
2+
name = "srml-elections-phragmen"
3+
version = "2.0.0"
4+
authors = ["Parity Technologies <[email protected]>"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
serde = { version = "1.0", optional = true }
9+
codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false, features = ["derive"] }
10+
primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false }
11+
runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false }
12+
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
13+
phragmen = { package = "substrate-phragmen", path = "../../core/phragmen", default-features = false }
14+
srml-support = { path = "../support", default-features = false }
15+
system = { package = "srml-system", path = "../system", default-features = false }
16+
rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false }
17+
18+
[dev-dependencies]
19+
hex-literal = "0.2.0"
20+
balances = { package = "srml-balances", path = "../balances" }
21+
22+
[features]
23+
default = ["std"]
24+
std = [
25+
"codec/std",
26+
"primitives/std",
27+
"serde",
28+
"runtime_io/std",
29+
"srml-support/std",
30+
"sr-primitives/std",
31+
"phragmen/std",
32+
"system/std",
33+
"rstd/std",
34+
]

0 commit comments

Comments
 (0)