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
126
127
128
129
130
131
132
133
134
135
136
use crate::shared;
use pallet_staking::SessionInterface;
use primitives::v1::ValidatorIndex;
pub const BACKING_POINTS: u32 = 20;
pub struct RewardValidatorsWithEraPoints<C>(sp_std::marker::PhantomData<C>);
fn validators_to_reward<C, T, I>(
validators: &'_ [T],
indirect_indices: I,
) -> impl IntoIterator<Item = &'_ T>
where
C: shared::Config,
I: IntoIterator<Item = ValidatorIndex>,
{
let validator_indirection = <shared::Pallet<C>>::active_validator_indices();
indirect_indices
.into_iter()
.filter_map(move |i| validator_indirection.get(i.0 as usize).map(|v| v.clone()))
.filter_map(move |i| validators.get(i.0 as usize))
}
impl<C> crate::inclusion::RewardValidators for RewardValidatorsWithEraPoints<C>
where
C: pallet_staking::Config + shared::Config,
{
fn reward_backing(indirect_indices: impl IntoIterator<Item = ValidatorIndex>) {
let validators = C::SessionInterface::validators();
let rewards = validators_to_reward::<C, _, _>(&validators, indirect_indices)
.into_iter()
.map(|v| (v.clone(), BACKING_POINTS));
<pallet_staking::Pallet<C>>::reward_by_ids(rewards);
}
fn reward_bitfields(_validators: impl IntoIterator<Item = ValidatorIndex>) {}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
configuration::HostConfiguration,
mock::{new_test_ext, MockGenesisConfig, ParasShared, Test},
};
use keyring::Sr25519Keyring;
use primitives::v1::ValidatorId;
#[test]
fn rewards_based_on_indirection() {
let validators = vec![
Sr25519Keyring::Alice,
Sr25519Keyring::Bob,
Sr25519Keyring::Charlie,
Sr25519Keyring::Dave,
Sr25519Keyring::Ferdie,
];
fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec<ValidatorId> {
val_ids.iter().map(|v| v.public().into()).collect()
}
new_test_ext(MockGenesisConfig::default()).execute_with(|| {
let mut config = HostConfiguration::default();
config.max_validators = None;
let pubkeys = validator_pubkeys(&validators);
let shuffled_pubkeys =
ParasShared::initializer_on_new_session(1, [1; 32], &config, pubkeys);
assert_eq!(
shuffled_pubkeys,
validator_pubkeys(&[
Sr25519Keyring::Ferdie,
Sr25519Keyring::Bob,
Sr25519Keyring::Charlie,
Sr25519Keyring::Dave,
Sr25519Keyring::Alice,
])
);
assert_eq!(
ParasShared::active_validator_indices(),
vec![
ValidatorIndex(4),
ValidatorIndex(1),
ValidatorIndex(2),
ValidatorIndex(3),
ValidatorIndex(0),
]
);
assert_eq!(
validators_to_reward::<Test, _, _>(
&validators,
vec![ValidatorIndex(0), ValidatorIndex(1), ValidatorIndex(2)],
)
.into_iter()
.copied()
.collect::<Vec<_>>(),
vec![Sr25519Keyring::Ferdie, Sr25519Keyring::Bob, Sr25519Keyring::Charlie],
);
})
}
}