From 8a9961b48e175b897b3f227f1e334e0e1a0acdbc Mon Sep 17 00:00:00 2001 From: Ayevbeosa Iyamu Date: Tue, 26 Apr 2022 12:57:55 +0100 Subject: [PATCH] Recovery Pallet benchmarking (#11176) * Created benchmarks * Added recovery benchmarks * benchmark for `create_recovery` * benchmark for `initiate_recovery` * benchmark for `vouch_recovery` * benchmark for `claim_recovery` * benchmark for `close_recovery` * benchmark for `remove_recovery` * benchmark for `cancel_recovered` * benchmark for `as_recovered` * Some refactoring * Some refactoring * Fix create_recovery benchmark * fix close_recovery benchmark test * fixed issues with failing tests * Update frame/recovery/src/benchmarking.rs Co-authored-by: Oliver Tale-Yazdi * removed repetitive code * create weights file * Used weights to annotate extrinsics * Added WeightInfo implementation to mock * Beauty fixes Signed-off-by: Oliver Tale-Yazdi * Update frame/recovery/src/benchmarking.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Update frame/recovery/src/benchmarking.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * Set vec to be mut * set delay_period to use non-zero amount * set delay default * Add weights Signed-off-by: Oliver Tale-Yazdi Co-authored-by: Oliver Tale-Yazdi Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> --- substrate/Cargo.lock | 1 + substrate/bin/node/runtime/Cargo.toml | 1 + substrate/bin/node/runtime/src/lib.rs | 2 + substrate/frame/recovery/Cargo.toml | 8 + substrate/frame/recovery/src/benchmarking.rs | 371 +++++++++++++++++++ substrate/frame/recovery/src/lib.rs | 114 ++---- substrate/frame/recovery/src/mock.rs | 5 +- substrate/frame/recovery/src/tests.rs | 21 +- substrate/frame/recovery/src/weights.rs | 203 ++++++++++ 9 files changed, 626 insertions(+), 100 deletions(-) create mode 100644 substrate/frame/recovery/src/benchmarking.rs create mode 100644 substrate/frame/recovery/src/weights.rs diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index d58c660968..397f1f038c 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -6276,6 +6276,7 @@ dependencies = [ name = "pallet-recovery" version = "4.0.0-dev" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", "pallet-balances", diff --git a/substrate/bin/node/runtime/Cargo.toml b/substrate/bin/node/runtime/Cargo.toml index 19d911a165..847530e5c6 100644 --- a/substrate/bin/node/runtime/Cargo.toml +++ b/substrate/bin/node/runtime/Cargo.toml @@ -215,6 +215,7 @@ runtime-benchmarks = [ "pallet-proxy/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", "pallet-referenda/runtime-benchmarks", + "pallet-recovery/runtime-benchmarks", "pallet-remark/runtime-benchmarks", "pallet-session-benchmarking", "pallet-society/runtime-benchmarks", diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index c88dc8d731..f073482d88 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -1213,6 +1213,7 @@ parameter_types! { impl pallet_recovery::Config for Runtime { type Event = Event; + type WeightInfo = pallet_recovery::weights::SubstrateWeight; type Call = Call; type Currency = Balances; type ConfigDepositBase = ConfigDepositBase; @@ -1557,6 +1558,7 @@ mod benches { [pallet_preimage, Preimage] [pallet_proxy, Proxy] [pallet_referenda, Referenda] + [pallet_recovery, Recovery] [pallet_remark, Remark] [pallet_scheduler, Scheduler] [pallet_session, SessionBench::] diff --git a/substrate/frame/recovery/Cargo.toml b/substrate/frame/recovery/Cargo.toml index 0a173fe2c9..98dbfc0eb0 100644 --- a/substrate/frame/recovery/Cargo.toml +++ b/substrate/frame/recovery/Cargo.toml @@ -18,6 +18,7 @@ scale-info = { version = "2.0.1", default-features = false, features = ["derive" sp-std = { version = "4.0.0", default-features = false, path = "../../primitives/std" } sp-io = { version = "6.0.0", default-features = false, path = "../../primitives/io" } sp-runtime = { version = "6.0.0", default-features = false, path = "../../primitives/runtime" } +frame-benchmarking = { version = "4.0.0-dev", default-features = false, path = "../benchmarking", optional = true } frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" } @@ -27,6 +28,12 @@ pallet-balances = { version = "4.0.0-dev", path = "../balances" } [features] default = ["std"] +runtime-benchmarks = [ + 'frame-benchmarking', + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] std = [ "codec/std", "scale-info/std", @@ -35,5 +42,6 @@ std = [ "sp-runtime/std", "frame-support/std", "frame-system/std", + "frame-benchmarking/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/substrate/frame/recovery/src/benchmarking.rs b/substrate/frame/recovery/src/benchmarking.rs new file mode 100644 index 0000000000..5354de6d10 --- /dev/null +++ b/substrate/frame/recovery/src/benchmarking.rs @@ -0,0 +1,371 @@ +// This file is part of Substrate. + +// Copyright (C) 2022 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; + +use crate::Pallet; +use frame_benchmarking::{account, benchmarks, whitelisted_caller}; +use frame_support::traits::{Currency, Get}; +use frame_system::RawOrigin; +use sp_runtime::traits::Bounded; + +const SEED: u32 = 0; +const DEFAULT_DELAY: u32 = 0; + +fn assert_last_event(generic_event: ::Event) { + frame_system::Pallet::::assert_last_event(generic_event.into()); +} + +fn get_total_deposit( + bounded_friends: &FriendsOf, +) -> Option<<::Currency as Currency<::AccountId>>::Balance> +{ + let friend_deposit = T::FriendDepositFactor::get() + .checked_mul(&bounded_friends.len().saturated_into()) + .unwrap(); + + T::ConfigDepositBase::get().checked_add(&friend_deposit) +} + +fn generate_friends(num: u32) -> Vec<::AccountId> { + // Create friends + let mut friends = (0..num).map(|x| account("friend", x, SEED)).collect::>(); + // Sort + friends.sort(); + + for friend in 0..friends.len() { + // Top up accounts of friends + T::Currency::make_free_balance_be( + &friends.get(friend).unwrap(), + BalanceOf::::max_value(), + ); + } + + friends +} + +fn add_caller_and_generate_friends( + caller: T::AccountId, + num: u32, +) -> Vec<::AccountId> { + // Create friends + let mut friends = generate_friends::(num - 1); + + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + friends.push(caller); + + // Sort + friends.sort(); + + friends +} + +fn insert_recovery_account(caller: &T::AccountId, account: &T::AccountId) { + T::Currency::make_free_balance_be(&account, BalanceOf::::max_value()); + + let n = T::MaxFriends::get(); + + let friends = generate_friends::(n); + + let bounded_friends: FriendsOf = friends.try_into().unwrap(); + + // Get deposit for recovery + let total_deposit = get_total_deposit::(&bounded_friends).unwrap(); + + let recovery_config = RecoveryConfig { + delay_period: DEFAULT_DELAY.into(), + deposit: total_deposit, + friends: bounded_friends, + threshold: n as u16, + }; + + // Reserve deposit for recovery + T::Currency::reserve(&caller, total_deposit).unwrap(); + + >::insert(&account, recovery_config); +} + +benchmarks! { + as_recovered { + let caller: T::AccountId = whitelisted_caller(); + let recovered_account: T::AccountId = account("recovered_account", 0, SEED); + let call: ::Call = frame_system::Call::::remark { remark: vec![] }.into(); + + Proxy::::insert(&caller, &recovered_account); + }: _( + RawOrigin::Signed(caller), + recovered_account, + Box::new(call) + ) + + set_recovered { + let lost: T::AccountId = whitelisted_caller(); + let rescuer: T::AccountId = whitelisted_caller(); + }: _( + RawOrigin::Root, + lost.clone(), + rescuer.clone() + ) verify { + assert_last_event::( + Event::AccountRecovered { + lost_account: lost, + rescuer_account: rescuer, + }.into() + ); + } + + create_recovery { + let n in 1 .. T::MaxFriends::get(); + + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Create friends + let friends = generate_friends::(n); + }: _( + RawOrigin::Signed(caller.clone()), + friends, + n as u16, + DEFAULT_DELAY.into() + ) verify { + assert_last_event::(Event::RecoveryCreated { account: caller }.into()); + } + + initiate_recovery { + let caller: T::AccountId = whitelisted_caller(); + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + let lost_account: T::AccountId = account("lost_account", 0, SEED); + + insert_recovery_account::(&caller, &lost_account); + }: _( + RawOrigin::Signed(caller.clone()), + lost_account.clone() + ) verify { + assert_last_event::( + Event::RecoveryInitiated { + lost_account: lost_account, + rescuer_account: caller, + }.into() + ); + } + + vouch_recovery { + let n in 1 .. T::MaxFriends::get(); + + let caller: T::AccountId = whitelisted_caller(); + let lost_account: T::AccountId = account("lost_account", 0, SEED); + let rescuer_account: T::AccountId = account("rescuer_account", 0, SEED); + + // Create friends + let friends = add_caller_and_generate_friends::(caller.clone(), n); + let bounded_friends: FriendsOf = friends.try_into().unwrap(); + + // Get deposit for recovery + let total_deposit = get_total_deposit::(&bounded_friends).unwrap(); + + let recovery_config = RecoveryConfig { + delay_period: DEFAULT_DELAY.into(), + deposit: total_deposit.clone(), + friends: bounded_friends.clone(), + threshold: n as u16, + }; + + // Create the recovery config storage item + >::insert(&lost_account, recovery_config.clone()); + + // Reserve deposit for recovery + T::Currency::reserve(&caller, total_deposit).unwrap(); + + // Create an active recovery status + let recovery_status = ActiveRecovery { + created: DEFAULT_DELAY.into(), + deposit: total_deposit, + friends: generate_friends::(n - 1).try_into().unwrap(), + }; + + // Create the active recovery storage item + >::insert(&lost_account, &rescuer_account, recovery_status); + + }: _( + RawOrigin::Signed(caller.clone()), + lost_account.clone(), + rescuer_account.clone() + ) verify { + assert_last_event::( + Event::RecoveryVouched { + lost_account: lost_account, + rescuer_account: rescuer_account, + sender: caller, + }.into() + ); + } + + claim_recovery { + let n in 1 .. T::MaxFriends::get(); + + let caller: T::AccountId = whitelisted_caller(); + let lost_account: T::AccountId = account("lost_account", 0, SEED); + + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Create friends + let friends = generate_friends::(n); + let bounded_friends: FriendsOf = friends.try_into().unwrap(); + + // Get deposit for recovery + let total_deposit = get_total_deposit::(&bounded_friends).unwrap(); + + let recovery_config = RecoveryConfig { + delay_period: 0u32.into(), + deposit: total_deposit.clone(), + friends: bounded_friends.clone(), + threshold: n as u16, + }; + + // Create the recovery config storage item + >::insert(&lost_account, recovery_config.clone()); + + // Reserve deposit for recovery + T::Currency::reserve(&caller, total_deposit).unwrap(); + + // Create an active recovery status + let recovery_status = ActiveRecovery { + created: 0u32.into(), + deposit: total_deposit, + friends: bounded_friends.clone(), + }; + + // Create the active recovery storage item + >::insert(&lost_account, &caller, recovery_status); + }: _( + RawOrigin::Signed(caller.clone()), + lost_account.clone() + ) verify { + assert_last_event::( + Event::AccountRecovered { + lost_account: lost_account, + rescuer_account: caller, + }.into() + ); + } + + close_recovery { + let caller: T::AccountId = whitelisted_caller(); + let rescuer_account: T::AccountId = account("rescuer_account", 0, SEED); + + let n in 1 .. T::MaxFriends::get(); + + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + T::Currency::make_free_balance_be(&rescuer_account, BalanceOf::::max_value()); + + // Create friends + let friends = generate_friends::(n); + let bounded_friends: FriendsOf = friends.try_into().unwrap(); + + // Get deposit for recovery + let total_deposit = get_total_deposit::(&bounded_friends).unwrap(); + + let recovery_config = RecoveryConfig { + delay_period: DEFAULT_DELAY.into(), + deposit: total_deposit.clone(), + friends: bounded_friends.clone(), + threshold: n as u16, + }; + + // Create the recovery config storage item + >::insert(&caller, recovery_config.clone()); + + // Reserve deposit for recovery + T::Currency::reserve(&caller, total_deposit).unwrap(); + + // Create an active recovery status + let recovery_status = ActiveRecovery { + created: DEFAULT_DELAY.into(), + deposit: total_deposit, + friends: bounded_friends.clone(), + }; + + // Create the active recovery storage item + >::insert(&caller, &rescuer_account, recovery_status); + }: _( + RawOrigin::Signed(caller.clone()), + rescuer_account.clone() + ) verify { + assert_last_event::( + Event::RecoveryClosed { + lost_account: caller, + rescuer_account: rescuer_account, + }.into() + ); + } + + remove_recovery { + let n in 1 .. T::MaxFriends::get(); + + let caller: T::AccountId = whitelisted_caller(); + + T::Currency::make_free_balance_be(&caller, BalanceOf::::max_value()); + + // Create friends + let friends = generate_friends::(n); + let bounded_friends: FriendsOf = friends.try_into().unwrap(); + + // Get deposit for recovery + let total_deposit = get_total_deposit::(&bounded_friends).unwrap(); + + let recovery_config = RecoveryConfig { + delay_period: DEFAULT_DELAY.into(), + deposit: total_deposit.clone(), + friends: bounded_friends.clone(), + threshold: n as u16, + }; + + // Create the recovery config storage item + >::insert(&caller, recovery_config); + + // Reserve deposit for recovery + T::Currency::reserve(&caller, total_deposit).unwrap(); + }: _( + RawOrigin::Signed(caller.clone()) + ) verify { + assert_last_event::( + Event::RecoveryRemoved { + lost_account: caller + }.into() + ); + } + + cancel_recovered { + let caller: T::AccountId = whitelisted_caller(); + let account: T::AccountId = account("account", 0, SEED); + + frame_system::Pallet::::inc_providers(&caller); + + frame_system::Pallet::::inc_consumers(&caller)?; + + Proxy::::insert(&caller, &account); + }: _( + RawOrigin::Signed(caller), + account + ) + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/substrate/frame/recovery/src/lib.rs b/substrate/frame/recovery/src/lib.rs index adc5c0b895..e75c902576 100644 --- a/substrate/frame/recovery/src/lib.rs +++ b/substrate/frame/recovery/src/lib.rs @@ -167,11 +167,16 @@ use frame_support::{ }; pub use pallet::*; +pub use weights::WeightInfo; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; #[cfg(test)] mod mock; #[cfg(test)] mod tests; +pub mod weights; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; @@ -222,10 +227,14 @@ pub mod pallet { /// The overarching event type. type Event: From> + IsType<::Event>; + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + /// The overarching call type. type Call: Parameter + Dispatchable - + GetDispatchInfo; + + GetDispatchInfo + + From>; /// The currency mechanism. type Currency: ReservableCurrency; @@ -365,21 +374,12 @@ pub mod pallet { /// Parameters: /// - `account`: The recovered account you want to make a call on-behalf-of. /// - `call`: The call you want to make with the recovered account. - /// - /// # - /// - The weight of the `call` + 10,000. - /// - One storage lookup to check account is recovered by `who`. O(1) - /// # #[pallet::weight({ let dispatch_info = call.get_dispatch_info(); ( - dispatch_info.weight - .saturating_add(10_000) - // AccountData for inner call origin accountdata. - .saturating_add(T::DbWeight::get().reads_writes(1, 1)), + T::WeightInfo::as_recovered().saturating_add(dispatch_info.weight), dispatch_info.class, - ) - })] + )})] pub fn as_recovered( origin: OriginFor, account: T::AccountId, @@ -402,12 +402,7 @@ pub mod pallet { /// Parameters: /// - `lost`: The "lost account" to be recovered. /// - `rescuer`: The "rescuer account" which can call as the lost account. - /// - /// # - /// - One storage write O(1) - /// - One event - /// # - #[pallet::weight(30_000_000)] + #[pallet::weight(T::WeightInfo::set_recovered())] pub fn set_recovered( origin: OriginFor, lost: T::AccountId, @@ -439,18 +434,7 @@ pub mod pallet { /// friends. /// - `delay_period`: The number of blocks after a recovery attempt is initialized that /// needs to pass before the account can be recovered. - /// - /// # - /// - Key: F (len of friends) - /// - One storage read to check that account is not already recoverable. O(1). - /// - A check that the friends list is sorted and unique. O(F) - /// - One currency reserve operation. O(X) - /// - One storage write. O(1). Codec O(F). - /// - One event. - /// - /// Total Complexity: O(F + X) - /// # - #[pallet::weight(100_000_000)] + #[pallet::weight(T::WeightInfo::create_recovery(friends.len() as u32))] pub fn create_recovery( origin: OriginFor, friends: Vec, @@ -501,18 +485,7 @@ pub mod pallet { /// Parameters: /// - `account`: The lost account that you want to recover. This account needs to be /// recoverable (i.e. have a recovery configuration). - /// - /// # - /// - One storage read to check that account is recoverable. O(F) - /// - One storage read to check that this recovery process hasn't already started. O(1) - /// - One currency reserve operation. O(X) - /// - One storage read to get the current block number. O(1) - /// - One storage write. O(1). - /// - One event. - /// - /// Total Complexity: O(F + X) - /// # - #[pallet::weight(100_000_000)] + #[pallet::weight(T::WeightInfo::initiate_recovery())] pub fn initiate_recovery(origin: OriginFor, account: T::AccountId) -> DispatchResult { let who = ensure_signed(origin)?; // Check that the account is recoverable @@ -552,19 +525,7 @@ pub mod pallet { /// /// The combination of these two parameters must point to an active recovery /// process. - /// - /// # - /// Key: F (len of friends in config), V (len of vouching friends) - /// - One storage read to get the recovery configuration. O(1), Codec O(F) - /// - One storage read to get the active recovery process. O(1), Codec O(V) - /// - One binary search to confirm caller is a friend. O(logF) - /// - One binary search to confirm caller has not already vouched. O(logV) - /// - One storage write. O(1), Codec O(V). - /// - One event. - /// - /// Total Complexity: O(F + logF + V + logV) - /// # - #[pallet::weight(100_000_000)] + #[pallet::weight(T::WeightInfo::vouch_recovery(T::MaxFriends::get()))] pub fn vouch_recovery( origin: OriginFor, lost: T::AccountId, @@ -605,18 +566,7 @@ pub mod pallet { /// Parameters: /// - `account`: The lost account that you want to claim has been successfully recovered by /// you. - /// - /// # - /// Key: F (len of friends in config), V (len of vouching friends) - /// - One storage read to get the recovery configuration. O(1), Codec O(F) - /// - One storage read to get the active recovery process. O(1), Codec O(V) - /// - One storage read to get the current block number. O(1) - /// - One storage write. O(1), Codec O(V). - /// - One event. - /// - /// Total Complexity: O(F + V) - /// # - #[pallet::weight(100_000_000)] + #[pallet::weight(T::WeightInfo::claim_recovery(T::MaxFriends::get()))] pub fn claim_recovery(origin: OriginFor, account: T::AccountId) -> DispatchResult { let who = ensure_signed(origin)?; // Get the recovery configuration for the lost account @@ -659,16 +609,7 @@ pub mod pallet { /// /// Parameters: /// - `rescuer`: The account trying to rescue this recoverable account. - /// - /// # - /// Key: V (len of vouching friends) - /// - One storage read/remove to get the active recovery process. O(1), Codec O(V) - /// - One balance call to repatriate reserved. O(X) - /// - One event. - /// - /// Total Complexity: O(V + X) - /// # - #[pallet::weight(30_000_000)] + #[pallet::weight(T::WeightInfo::close_recovery(T::MaxFriends::get()))] pub fn close_recovery(origin: OriginFor, rescuer: T::AccountId) -> DispatchResult { let who = ensure_signed(origin)?; // Take the active recovery process started by the rescuer for this account. @@ -701,17 +642,7 @@ pub mod pallet { /// /// The dispatch origin for this call must be _Signed_ and must be a /// recoverable account (i.e. has a recovery configuration). - /// - /// # - /// Key: F (len of friends) - /// - One storage read to get the prefix iterator for active recoveries. O(1) - /// - One storage read/remove to get the recovery configuration. O(1), Codec O(F) - /// - One balance call to unreserved. O(X) - /// - One event. - /// - /// Total Complexity: O(F + X) - /// # - #[pallet::weight(30_000_000)] + #[pallet::weight(T::WeightInfo::remove_recovery(T::MaxFriends::get()))] pub fn remove_recovery(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; // Check there are no active recoveries @@ -733,16 +664,13 @@ pub mod pallet { /// /// Parameters: /// - `account`: The recovered account you are able to call on-behalf-of. - /// - /// # - /// - One storage mutation to check account is recovered by `who`. O(1) - /// # - #[pallet::weight(30_000_000)] + #[pallet::weight(T::WeightInfo::cancel_recovered())] pub fn cancel_recovered(origin: OriginFor, account: T::AccountId) -> DispatchResult { let who = ensure_signed(origin)?; // Check `who` is allowed to make a call on behalf of `account` ensure!(Self::proxy(&who) == Some(account), Error::::NotAllowed); Proxy::::remove(&who); + frame_system::Pallet::::dec_consumers(&who); Ok(()) } diff --git a/substrate/frame/recovery/src/mock.rs b/substrate/frame/recovery/src/mock.rs index 2088f9eb09..44fc4d72a4 100644 --- a/substrate/frame/recovery/src/mock.rs +++ b/substrate/frame/recovery/src/mock.rs @@ -97,15 +97,18 @@ parameter_types! { pub const ConfigDepositBase: u64 = 10; pub const FriendDepositFactor: u64 = 1; pub const RecoveryDeposit: u64 = 10; + // Large number of friends for benchmarking. + pub const MaxFriends: u32 = 128; } impl Config for Test { type Event = Event; + type WeightInfo = (); type Call = Call; type Currency = Balances; type ConfigDepositBase = ConfigDepositBase; type FriendDepositFactor = FriendDepositFactor; - type MaxFriends = ConstU32<3>; + type MaxFriends = MaxFriends; type RecoveryDeposit = RecoveryDeposit; } diff --git a/substrate/frame/recovery/src/tests.rs b/substrate/frame/recovery/src/tests.rs index 16fc678d35..a900a5b6bf 100644 --- a/substrate/frame/recovery/src/tests.rs +++ b/substrate/frame/recovery/src/tests.rs @@ -20,7 +20,8 @@ use super::*; use frame_support::{assert_noop, assert_ok, bounded_vec, traits::Currency}; use mock::{ - new_test_ext, run_to_block, Balances, BalancesCall, Call, Origin, Recovery, RecoveryCall, Test, + new_test_ext, run_to_block, Balances, BalancesCall, Call, MaxFriends, Origin, Recovery, + RecoveryCall, Test, }; use sp_runtime::traits::BadOrigin; @@ -112,10 +113,13 @@ fn malicious_recovery_fails() { // Using account 1, the malicious user begins the recovery process on account 5 assert_ok!(Recovery::initiate_recovery(Origin::signed(1), 5)); // Off chain, the user **tricks** their friends and asks them to vouch for the recovery - assert_ok!(Recovery::vouch_recovery(Origin::signed(2), 5, 1)); // shame on you - assert_ok!(Recovery::vouch_recovery(Origin::signed(3), 5, 1)); // shame on you - assert_ok!(Recovery::vouch_recovery(Origin::signed(4), 5, 1)); // shame on you - // We met the threshold, lets try to recover the account...? + assert_ok!(Recovery::vouch_recovery(Origin::signed(2), 5, 1)); + // shame on you + assert_ok!(Recovery::vouch_recovery(Origin::signed(3), 5, 1)); + // shame on you + assert_ok!(Recovery::vouch_recovery(Origin::signed(4), 5, 1)); + // shame on you + // We met the threshold, lets try to recover the account...? assert_noop!(Recovery::claim_recovery(Origin::signed(1), 5), Error::::DelayPeriod); // Account 1 needs to wait... run_to_block(19); @@ -162,7 +166,12 @@ fn create_recovery_handles_basic_errors() { ); // Too many friends assert_noop!( - Recovery::create_recovery(Origin::signed(5), vec![1, 2, 3, 4], 4, 0), + Recovery::create_recovery( + Origin::signed(5), + vec![1; (MaxFriends::get() + 1) as usize], + 1, + 0 + ), Error::::MaxFriends ); // Unsorted friends diff --git a/substrate/frame/recovery/src/weights.rs b/substrate/frame/recovery/src/weights.rs new file mode 100644 index 0000000000..4e5fb91ae6 --- /dev/null +++ b/substrate/frame/recovery/src/weights.rs @@ -0,0 +1,203 @@ +// This file is part of Substrate. + +// Copyright (C) 2022 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Autogenerated weights for pallet_recovery +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2022-04-26, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// target/production/substrate +// benchmark +// pallet +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet-recovery +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./frame/recovery/src/weights.rs +// --template=.maintain/frame-weight-template.hbs +// --header=HEADER-APACHE2 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weight functions needed for pallet_recovery. +pub trait WeightInfo { + fn as_recovered() -> Weight; + fn set_recovered() -> Weight; + fn create_recovery(n: u32, ) -> Weight; + fn initiate_recovery() -> Weight; + fn vouch_recovery(n: u32, ) -> Weight; + fn claim_recovery(n: u32, ) -> Weight; + fn close_recovery(n: u32, ) -> Weight; + fn remove_recovery(n: u32, ) -> Weight; + fn cancel_recovered() -> Weight; +} + +/// Weights for pallet_recovery using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + // Storage: Recovery Proxy (r:1 w:0) + fn as_recovered() -> Weight { + (3_667_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + } + // Storage: Recovery Proxy (r:0 w:1) + fn set_recovered() -> Weight { + (10_149_000 as Weight) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Recovery Recoverable (r:1 w:1) + fn create_recovery(n: u32, ) -> Weight { + (23_154_000 as Weight) + // Standard Error: 16_000 + .saturating_add((235_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Recovery Recoverable (r:1 w:0) + // Storage: Recovery ActiveRecoveries (r:1 w:1) + fn initiate_recovery() -> Weight { + (28_857_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Recovery Recoverable (r:1 w:0) + // Storage: Recovery ActiveRecoveries (r:1 w:1) + fn vouch_recovery(n: u32, ) -> Weight { + (17_841_000 as Weight) + // Standard Error: 10_000 + .saturating_add((349_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Recovery Recoverable (r:1 w:0) + // Storage: Recovery ActiveRecoveries (r:1 w:0) + // Storage: Recovery Proxy (r:1 w:1) + fn claim_recovery(n: u32, ) -> Weight { + (24_927_000 as Weight) + // Standard Error: 14_000 + .saturating_add((222_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Recovery ActiveRecoveries (r:1 w:1) + // Storage: System Account (r:1 w:1) + fn close_recovery(n: u32, ) -> Weight { + (28_201_000 as Weight) + // Standard Error: 17_000 + .saturating_add((272_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + // Storage: Recovery ActiveRecoveries (r:1 w:0) + // Storage: Recovery Recoverable (r:1 w:1) + fn remove_recovery(n: u32, ) -> Weight { + (27_531_000 as Weight) + // Standard Error: 10_000 + .saturating_add((218_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: Recovery Proxy (r:1 w:1) + fn cancel_recovered() -> Weight { + (9_015_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + // Storage: Recovery Proxy (r:1 w:0) + fn as_recovered() -> Weight { + (3_667_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + } + // Storage: Recovery Proxy (r:0 w:1) + fn set_recovered() -> Weight { + (10_149_000 as Weight) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Recovery Recoverable (r:1 w:1) + fn create_recovery(n: u32, ) -> Weight { + (23_154_000 as Weight) + // Standard Error: 16_000 + .saturating_add((235_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Recovery Recoverable (r:1 w:0) + // Storage: Recovery ActiveRecoveries (r:1 w:1) + fn initiate_recovery() -> Weight { + (28_857_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Recovery Recoverable (r:1 w:0) + // Storage: Recovery ActiveRecoveries (r:1 w:1) + fn vouch_recovery(n: u32, ) -> Weight { + (17_841_000 as Weight) + // Standard Error: 10_000 + .saturating_add((349_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Recovery Recoverable (r:1 w:0) + // Storage: Recovery ActiveRecoveries (r:1 w:0) + // Storage: Recovery Proxy (r:1 w:1) + fn claim_recovery(n: u32, ) -> Weight { + (24_927_000 as Weight) + // Standard Error: 14_000 + .saturating_add((222_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Recovery ActiveRecoveries (r:1 w:1) + // Storage: System Account (r:1 w:1) + fn close_recovery(n: u32, ) -> Weight { + (28_201_000 as Weight) + // Standard Error: 17_000 + .saturating_add((272_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + // Storage: Recovery ActiveRecoveries (r:1 w:0) + // Storage: Recovery Recoverable (r:1 w:1) + fn remove_recovery(n: u32, ) -> Weight { + (27_531_000 as Weight) + // Standard Error: 10_000 + .saturating_add((218_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } + // Storage: Recovery Proxy (r:1 w:1) + fn cancel_recovered() -> Weight { + (9_015_000 as Weight) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(1 as Weight)) + } +}