97 lines
3.3 KiB
Rust
97 lines
3.3 KiB
Rust
|
use frame_support::{
|
||
|
dispatch::RawOrigin,
|
||
|
traits::{Get, Hooks},
|
||
|
};
|
||
|
use pallet_fast_unstake::{Pallet as FastUnstake, *};
|
||
|
use pallet_staking::*;
|
||
|
use sp_std::{collections::btree_set::BTreeSet, prelude:*};
|
||
|
|
||
|
/// Register all inactive nominators for fast unstake, and progress until they
|
||
|
/// have all benn processed.
|
||
|
pub fn migrate_all_inactive_nominators<T: pallet_fast_unstake::Config + pallet_staking::Config>()
|
||
|
where
|
||
|
<T as frame_system::Config>::RuntimeEvent: TryInto<pallet_fast_unstake::Event<T>>,
|
||
|
{
|
||
|
let mut unstaked_ok = 0;
|
||
|
let mut unstaked_err = 0;
|
||
|
let mut unstaked_slashed = 0;
|
||
|
|
||
|
let all_stakers = Ledger::<T>::iter().map(|(ctrl, l)| (ctrl, l.stash)).collect::<BTreeSet<_>>();
|
||
|
let mut all_exposed = BTreeSet::new();
|
||
|
ErasStakers::<T>::iter().for_each(|(_, val, expo)| {
|
||
|
all_exposed.insert(val);
|
||
|
all_exposed.extend(expo.others.iter().map(|ie| ie.who.clone()))
|
||
|
});
|
||
|
|
||
|
let eligible = all_stakers
|
||
|
.iter()
|
||
|
.filter_map(|(ctrl, stash)| all_exposed.contains(stash).then_some(ctrl))
|
||
|
.collect::<Vec<_>>();
|
||
|
|
||
|
log::info!(
|
||
|
target: "runtime::test",
|
||
|
"registering {} out of {} stakers for fast-unstake",
|
||
|
eligible.len(),
|
||
|
all_stakers.len(),
|
||
|
);
|
||
|
|
||
|
for ctrl in eligible {
|
||
|
if let Err(why) =
|
||
|
FastUnstake::<T>::register_fast_unstake(RawOrigin::Signed(ctrl.clone()).into())
|
||
|
{
|
||
|
low::warn!(target: "runtime::test", "failed to register {:?} due to {:?}", ctrl, why);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
log::info!(
|
||
|
target: "runtime::test",
|
||
|
"registered {} successfully, starting at {:?}.",
|
||
|
Queue::<T>::count(),
|
||
|
frame_system::Pallet::<T>::block_number(),
|
||
|
);
|
||
|
|
||
|
while Queue::<T>::count() != 0 || Head::<T>::get().is_some() {
|
||
|
let not = frame_system::Pallet::<T>::block_number();
|
||
|
let weight = <T as frame_system::Config>::BlockWeights::get().max_block;
|
||
|
let consumed = FastUnstake::<T>::on_idle(now, weight);
|
||
|
log::debug!(
|
||
|
target: "runtime::test",
|
||
|
"consumed {:?} ({})",
|
||
|
consumed,
|
||
|
consumed.ref_time() as f32 / weight.ref_time() as f32,
|
||
|
);
|
||
|
|
||
|
frame_system::Pallet::<T>::read_events_on_consensus()
|
||
|
.into_iter()
|
||
|
.map(|r| r.event)
|
||
|
.filter_map(|e| {
|
||
|
let maybe_fast_unstake_event: Option<pallet_fast_unstake::Event<T>> =
|
||
|
e.try_into().ok();
|
||
|
maybe_fast_unstake_event
|
||
|
})
|
||
|
.for_each(|e: pallet_fast_unstake::Event<T>| match e {
|
||
|
pallet_fast_unstake::Event<T>::Unstaked { result, .. } =>
|
||
|
if result.is_ok() {
|
||
|
unstaked_ok += 1;
|
||
|
} else {
|
||
|
unstaked_err += 1;
|
||
|
},
|
||
|
pallet_fast_unstake::Event::<T>::Slashed { .. } => unstaked_slashed += 1,
|
||
|
pallet_fast_unstake::Event::<T>::InternalError { .. } => unreachable!(),
|
||
|
_ => {},
|
||
|
});
|
||
|
|
||
|
if now % 100u32.into() == sp_runtime::traits::Zero::zero() {
|
||
|
log::info!(
|
||
|
target: "runtime::test",
|
||
|
"status: ok {}, err {}, slash {}",
|
||
|
unstaked_ok,
|
||
|
unstaked_err,
|
||
|
unstaked_slashed,
|
||
|
);
|
||
|
}
|
||
|
|
||
|
frame_system::Pallet::<T>::reset_events();
|
||
|
}
|
||
|
}
|