polkadot_runtime_common/
try_runtime.rs1use alloc::{collections::btree_set::BTreeSet, vec::Vec};
20use frame_support::{
21 dispatch::RawOrigin,
22 traits::{Get, Hooks},
23};
24use pallet_fast_unstake::{Pallet as FastUnstake, *};
25use pallet_staking::*;
26
27pub fn migrate_all_inactive_nominators<T: pallet_fast_unstake::Config + pallet_staking::Config>()
30where
31 <T as frame_system::Config>::RuntimeEvent: TryInto<pallet_fast_unstake::Event<T>>,
32{
33 let mut unstaked_ok = 0;
34 let mut unstaked_err = 0;
35 let mut unstaked_slashed = 0;
36
37 let all_stakers = Ledger::<T>::iter().map(|(ctrl, l)| (ctrl, l.stash)).collect::<BTreeSet<_>>();
38 let mut all_exposed = BTreeSet::new();
39 ErasStakersPaged::<T>::iter().for_each(|((_era, val, _page), expo)| {
40 all_exposed.insert(val);
41 all_exposed.extend(expo.others.iter().map(|ie| ie.who.clone()))
42 });
43
44 let eligible = all_stakers
45 .iter()
46 .filter_map(|(ctrl, stash)| all_exposed.contains(stash).then_some(ctrl))
47 .collect::<Vec<_>>();
48
49 log::info!(
50 target: "runtime::test",
51 "registering {} out of {} stakers for fast-unstake",
52 eligible.len(),
53 all_stakers.len()
54 );
55 for ctrl in eligible {
56 if let Err(why) =
57 FastUnstake::<T>::register_fast_unstake(RawOrigin::Signed(ctrl.clone()).into())
58 {
59 log::warn!(target: "runtime::test", "failed to register {:?} due to {:?}", ctrl, why);
60 }
61 }
62
63 log::info!(
64 target: "runtime::test",
65 "registered {} successfully, starting at {:?}.",
66 Queue::<T>::count(),
67 frame_system::Pallet::<T>::block_number(),
68 );
69 while Queue::<T>::count() != 0 || Head::<T>::get().is_some() {
70 let now = frame_system::Pallet::<T>::block_number();
71 let weight = <T as frame_system::Config>::BlockWeights::get().max_block;
72 let consumed = FastUnstake::<T>::on_idle(now, weight);
73 log::debug!(target: "runtime::test", "consumed {:?} ({})", consumed, consumed.ref_time() as f32 / weight.ref_time() as f32);
74
75 frame_system::Pallet::<T>::read_events_no_consensus()
76 .into_iter()
77 .map(|r| r.event)
78 .filter_map(|e| {
79 let maybe_fast_unstake_event: Option<pallet_fast_unstake::Event<T>> =
80 e.try_into().ok();
81 maybe_fast_unstake_event
82 })
83 .for_each(|e: pallet_fast_unstake::Event<T>| match e {
84 pallet_fast_unstake::Event::<T>::Unstaked { result, .. } =>
85 if result.is_ok() {
86 unstaked_ok += 1;
87 } else {
88 unstaked_err += 1
89 },
90 pallet_fast_unstake::Event::<T>::Slashed { .. } => unstaked_slashed += 1,
91 pallet_fast_unstake::Event::<T>::InternalError => unreachable!(),
92 _ => {},
93 });
94
95 if now % 100u32.into() == sp_runtime::traits::Zero::zero() {
96 log::info!(
97 target: "runtime::test",
98 "status: ok {}, err {}, slash {}",
99 unstaked_ok,
100 unstaked_err,
101 unstaked_slashed,
102 );
103 }
104
105 frame_system::Pallet::<T>::reset_events();
106 }
107}