Skip to content

Commit

Permalink
Add batching to fast-unstake pallet (paritytech#12394)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
2 people authored and ark0f committed Feb 27, 2023
1 parent 7fcdef1 commit a2718d6
Show file tree
Hide file tree
Showing 8 changed files with 609 additions and 264 deletions.
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"
]
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>() {
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

0 comments on commit a2718d6

Please sign in to comment.