pallet_election_provider_multi_phase/
helpers.rs1use crate::{
21 unsigned::{MinerConfig, MinerVoterOf},
22 SolutionTargetIndexOf, SolutionVoterIndexOf, VoteWeight,
23};
24use alloc::{collections::btree_map::BTreeMap, vec::Vec};
25
26#[macro_export]
27macro_rules! log {
28 ($level:tt, $pattern:expr $(, $values:expr)* $(,)?) => {
29 log::$level!(
30 target: $crate::LOG_TARGET,
31 concat!("[#{:?}] 🗳 ", $pattern), frame_system::Pallet::<T>::block_number() $(, $values)*
32 )
33 };
34}
35
36#[macro_export]
38macro_rules! log_no_system {
39 ($level:tt, $pattern:expr $(, $values:expr)* $(,)?) => {
40 log::$level!(
41 target: $crate::LOG_TARGET,
42 concat!("🗳 ", $pattern) $(, $values)*
43 )
44 };
45}
46
47pub fn generate_voter_cache<T: MinerConfig>(
51 snapshot: &Vec<MinerVoterOf<T>>,
52) -> BTreeMap<T::AccountId, usize> {
53 let mut cache: BTreeMap<T::AccountId, usize> = BTreeMap::new();
54 snapshot.iter().enumerate().for_each(|(i, (x, _, _))| {
55 let _existed = cache.insert(x.clone(), i);
56 debug_assert!(_existed.is_none());
59 });
60
61 cache
62}
63
64pub fn voter_index_fn<T: MinerConfig>(
72 cache: &BTreeMap<T::AccountId, usize>,
73) -> impl Fn(&T::AccountId) -> Option<SolutionVoterIndexOf<T>> + '_ {
74 move |who| {
75 cache
76 .get(who)
77 .and_then(|i| <usize as TryInto<SolutionVoterIndexOf<T>>>::try_into(*i).ok())
78 }
79}
80
81pub fn voter_index_fn_owned<T: MinerConfig>(
86 cache: BTreeMap<T::AccountId, usize>,
87) -> impl Fn(&T::AccountId) -> Option<SolutionVoterIndexOf<T>> {
88 move |who| {
89 cache
90 .get(who)
91 .and_then(|i| <usize as TryInto<SolutionVoterIndexOf<T>>>::try_into(*i).ok())
92 }
93}
94
95pub fn voter_index_fn_usize<T: MinerConfig>(
101 cache: &BTreeMap<T::AccountId, usize>,
102) -> impl Fn(&T::AccountId) -> Option<usize> + '_ {
103 move |who| cache.get(who).cloned()
104}
105
106#[cfg(test)]
113pub fn voter_index_fn_linear<T: MinerConfig>(
114 snapshot: &Vec<MinerVoterOf<T>>,
115) -> impl Fn(&T::AccountId) -> Option<SolutionVoterIndexOf<T>> + '_ {
116 move |who| {
117 snapshot
118 .iter()
119 .position(|(x, _, _)| x == who)
120 .and_then(|i| <usize as TryInto<SolutionVoterIndexOf<T>>>::try_into(i).ok())
121 }
122}
123
124pub fn target_index_fn<T: MinerConfig>(
132 snapshot: &Vec<T::AccountId>,
133) -> impl Fn(&T::AccountId) -> Option<SolutionTargetIndexOf<T>> + '_ {
134 let cache: BTreeMap<_, _> =
135 snapshot.iter().enumerate().map(|(idx, account_id)| (account_id, idx)).collect();
136 move |who| {
137 cache
138 .get(who)
139 .and_then(|i| <usize as TryInto<SolutionTargetIndexOf<T>>>::try_into(*i).ok())
140 }
141}
142
143#[cfg(test)]
151pub fn target_index_fn_linear<T: MinerConfig>(
152 snapshot: &Vec<T::AccountId>,
153) -> impl Fn(&T::AccountId) -> Option<SolutionTargetIndexOf<T>> + '_ {
154 move |who| {
155 snapshot
156 .iter()
157 .position(|x| x == who)
158 .and_then(|i| <usize as TryInto<SolutionTargetIndexOf<T>>>::try_into(i).ok())
159 }
160}
161
162pub fn voter_at_fn<T: MinerConfig>(
165 snapshot: &Vec<MinerVoterOf<T>>,
166) -> impl Fn(SolutionVoterIndexOf<T>) -> Option<T::AccountId> + '_ {
167 move |i| {
168 <SolutionVoterIndexOf<T> as TryInto<usize>>::try_into(i)
169 .ok()
170 .and_then(|i| snapshot.get(i).map(|(x, _, _)| x).cloned())
171 }
172}
173
174pub fn target_at_fn<T: MinerConfig>(
177 snapshot: &Vec<T::AccountId>,
178) -> impl Fn(SolutionTargetIndexOf<T>) -> Option<T::AccountId> + '_ {
179 move |i| {
180 <SolutionTargetIndexOf<T> as TryInto<usize>>::try_into(i)
181 .ok()
182 .and_then(|i| snapshot.get(i).cloned())
183 }
184}
185
186#[cfg(test)]
190pub fn stake_of_fn_linear<T: MinerConfig>(
191 snapshot: &Vec<MinerVoterOf<T>>,
192) -> impl Fn(&T::AccountId) -> VoteWeight + '_ {
193 move |who| {
194 snapshot
195 .iter()
196 .find(|(x, _, _)| x == who)
197 .map(|(_, x, _)| *x)
198 .unwrap_or_default()
199 }
200}
201
202pub fn stake_of_fn<'a, T: MinerConfig>(
209 snapshot: &'a Vec<MinerVoterOf<T>>,
210 cache: &'a BTreeMap<T::AccountId, usize>,
211) -> impl Fn(&T::AccountId) -> VoteWeight + 'a {
212 move |who| {
213 if let Some(index) = cache.get(who) {
214 snapshot.get(*index).map(|(_, x, _)| x).cloned().unwrap_or_default()
215 } else {
216 0
217 }
218 }
219}