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
use crate::{
Assignment, Error, IdentifierT, PerThing128, StakedAssignment, VoteWeight, WithApprovalOf,
};
use sp_arithmetic::PerThing;
use sp_std::prelude::*;
pub fn assignment_ratio_to_staked<A: IdentifierT, P: PerThing128, FS>(
ratios: Vec<Assignment<A, P>>,
stake_of: FS,
) -> Vec<StakedAssignment<A>>
where
for<'r> FS: Fn(&'r A) -> VoteWeight,
{
ratios
.into_iter()
.map(|a| {
let stake = stake_of(&a.who);
a.into_staked(stake.into())
})
.collect()
}
pub fn assignment_ratio_to_staked_normalized<A: IdentifierT, P: PerThing128, FS>(
ratio: Vec<Assignment<A, P>>,
stake_of: FS,
) -> Result<Vec<StakedAssignment<A>>, Error>
where
for<'r> FS: Fn(&'r A) -> VoteWeight,
{
let mut staked = assignment_ratio_to_staked(ratio, &stake_of);
staked
.iter_mut()
.map(|a| {
a.try_normalize(stake_of(&a.who).into())
.map_err(|err| Error::ArithmeticError(err))
})
.collect::<Result<_, _>>()?;
Ok(staked)
}
pub fn assignment_staked_to_ratio<A: IdentifierT, P: PerThing>(
staked: Vec<StakedAssignment<A>>,
) -> Vec<Assignment<A, P>> {
staked.into_iter().map(|a| a.into_assignment()).collect()
}
pub fn assignment_staked_to_ratio_normalized<A: IdentifierT, P: PerThing128>(
staked: Vec<StakedAssignment<A>>,
) -> Result<Vec<Assignment<A, P>>, Error> {
let mut ratio = staked.into_iter().map(|a| a.into_assignment()).collect::<Vec<_>>();
for assignment in ratio.iter_mut() {
assignment.try_normalize().map_err(|err| Error::ArithmeticError(err))?;
}
Ok(ratio)
}
pub fn to_without_backing<A: IdentifierT>(winners: Vec<WithApprovalOf<A>>) -> Vec<A> {
winners.into_iter().map(|(who, _)| who).collect::<Vec<A>>()
}
#[cfg(test)]
mod tests {
use super::*;
use sp_arithmetic::Perbill;
#[test]
fn into_staked_works() {
let assignments = vec![
Assignment {
who: 1u32,
distribution: vec![
(10u32, Perbill::from_float(0.5)),
(20, Perbill::from_float(0.5)),
],
},
Assignment {
who: 2u32,
distribution: vec![
(10, Perbill::from_float(0.33)),
(20, Perbill::from_float(0.67)),
],
},
];
let stake_of = |_: &u32| -> VoteWeight { 100 };
let staked = assignment_ratio_to_staked(assignments, stake_of);
assert_eq!(
staked,
vec![
StakedAssignment { who: 1u32, distribution: vec![(10u32, 50), (20, 50),] },
StakedAssignment { who: 2u32, distribution: vec![(10u32, 33), (20, 67),] }
]
);
}
}