Add batching to fast-unstake pallet (#12394)

* implement a brand new batch with all tests passing.

* fix benchmarks as well

* make benchmarks more or less work

* fix migration

* add some testing

* Update frame/fast-unstake/src/benchmarking.rs

Co-authored-by: Roman Useinov <roman.useinov@gmail.com>

* review comments

* some fixes

* fix review comments

* fix build

* fmt

* fix benchmarks

* fmt

* update

Co-authored-by: Roman Useinov <roman.useinov@gmail.com>
This commit is contained in:
Kian Paimani
2022-11-08 16:15:55 +00:00
committed by GitHub
parent 74b52f9338
commit c42db93312
8 changed files with 609 additions and 264 deletions
@@ -36,10 +36,15 @@ const MAX_VALIDATORS: u32 = 128;
type CurrencyOf<T> = <T as Config>::Currency;
fn create_unexposed_nominator<T: Config>() -> T::AccountId {
let account = frame_benchmarking::account::<T::AccountId>("nominator_42", 0, USER_SEED);
fund_and_bond_account::<T>(&account);
account
fn create_unexposed_nominators<T: Config>() -> Vec<T::AccountId> {
(0..T::BatchSize::get())
.map(|i| {
let account =
frame_benchmarking::account::<T::AccountId>("unexposed_nominator", i, USER_SEED);
fund_and_bond_account::<T>(&account);
account
})
.collect()
}
fn fund_and_bond_account<T: Config>(account: &T::AccountId) {
@@ -90,21 +95,27 @@ fn on_idle_full_block<T: Config>() {
}
benchmarks! {
// on_idle, we we don't check anyone, but fully unbond and move them to another pool.
// on_idle, we don't check anyone, but fully unbond them.
on_idle_unstake {
ErasToCheckPerBlock::<T>::put(1);
let who = create_unexposed_nominator::<T>();
assert_ok!(FastUnstake::<T>::register_fast_unstake(
RawOrigin::Signed(who.clone()).into(),
));
for who in create_unexposed_nominators::<T>() {
assert_ok!(FastUnstake::<T>::register_fast_unstake(
RawOrigin::Signed(who.clone()).into(),
));
}
// run on_idle once. This will check era 0.
assert_eq!(Head::<T>::get(), None);
on_idle_full_block::<T>();
assert_eq!(
assert!(matches!(
Head::<T>::get(),
Some(UnstakeRequest { stash: who.clone(), checked: vec![0].try_into().unwrap(), deposit: T::Deposit::get() })
);
Some(UnstakeRequest {
checked,
stashes,
..
}) if checked.len() == 1 && stashes.len() as u32 == T::BatchSize::get()
));
}
: {
on_idle_full_block::<T>();
@@ -112,7 +123,7 @@ benchmarks! {
verify {
assert!(matches!(
fast_unstake_events::<T>().last(),
Some(Event::Unstaked { .. })
Some(Event::BatchFinished)
));
}
@@ -129,10 +140,13 @@ benchmarks! {
// setup staking with v validators and u eras of data (0..=u)
setup_staking::<T>(v, u);
let who = create_unexposed_nominator::<T>();
assert_ok!(FastUnstake::<T>::register_fast_unstake(
RawOrigin::Signed(who.clone()).into(),
));
let stashes = create_unexposed_nominators::<T>().into_iter().map(|s| {
assert_ok!(FastUnstake::<T>::register_fast_unstake(
RawOrigin::Signed(s.clone()).into(),
));
(s, T::Deposit::get())
}).collect::<Vec<_>>();
// no one is queued thus far.
assert_eq!(Head::<T>::get(), None);
@@ -141,20 +155,19 @@ benchmarks! {
on_idle_full_block::<T>();
}
verify {
let checked: frame_support::BoundedVec<_, _> = (1..=u).rev().collect::<Vec<EraIndex>>().try_into().unwrap();
assert_eq!(
Head::<T>::get(),
Some(UnstakeRequest { stash: who.clone(), checked, deposit: T::Deposit::get() })
);
let checked = (1..=u).rev().collect::<Vec<EraIndex>>();
let request = Head::<T>::get().unwrap();
assert_eq!(checked, request.checked.into_inner());
assert!(matches!(
fast_unstake_events::<T>().last(),
Some(Event::Checking { .. })
Some(Event::BatchChecked { .. })
));
assert!(stashes.iter().all(|(s, _)| request.stashes.iter().find(|(ss, _)| ss == s).is_some()));
}
register_fast_unstake {
ErasToCheckPerBlock::<T>::put(1);
let who = create_unexposed_nominator::<T>();
let who = create_unexposed_nominators::<T>().get(0).cloned().unwrap();
whitelist_account!(who);
assert_eq!(Queue::<T>::count(), 0);
@@ -166,7 +179,7 @@ benchmarks! {
deregister {
ErasToCheckPerBlock::<T>::put(1);
let who = create_unexposed_nominator::<T>();
let who = create_unexposed_nominators::<T>().get(0).cloned().unwrap();
assert_ok!(FastUnstake::<T>::register_fast_unstake(
RawOrigin::Signed(who.clone()).into(),
));