diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index 2bed3b2bb5..4b170d9082 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -4545,6 +4545,7 @@ name = "pallet-vesting" version = "2.0.0-alpha.3" dependencies = [ "enumflags2", + "frame-benchmarking", "frame-support", "frame-system", "hex-literal", diff --git a/substrate/bin/node/runtime/Cargo.toml b/substrate/bin/node/runtime/Cargo.toml index 0d65cf5339..15672715a4 100644 --- a/substrate/bin/node/runtime/Cargo.toml +++ b/substrate/bin/node/runtime/Cargo.toml @@ -137,4 +137,5 @@ runtime-benchmarks = [ "pallet-timestamp/runtime-benchmarks", "pallet-identity/runtime-benchmarks", "pallet-balances/runtime-benchmarks", + "pallet-vesting/runtime-benchmarks", ] diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index 064132e61c..796782a102 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -83,7 +83,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // implementation changes and behavior does not, then leave spec_version as // is and increment impl_version. spec_version: 233, - impl_version: 0, + impl_version: 1, apis: RUNTIME_API_VERSIONS, }; @@ -864,6 +864,13 @@ impl_runtime_apis! { steps, repeat, ), + b"pallet-vesting" | b"vesting" => Vesting::run_benchmark( + extrinsic, + lowest_range_values, + highest_range_values, + steps, + repeat, + ), _ => Err("Benchmark not found for this pallet."), }; diff --git a/substrate/frame/vesting/Cargo.toml b/substrate/frame/vesting/Cargo.toml index f01a0f6bf2..882c062c43 100644 --- a/substrate/frame/vesting/Cargo.toml +++ b/substrate/frame/vesting/Cargo.toml @@ -17,6 +17,7 @@ sp-io = { version = "2.0.0-alpha.2", default-features = false, path = "../../pri sp-runtime = { version = "2.0.0-alpha.2", default-features = false, path = "../../primitives/runtime" } frame-support = { version = "2.0.0-alpha.2", default-features = false, path = "../support" } frame-system = { version = "2.0.0-alpha.2", default-features = false, path = "../system" } +frame-benchmarking = { version = "2.0.0-alpha.2", default-features = false, path = "../benchmarking", optional = true } [dev-dependencies] sp-core = { version = "2.0.0-alpha.2", path = "../../primitives/core" } @@ -35,3 +36,4 @@ std = [ "frame-support/std", "frame-system/std", ] +runtime-benchmarks = ["frame-benchmarking", "frame-system/runtime-benchmarks"] diff --git a/substrate/frame/vesting/src/benchmarking.rs b/substrate/frame/vesting/src/benchmarking.rs new file mode 100644 index 0000000000..79ab0cb6e3 --- /dev/null +++ b/substrate/frame/vesting/src/benchmarking.rs @@ -0,0 +1,111 @@ +// Copyright 2020 Parity Technologies (UK) Ltd. +// This file is part of Substrate. + +// Substrate is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Substrate is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Substrate. If not, see . + +//! Vesting pallet benchmarking. + +use super::*; + +use frame_system::{RawOrigin, Module as System}; +use sp_io::hashing::blake2_256; +use frame_benchmarking::{benchmarks, account}; + +use crate::Module as Vesting; + +const SEED: u32 = 0; +const MAX_LOCKS: u32 = 20; + +fn add_locks(l: u32) { + for id in 0..l { + let lock_id = <[u8; 8]>::decode(&mut &id.using_encoded(blake2_256)[..]) + .unwrap_or_default(); + let locker = account("locker", 0, SEED); + let locked = 1; + let reasons = WithdrawReason::Transfer | WithdrawReason::Reserve; + T::Currency::set_lock(lock_id, &locker, locked.into(), reasons); + } +} + +fn setup(b: u32) -> T::AccountId { + let locked = 1; + let per_block = 1; + let starting_block = 0; + + let caller = account("caller", 0, SEED); + + // Add schedule to avoid `NotVesting` error. + let _ = Vesting::::add_vesting_schedule( + &caller, + locked.into(), + per_block.into(), + starting_block.into(), + ); + + // Set lock and block number to take different code paths. + let reasons = WithdrawReason::Transfer | WithdrawReason::Reserve; + T::Currency::set_lock(VESTING_ID, &caller, locked.into(), reasons); + System::::set_block_number(b.into()); + + caller +} + +benchmarks! { + _ { + // Current block. It allows to hit different paths of `update_lock`. + // It doesn't seems to influence the timings which branch is taken. + let b in 0 .. 1 => (); + // Number of previous locks. + // It doesn't seems to influence the timings for lower values. + let l in 0 .. MAX_LOCKS => add_locks::(l); + } + + vest { + let b in ...; + let l in ...; + + let caller = setup::(b); + + }: _(RawOrigin::Signed(caller)) + + vest_other { + let b in ...; + let l in ...; + + let other: T::AccountId = setup::(b); + let other_lookup: ::Source = T::Lookup::unlookup(other.clone()); + + let caller = account("caller", 0, SEED); + + }: _(RawOrigin::Signed(caller), other_lookup) + + vested_transfer { + let u in 0 .. 1000; + + let from = account("from", u, SEED); + let to = account("to", u, SEED); + let to_lookup: ::Source = T::Lookup::unlookup(to); + + let transfer_amount = T::MinVestedTransfer::get(); + + let vesting_schedule = VestingInfo { + locked: transfer_amount, + per_block: 1.into(), + starting_block: 0.into(), + }; + + let _ = T::Currency::make_free_balance_be(&from, transfer_amount * 10.into()); + + }: _(RawOrigin::Signed(from), to_lookup, vesting_schedule) +} diff --git a/substrate/frame/vesting/src/lib.rs b/substrate/frame/vesting/src/lib.rs index 02d5bebfd2..223b840678 100644 --- a/substrate/frame/vesting/src/lib.rs +++ b/substrate/frame/vesting/src/lib.rs @@ -60,6 +60,9 @@ use frame_support::traits::{ use frame_support::weights::SimpleDispatchInfo; use frame_system::{self as system, ensure_signed}; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; pub trait Trait: frame_system::Trait {