Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Add batching to fast-unstake pallet #12394

Merged
merged 21 commits into from
Nov 8, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ impl pallet_staking::Config for Runtime {
impl pallet_fast_unstake::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type ControlOrigin = frame_system::EnsureRoot<AccountId>;
type BatchSize = ConstU32<128>;
type Deposit = ConstU128<{ DOLLARS }>;
type DepositCurrency = Balances;
type WeightInfo = ();
Expand Down
62 changes: 37 additions & 25 deletions frame/fast-unstake/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,14 @@ fn l<T: Config>(
T::Lookup::unlookup(who)
}

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>("nominator_42", i, USER_SEED);
ruseinov marked this conversation as resolved.
Show resolved Hide resolved
fund_and_bond_account::<T>(&account);
account
})
.collect()
}

fn fund_and_bond_account<T: Config>(account: &T::AccountId) {
Expand Down Expand Up @@ -108,29 +112,35 @@ 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>() {
kianenigma marked this conversation as resolved.
Show resolved Hide resolved
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>();
}
verify {
assert!(matches!(
fast_unstake_events::<T>().last(),
Some(Event::Unstaked { .. })
Some(Event::BatchFinished)
));
}

Expand All @@ -147,10 +157,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);
Expand All @@ -159,20 +172,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!(stashes.iter().all(|(s, _)| request.stashes.iter().find(|(ss, _)| ss == s).is_some()));
assert!(matches!(
fast_unstake_events::<T>().last(),
Some(Event::Checking { .. })
Some(Event::BatchChecked { .. })
));
}

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);

Expand All @@ -184,7 +196,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(),
));
Expand Down
Loading