Skip to content

Commit 5e26401

Browse files
authored
add vesting benchmarks (#1039)
1 parent 29ee65a commit 5e26401

File tree

4 files changed

+150
-0
lines changed

4 files changed

+150
-0
lines changed

vesting/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ parity-scale-codec = { workspace = true, default-features = false, features = ["
1212
scale-info = { workspace = true }
1313
serde = { workspace = true, optional = true }
1414

15+
frame-benchmarking = { workspace = true, optional = true }
1516
frame-support = { workspace = true }
1617
frame-system = { workspace = true }
1718
sp-io = { workspace = true }
@@ -25,6 +26,7 @@ sp-core = { workspace = true, features = ["std"] }
2526
[features]
2627
default = [ "std" ]
2728
std = [
29+
"frame-benchmarking?/std",
2830
"frame-support/std",
2931
"frame-system/std",
3032
"parity-scale-codec/std",
@@ -35,6 +37,7 @@ std = [
3537
"sp-std/std",
3638
]
3739
runtime-benchmarks = [
40+
"frame-benchmarking/runtime-benchmarks",
3841
"frame-support/runtime-benchmarks",
3942
"frame-system/runtime-benchmarks",
4043
"sp-runtime/runtime-benchmarks",

vesting/src/benchmarking.rs

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
pub use crate::*;
2+
3+
use frame_benchmarking::v2::*;
4+
use frame_support::assert_ok;
5+
use frame_system::RawOrigin;
6+
use sp_std::vec;
7+
8+
/// Helper trait for benchmarking.
9+
pub trait BenchmarkHelper<AccountId, Balance> {
10+
fn get_vesting_account_and_amount() -> Option<(AccountId, Balance)>;
11+
}
12+
13+
impl<AccountId, Balance> BenchmarkHelper<AccountId, Balance> for () {
14+
fn get_vesting_account_and_amount() -> Option<(AccountId, Balance)> {
15+
None
16+
}
17+
}
18+
19+
fn set_balance<T: Config>(who: &T::AccountId, amount: BalanceOf<T>) {
20+
let _ = <<T as Config>::Currency as Currency<_>>::deposit_creating(&who, amount);
21+
}
22+
23+
fn total_balance<T: Config>(who: &T::AccountId) -> BalanceOf<T> {
24+
<<T as Config>::Currency as Currency<_>>::total_balance(who)
25+
}
26+
27+
fn free_balance<T: Config>(who: &T::AccountId) -> BalanceOf<T> {
28+
<<T as Config>::Currency as Currency<_>>::free_balance(who)
29+
}
30+
31+
#[benchmarks]
32+
mod benchmarks {
33+
use super::*;
34+
35+
#[benchmark]
36+
fn vested_transfer() {
37+
let schedule = VestingScheduleOf::<T> {
38+
start: 0u32.into(),
39+
period: 2u32.into(),
40+
period_count: 3u32.into(),
41+
per_period: T::MinVestedTransfer::get(),
42+
};
43+
44+
// extra 1 dollar to pay fees
45+
let (from, amount) = T::BenchmarkHelper::get_vesting_account_and_amount().unwrap();
46+
set_balance::<T>(&from, schedule.total_amount().unwrap() + amount);
47+
48+
let to: T::AccountId = account("to", 0, 0);
49+
let to_lookup = <T as frame_system::Config>::Lookup::unlookup(to.clone());
50+
51+
#[extrinsic_call]
52+
_(RawOrigin::Signed(from), to_lookup, schedule.clone());
53+
54+
assert_eq!(total_balance::<T>(&to), schedule.total_amount().unwrap());
55+
}
56+
57+
#[benchmark]
58+
fn claim(i: Linear<1, { T::MaxVestingSchedules::get() }>) {
59+
let mut schedule = VestingScheduleOf::<T> {
60+
start: 0u32.into(),
61+
period: 2u32.into(),
62+
period_count: 3u32.into(),
63+
per_period: T::MinVestedTransfer::get(),
64+
};
65+
66+
// extra 1 dollar to pay fees
67+
let (from, amount) = T::BenchmarkHelper::get_vesting_account_and_amount().unwrap();
68+
set_balance::<T>(
69+
&from,
70+
schedule.total_amount().unwrap().saturating_mul(i.into()) + amount,
71+
);
72+
73+
let to: T::AccountId = account("to", 0, 0);
74+
let to_lookup = <T as frame_system::Config>::Lookup::unlookup(to.clone());
75+
76+
for _ in 0..i {
77+
schedule.start = i.into();
78+
assert_ok!(Pallet::<T>::vested_transfer(
79+
RawOrigin::Signed(from.clone()).into(),
80+
to_lookup.clone(),
81+
schedule.clone()
82+
));
83+
}
84+
frame_system::Pallet::<T>::set_block_number(schedule.end().unwrap() + 1u32.into());
85+
86+
#[extrinsic_call]
87+
_(RawOrigin::Signed(to.clone()));
88+
89+
assert_eq!(
90+
free_balance::<T>(&to),
91+
schedule.total_amount().unwrap().saturating_mul(i.into()),
92+
);
93+
}
94+
95+
#[benchmark]
96+
fn update_vesting_schedules(i: Linear<1, { T::MaxVestingSchedules::get() }>) {
97+
let mut schedule = VestingScheduleOf::<T> {
98+
start: 0u32.into(),
99+
period: 2u32.into(),
100+
period_count: 3u32.into(),
101+
per_period: T::MinVestedTransfer::get(),
102+
};
103+
104+
let to: T::AccountId = account("to", 0, 0);
105+
let to_lookup = <T as frame_system::Config>::Lookup::unlookup(to.clone());
106+
107+
set_balance::<T>(&to, schedule.total_amount().unwrap().saturating_mul(i.into()));
108+
109+
let mut schedules = vec![];
110+
for _ in 0..i {
111+
schedule.start = i.into();
112+
schedules.push(schedule.clone());
113+
}
114+
115+
#[extrinsic_call]
116+
_(RawOrigin::Root, to_lookup, schedules);
117+
118+
assert_eq!(
119+
free_balance::<T>(&to),
120+
schedule.total_amount().unwrap().saturating_mul(i.into()),
121+
);
122+
}
123+
124+
impl_benchmark_test_suite! {
125+
Pallet,
126+
crate::mock::ExtBuilder::build(),
127+
crate::mock::Runtime,
128+
}
129+
}

vesting/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,14 @@ use sp_std::{
4545
vec::Vec,
4646
};
4747

48+
#[cfg(feature = "runtime-benchmarks")]
49+
mod benchmarking;
4850
mod mock;
4951
mod tests;
5052
mod weights;
5153

54+
#[cfg(feature = "runtime-benchmarks")]
55+
pub use benchmarking::BenchmarkHelper;
5256
pub use module::*;
5357
pub use weights::WeightInfo;
5458

@@ -143,6 +147,9 @@ pub mod module {
143147

144148
// The block number provider
145149
type BlockNumberProvider: BlockNumberProvider<BlockNumber = BlockNumberFor<Self>>;
150+
151+
#[cfg(feature = "runtime-benchmarks")]
152+
type BenchmarkHelper: BenchmarkHelper<Self::AccountId, BalanceOf<Self>>;
146153
}
147154

148155
#[pallet::error]

vesting/src/mock.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,24 @@ impl BlockNumberProvider for MockBlockNumberProvider {
7373
}
7474
}
7575

76+
#[cfg(feature = "runtime-benchmarks")]
77+
pub struct MockBenchmarkHelper;
78+
#[cfg(feature = "runtime-benchmarks")]
79+
impl BenchmarkHelper<AccountId, Balance> for MockBenchmarkHelper {
80+
fn get_vesting_account_and_amount() -> Option<(AccountId, Balance)> {
81+
Some((ALICE, 1000))
82+
}
83+
}
84+
7685
impl Config for Runtime {
7786
type Currency = PalletBalances;
7887
type MinVestedTransfer = ConstU64<5>;
7988
type VestedTransferOrigin = EnsureAliceOrBob;
8089
type WeightInfo = ();
8190
type MaxVestingSchedules = ConstU32<2>;
8291
type BlockNumberProvider = MockBlockNumberProvider;
92+
#[cfg(feature = "runtime-benchmarks")]
93+
type BenchmarkHelper = MockBenchmarkHelper;
8394
}
8495

8596
type Block = frame_system::mocking::MockBlock<Runtime>;

0 commit comments

Comments
 (0)