pallet_bags_list_remote_tests/
lib.rs1use frame_election_provider_support::ScoreProvider;
21use pallet_bags_list::Instance1;
22
23pub const LOG_TARGET: &str = "runtime::bags-list::remote-tests";
25
26pub mod migration;
27pub mod snapshot;
28pub mod try_state;
29
30pub trait RuntimeT<I: 'static>:
34 pallet_staking::Config + pallet_bags_list::Config<I> + frame_system::Config
35{
36}
37impl<
38 I: 'static,
39 T: pallet_staking::Config + pallet_bags_list::Config<I> + frame_system::Config,
40 > RuntimeT<I> for T
41{
42}
43
44fn percent(portion: u32, total: u32) -> f64 {
45 (portion as f64 / total as f64) * 100f64
46}
47
48pub fn display_and_check_bags<Runtime: RuntimeT<Instance1>>(
50 currency_unit: u64,
51 currency_name: &'static str,
52) {
53 use frame_election_provider_support::SortedListProvider;
54 use frame_support::traits::Get;
55
56 let min_nominator_bond = <pallet_staking::MinNominatorBond<Runtime>>::get();
57 log::info!(target: LOG_TARGET, "min nominator bond is {:?}", min_nominator_bond);
58
59 let voter_list_count = <Runtime as pallet_staking::Config>::VoterList::count();
60
61 let mut seen_in_bags = 0;
64 let mut rebaggable = 0;
65 let mut active_bags = 0;
66 for vote_weight_thresh in <Runtime as pallet_bags_list::Config<Instance1>>::BagThresholds::get()
67 {
68 let vote_weight_thresh_u64: u64 = (*vote_weight_thresh)
69 .try_into()
70 .map_err(|_| "runtime must configure score to at most u64 to use this test")
71 .unwrap();
72 let vote_weight_thresh_as_unit = vote_weight_thresh_u64 as f64 / currency_unit as f64;
74 let pretty_thresh = format!("Threshold: {}. {}", vote_weight_thresh_as_unit, currency_name);
75
76 let bag = match pallet_bags_list::Pallet::<Runtime, Instance1>::list_bags_get(
77 *vote_weight_thresh,
78 ) {
79 Some(bag) => bag,
80 None => {
81 log::info!(target: LOG_TARGET, "{} NO VOTERS.", pretty_thresh);
82 continue
83 },
84 };
85
86 active_bags += 1;
87
88 for id in bag.std_iter().map(|node| node.std_id().clone()) {
89 let vote_weight =
90 <Runtime as pallet_bags_list::Config<Instance1>>::ScoreProvider::score(&id)
91 .unwrap();
92 let vote_weight_thresh_u64: u64 = (*vote_weight_thresh)
93 .try_into()
94 .map_err(|_| "runtime must configure score to at most u64 to use this test")
95 .unwrap();
96 let vote_weight_as_balance: pallet_staking::BalanceOf<Runtime> =
97 vote_weight_thresh_u64.try_into().map_err(|_| "can't convert").unwrap();
98
99 if vote_weight_as_balance < min_nominator_bond {
100 log::trace!(
101 target: LOG_TARGET,
102 "⚠️ {} Account found below min bond: {:?}.",
103 pretty_thresh,
104 id
105 );
106 }
107
108 let node = pallet_bags_list::Node::<Runtime, Instance1>::get(&id)
109 .expect("node in bag must exist.");
110 if node.is_misplaced(vote_weight) {
111 rebaggable += 1;
112 let notional_bag = pallet_bags_list::notional_bag_for::<Runtime, _>(vote_weight);
113 let notional_bag_as_u64: u64 = notional_bag
114 .try_into()
115 .map_err(|_| "runtime must configure score to at most u64 to use this test")
116 .unwrap();
117 log::trace!(
118 target: LOG_TARGET,
119 "Account {:?} can be rebagged from {:?} to {:?}",
120 id,
121 vote_weight_thresh_as_unit,
122 notional_bag_as_u64 as f64 / currency_unit as f64
123 );
124 }
125 }
126
127 let voters_in_bag = bag.std_iter().count() as u32;
129 seen_in_bags += voters_in_bag;
130
131 let percent_of_voters = percent(voters_in_bag, voter_list_count);
133
134 log::info!(
135 target: LOG_TARGET,
136 "{} Nominators: {} [%{:.3}]",
137 pretty_thresh,
138 voters_in_bag,
139 percent_of_voters,
140 );
141 }
142
143 if seen_in_bags != voter_list_count {
144 log::error!(
145 target: LOG_TARGET,
146 "bags list population ({}) not on par whoever is voter_list ({})",
147 seen_in_bags,
148 voter_list_count,
149 )
150 }
151
152 log::info!(
153 target: LOG_TARGET,
154 "a total of {} nodes are in {} active bags [{} total bags], {} of which can be rebagged.",
155 voter_list_count,
156 active_bags,
157 <Runtime as pallet_bags_list::Config<Instance1>>::BagThresholds::get().len(),
158 rebaggable,
159 );
160}