1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use crate::{Assignment, IdentifierT, IndexAssignmentOf, PerThing128, VoteWeight};
use codec::Encode;
use scale_info::TypeInfo;
use sp_arithmetic::traits::{Bounded, UniqueSaturatedInto};
use sp_npos_elections::{ElectionScore, Error, EvaluateSupport};
use sp_std::{fmt::Debug, prelude::*};
pub trait NposSolution
where
Self: Sized + for<'a> TryFrom<&'a [IndexAssignmentOf<Self>], Error = Error>,
{
const LIMIT: usize;
type VoterIndex: UniqueSaturatedInto<usize>
+ TryInto<usize>
+ TryFrom<usize>
+ Debug
+ Copy
+ Clone
+ Bounded
+ Encode
+ TypeInfo;
type TargetIndex: UniqueSaturatedInto<usize>
+ TryInto<usize>
+ TryFrom<usize>
+ Debug
+ Copy
+ Clone
+ Bounded
+ Encode
+ TypeInfo;
type Accuracy: PerThing128;
fn voter_count(&self) -> usize;
fn edge_count(&self) -> usize;
fn unique_targets(&self) -> Vec<Self::TargetIndex>;
fn average_edge_count(&self) -> usize {
self.edge_count().checked_div(self.voter_count()).unwrap_or(0)
}
fn score<A, FS>(
self,
stake_of: FS,
voter_at: impl Fn(Self::VoterIndex) -> Option<A>,
target_at: impl Fn(Self::TargetIndex) -> Option<A>,
) -> Result<ElectionScore, Error>
where
for<'r> FS: Fn(&'r A) -> VoteWeight,
A: IdentifierT,
{
let ratio = self.into_assignment(voter_at, target_at)?;
let staked =
sp_npos_elections::helpers::assignment_ratio_to_staked_normalized(ratio, stake_of)?;
let supports = sp_npos_elections::to_supports(&staked);
Ok(supports.evaluate())
}
fn remove_voter(&mut self, to_remove: Self::VoterIndex) -> bool;
fn from_assignment<FV, FT, A>(
assignments: &[Assignment<A, Self::Accuracy>],
voter_index: FV,
target_index: FT,
) -> Result<Self, Error>
where
A: IdentifierT,
for<'r> FV: Fn(&'r A) -> Option<Self::VoterIndex>,
for<'r> FT: Fn(&'r A) -> Option<Self::TargetIndex>;
fn into_assignment<A: IdentifierT>(
self,
voter_at: impl Fn(Self::VoterIndex) -> Option<A>,
target_at: impl Fn(Self::TargetIndex) -> Option<A>,
) -> Result<Vec<Assignment<A, Self::Accuracy>>, Error>;
}