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 all 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 Currency = Balances;
type Staking = Staking;
Expand Down
3 changes: 2 additions & 1 deletion frame/fast-unstake/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ std = [
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-staking/runtime-benchmarks"
"sp-staking/runtime-benchmarks",
"pallet-staking/runtime-benchmarks"
ruseinov marked this conversation as resolved.
Show resolved Hide resolved
]
try-runtime = ["frame-support/try-runtime"]
63 changes: 38 additions & 25 deletions frame/fast-unstake/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -90,29 +95,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 @@ -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);
Expand All @@ -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);

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