diff --git a/substrate/Cargo.lock b/substrate/Cargo.lock index cec17f7f96..f02830e0c8 100644 --- a/substrate/Cargo.lock +++ b/substrate/Cargo.lock @@ -5091,8 +5091,10 @@ dependencies = [ name = "pallet-membership" version = "3.0.0" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", + "log", "parity-scale-codec", "sp-core", "sp-io", diff --git a/substrate/bin/node/runtime/Cargo.toml b/substrate/bin/node/runtime/Cargo.toml index edf7109bac..9d72186966 100644 --- a/substrate/bin/node/runtime/Cargo.toml +++ b/substrate/bin/node/runtime/Cargo.toml @@ -180,6 +180,7 @@ runtime-benchmarks = [ "pallet-im-online/runtime-benchmarks", "pallet-indices/runtime-benchmarks", "pallet-lottery/runtime-benchmarks", + "pallet-membership/runtime-benchmarks", "pallet-mmr/runtime-benchmarks", "pallet-multisig/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index b2a59d587d..648bbff633 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -698,6 +698,8 @@ impl pallet_membership::Config for Runtime { type PrimeOrigin = EnsureRootOrHalfCouncil; type MembershipInitialized = TechnicalCommittee; type MembershipChanged = TechnicalCommittee; + type MaxMembers = TechnicalMaxMembers; + type WeightInfo = pallet_membership::weights::SubstrateWeight; } parameter_types! { @@ -1500,6 +1502,7 @@ impl_runtime_apis! { add_benchmark!(params, batches, pallet_im_online, ImOnline); add_benchmark!(params, batches, pallet_indices, Indices); add_benchmark!(params, batches, pallet_lottery, Lottery); + add_benchmark!(params, batches, pallet_membership, TechnicalMembership); add_benchmark!(params, batches, pallet_mmr, Mmr); add_benchmark!(params, batches, pallet_multisig, Multisig); add_benchmark!(params, batches, pallet_offences, OffencesBench::); diff --git a/substrate/frame/benchmarking/src/lib.rs b/substrate/frame/benchmarking/src/lib.rs index ea1bfbd681..63f65db366 100644 --- a/substrate/frame/benchmarking/src/lib.rs +++ b/substrate/frame/benchmarking/src/lib.rs @@ -42,6 +42,16 @@ pub use sp_storage::TrackedStorageKey; #[doc(hidden)] pub use log; +/// Whitelist the given account. +#[macro_export] +macro_rules! whitelist { + ($acc:ident) => { + frame_benchmarking::benchmarking::add_to_whitelist( + frame_system::Account::::hashed_key_for(&$acc).into() + ); + }; +} + /// Construct pallet benchmarks for weighing dispatchables. /// /// Works around the idea of complexity parameters, named by a single letter (which is usually diff --git a/substrate/frame/elections-phragmen/src/benchmarking.rs b/substrate/frame/elections-phragmen/src/benchmarking.rs index cfdcd80207..39e04dcc2d 100644 --- a/substrate/frame/elections-phragmen/src/benchmarking.rs +++ b/substrate/frame/elections-phragmen/src/benchmarking.rs @@ -22,7 +22,7 @@ use super::*; use frame_system::RawOrigin; -use frame_benchmarking::{benchmarks, account, impl_benchmark_test_suite}; +use frame_benchmarking::{benchmarks, account, whitelist, impl_benchmark_test_suite}; use frame_support::traits::OnInitialize; use crate::Module as Elections; @@ -33,14 +33,6 @@ const MAX_CANDIDATES: u32 = 200; type Lookup = <::Lookup as StaticLookup>::Source; -macro_rules! whitelist { - ($acc:ident) => { - frame_benchmarking::benchmarking::add_to_whitelist( - frame_system::Account::::hashed_key_for(&$acc).into() - ); - }; -} - /// grab new account with infinite balance. fn endowed_account(name: &'static str, index: u32) -> T::AccountId { let account: T::AccountId = account(name, index, 0); diff --git a/substrate/frame/im-online/src/weights.rs b/substrate/frame/im-online/src/weights.rs index 147ce11682..83ec294e8e 100644 --- a/substrate/frame/im-online/src/weights.rs +++ b/substrate/frame/im-online/src/weights.rs @@ -44,7 +44,6 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_im_online. pub trait WeightInfo { fn validate_unsigned_and_then_heartbeat(k: u32, e: u32, ) -> Weight; - } /// Weights for pallet_im_online using the Substrate node and recommended hardware. @@ -56,9 +55,7 @@ impl WeightInfo for SubstrateWeight { .saturating_add((481_000 as Weight).saturating_mul(e as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } - } // For backwards compatibility and tests @@ -69,7 +66,5 @@ impl WeightInfo for () { .saturating_add((481_000 as Weight).saturating_mul(e as Weight)) .saturating_add(RocksDbWeight::get().reads(4 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) - } - } diff --git a/substrate/frame/membership/Cargo.toml b/substrate/frame/membership/Cargo.toml index b11e0a2b68..37f9552598 100644 --- a/substrate/frame/membership/Cargo.toml +++ b/substrate/frame/membership/Cargo.toml @@ -14,11 +14,14 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false } +log = { version = "0.4.0", default-features = false } sp-std = { version = "3.0.0", default-features = false, path = "../../primitives/std" } sp-io = { version = "3.0.0", default-features = false, path = "../../primitives/io" } +sp-runtime = { version = "3.0.0", default-features = false, path = "../../primitives/runtime" } frame-support = { version = "3.0.0", default-features = false, path = "../support" } frame-system = { version = "3.0.0", default-features = false, path = "../system" } -sp-runtime = { version = "3.0.0", default-features = false, path = "../../primitives/runtime" } + +frame-benchmarking = { version = "3.1.0", optional = true, default-features = false, path = "../benchmarking" } [dev-dependencies] sp-core = { version = "3.0.0", path = "../../primitives/core" } @@ -27,10 +30,18 @@ sp-core = { version = "3.0.0", path = "../../primitives/core" } default = ["std"] std = [ "codec/std", - "sp-runtime/std", + "log/std", "sp-std/std", "sp-io/std", + "sp-runtime/std", "frame-support/std", "frame-system/std", + "frame-benchmarking/std", +] +runtime-benchmarks = [ + "frame-benchmarking", + "sp-runtime/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", ] try-runtime = ["frame-support/try-runtime"] diff --git a/substrate/frame/membership/src/lib.rs b/substrate/frame/membership/src/lib.rs index 7ad7d6a543..62c9e5eae1 100644 --- a/substrate/frame/membership/src/lib.rs +++ b/substrate/frame/membership/src/lib.rs @@ -18,7 +18,7 @@ //! # Membership Module //! //! Allows control of membership of a set of `AccountId`s, useful for managing membership of of a -//! collective. A prime member may be set. +//! collective. A prime member may be set // Ensure we're `no_std` when compiling for Wasm. #![cfg_attr(not(feature = "std"), no_std)] @@ -26,11 +26,14 @@ use sp_std::prelude::*; use frame_support::{ decl_module, decl_storage, decl_event, decl_error, - traits::{ChangeMembers, InitializeMembers, EnsureOrigin, Contains, SortedMembers}, + traits::{ChangeMembers, InitializeMembers, EnsureOrigin, Contains, SortedMembers, Get}, }; use frame_system::ensure_signed; -pub trait Config: frame_system::Config { +pub mod weights; +pub use weights::WeightInfo; + +pub trait Config: frame_system::Config { /// The overarching event type. type Event: From> + Into<::Event>; @@ -56,6 +59,16 @@ pub trait Config: frame_system::Config { /// The receiver of the signal for when the membership has changed. type MembershipChanged: ChangeMembers; + + /// The maximum number of members that this membership can have. + /// + /// This is used for benchmarking. Re-run the benchmarks if this changes. + /// + /// This is not enforced in the code; the membership size can exceed this limit. + type MaxMembers: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; } decl_storage! { @@ -127,6 +140,8 @@ decl_module! { let mut members = >::get(); let location = members.binary_search(&who).err().ok_or(Error::::AlreadyMember)?; members.insert(location, who.clone()); + + Self::maybe_warn_max_members(&members); >::put(&members); T::MembershipChanged::change_members_sorted(&[who], &[], &members[..]); @@ -144,6 +159,8 @@ decl_module! { let mut members = >::get(); let location = members.binary_search(&who).ok().ok_or(Error::::NotMember)?; members.remove(location); + + Self::maybe_warn_max_members(&members); >::put(&members); T::MembershipChanged::change_members_sorted(&[], &[who], &members[..]); @@ -168,6 +185,8 @@ decl_module! { let _ = members.binary_search(&add).err().ok_or(Error::::AlreadyMember)?; members[location] = add.clone(); members.sort(); + + Self::maybe_warn_max_members(&members); >::put(&members); T::MembershipChanged::change_members_sorted( @@ -193,10 +212,10 @@ decl_module! { >::mutate(|m| { T::MembershipChanged::set_members_sorted(&members[..], m); Self::rejig_prime(&members); + Self::maybe_warn_max_members(&members); *m = members; }); - Self::deposit_event(RawEvent::MembersReset); } @@ -215,6 +234,8 @@ decl_module! { let _ = members.binary_search(&new).err().ok_or(Error::::AlreadyMember)?; members[location] = new.clone(); members.sort(); + + Self::maybe_warn_max_members(&members); >::put(&members); T::MembershipChanged::change_members_sorted( @@ -264,6 +285,17 @@ impl, I: Instance> Module { } } } + + fn maybe_warn_max_members(members: &[T::AccountId]) { + if members.len() as u32 > T::MaxMembers::get() { + log::error!( + target: "runtime::membership", + "maximum number of members used for weight is exceeded, weights can be underestimated [{} > {}].", + members.len(), + T::MaxMembers::get(), + ) + } + } } impl, I: Instance> Contains for Module { @@ -282,6 +314,149 @@ impl, I: Instance> SortedMembers for Module { } } +#[cfg(feature = "runtime-benchmarks")] +mod benchmark { + use super::{*, Module as Membership}; + use frame_system::RawOrigin; + use frame_support::{traits::EnsureOrigin, assert_ok}; + use frame_benchmarking::{benchmarks_instance, whitelist, account, impl_benchmark_test_suite}; + + const SEED: u32 = 0; + + fn set_members, I: Instance>(members: Vec, prime: Option) { + let reset_origin = T::ResetOrigin::successful_origin(); + let prime_origin = T::PrimeOrigin::successful_origin(); + + assert_ok!(>::reset_members(reset_origin, members.clone())); + if let Some(prime) = prime.map(|i| members[i].clone()) { + assert_ok!(>::set_prime(prime_origin, prime)); + } else { + assert_ok!(>::clear_prime(prime_origin)); + } + } + + benchmarks_instance! { + add_member { + let m in 1 .. T::MaxMembers::get(); + + let members = (0..m).map(|i| account("member", i, SEED)).collect::>(); + set_members::(members.clone(), None); + let new_member = account::("add", m, SEED); + }: { + assert_ok!(>::add_member(T::AddOrigin::successful_origin(), new_member.clone())); + } + verify { + assert!(>::get().contains(&new_member)); + #[cfg(test)] crate::tests::clean(); + } + + // the case of no prime or the prime being removed is surely cheaper than the case of + // reporting a new prime via `MembershipChanged`. + remove_member { + let m in 2 .. T::MaxMembers::get(); + + let members = (0..m).map(|i| account("member", i, SEED)).collect::>(); + set_members::(members.clone(), Some(members.len() - 1)); + + let to_remove = members.first().cloned().unwrap(); + }: { + assert_ok!(>::remove_member(T::RemoveOrigin::successful_origin(), to_remove.clone())); + } verify { + assert!(!>::get().contains(&to_remove)); + // prime is rejigged + assert!(>::get().is_some() && T::MembershipChanged::get_prime().is_some()); + #[cfg(test)] crate::tests::clean(); + } + + // we remove a non-prime to make sure it needs to be set again. + swap_member { + let m in 2 .. T::MaxMembers::get(); + + let members = (0..m).map(|i| account("member", i, SEED)).collect::>(); + set_members::(members.clone(), Some(members.len() - 1)); + let add = account::("member", m, SEED); + let remove = members.first().cloned().unwrap(); + }: { + assert_ok!(>::swap_member( + T::SwapOrigin::successful_origin(), + remove.clone(), + add.clone(), + )); + } verify { + assert!(!>::get().contains(&remove)); + assert!(>::get().contains(&add)); + // prime is rejigged + assert!(>::get().is_some() && T::MembershipChanged::get_prime().is_some()); + #[cfg(test)] crate::tests::clean(); + } + + // er keep the prime common between incoming and outgoing to make sure it is rejigged. + reset_member { + let m in 1 .. T::MaxMembers::get(); + + let members = (1..m+1).map(|i| account("member", i, SEED)).collect::>(); + set_members::(members.clone(), Some(members.len() - 1)); + let mut new_members = (m..2*m).map(|i| account("member", i, SEED)).collect::>(); + }: { + assert_ok!(>::reset_members(T::ResetOrigin::successful_origin(), new_members.clone())); + } verify { + new_members.sort(); + assert_eq!(>::get(), new_members); + // prime is rejigged + assert!(>::get().is_some() && T::MembershipChanged::get_prime().is_some()); + #[cfg(test)] crate::tests::clean(); + } + + change_key { + let m in 1 .. T::MaxMembers::get(); + + // worse case would be to change the prime + let members = (0..m).map(|i| account("member", i, SEED)).collect::>(); + let prime = members.last().cloned().unwrap(); + set_members::(members.clone(), Some(members.len() - 1)); + + let add = account::("member", m, SEED); + whitelist!(prime); + }: { + assert_ok!(>::change_key(RawOrigin::Signed(prime.clone()).into(), add.clone())); + } verify { + assert!(!>::get().contains(&prime)); + assert!(>::get().contains(&add)); + // prime is rejigged + assert_eq!(>::get().unwrap(), add); + #[cfg(test)] crate::tests::clean(); + } + + set_prime { + let m in 1 .. T::MaxMembers::get(); + let members = (0..m).map(|i| account("member", i, SEED)).collect::>(); + let prime = members.last().cloned().unwrap(); + set_members::(members, None); + }: { + assert_ok!(>::set_prime(T::PrimeOrigin::successful_origin(), prime)); + } verify { + assert!(>::get().is_some()); + assert!(::get_prime().is_some()); + #[cfg(test)] crate::tests::clean(); + } + + clear_prime { + let m in 1 .. T::MaxMembers::get(); + let members = (0..m).map(|i| account("member", i, SEED)).collect::>(); + let prime = members.last().cloned().unwrap(); + set_members::(members, None); + }: { + assert_ok!(>::clear_prime(T::PrimeOrigin::successful_origin())); + } verify { + assert!(>::get().is_none()); + assert!(::get_prime().is_none()); + #[cfg(test)] crate::tests::clean(); + } + } + + impl_benchmark_test_suite!(Membership, crate::tests::new_bench_ext(), crate::tests::Test,); +} + #[cfg(test)] mod tests { use super::*; @@ -308,11 +483,13 @@ mod tests { parameter_types! { pub const BlockHashCount: u64 = 250; + pub const MaxMembers: u32 = 10; pub BlockWeights: frame_system::limits::BlockWeights = frame_system::limits::BlockWeights::simple_max(1024); pub static Members: Vec = vec![]; pub static Prime: Option = None; } + impl frame_system::Config for Test { type BaseCallFilter = (); type BlockWeights = (); @@ -349,7 +526,7 @@ mod tests { pub struct TestChangeMembers; impl ChangeMembers for TestChangeMembers { fn change_members_sorted(incoming: &[u64], outgoing: &[u64], new: &[u64]) { - let mut old_plus_incoming = MEMBERS.with(|m| m.borrow().to_vec()); + let mut old_plus_incoming = Members::get(); old_plus_incoming.extend_from_slice(incoming); old_plus_incoming.sort(); let mut new_plus_outgoing = new.to_vec(); @@ -357,13 +534,17 @@ mod tests { new_plus_outgoing.sort(); assert_eq!(old_plus_incoming, new_plus_outgoing); - MEMBERS.with(|m| *m.borrow_mut() = new.to_vec()); - PRIME.with(|p| *p.borrow_mut() = None); + Members::set(new.to_vec()); + Prime::set(None); } fn set_prime(who: Option) { - PRIME.with(|p| *p.borrow_mut() = who); + Prime::set(who); + } + fn get_prime() -> Option { + Prime::get() } } + impl InitializeMembers for TestChangeMembers { fn initialize_members(members: &[u64]) { MEMBERS.with(|m| *m.borrow_mut() = members.to_vec()); @@ -379,9 +560,11 @@ mod tests { type PrimeOrigin = EnsureSignedBy; type MembershipInitialized = TestChangeMembers; type MembershipChanged = TestChangeMembers; + type MaxMembers = MaxMembers; + type WeightInfo = (); } - fn new_test_ext() -> sp_io::TestExternalities { + pub(crate) fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); // We use default for brevity, but you can configure as desired if needed. pallet_membership::GenesisConfig::{ @@ -391,6 +574,17 @@ mod tests { t.into() } + #[cfg(feature = "runtime-benchmarks")] + pub(crate) fn new_bench_ext() -> sp_io::TestExternalities { + frame_system::GenesisConfig::default().build_storage::().unwrap().into() + } + + #[cfg(feature = "runtime-benchmarks")] + pub(crate) fn clean() { + Members::set(vec![]); + Prime::set(None); + } + #[test] fn query_membership_works() { new_test_ext().execute_with(|| { diff --git a/substrate/frame/membership/src/weights.rs b/substrate/frame/membership/src/weights.rs new file mode 100644 index 0000000000..fbdb44caec --- /dev/null +++ b/substrate/frame/membership/src/weights.rs @@ -0,0 +1,159 @@ +// This file is part of Substrate. + +// Copyright (C) 2021 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_membership +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0 +//! DATE: 2021-04-17, STEPS: `[50, ]`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128 + +// Executed Command: +// target/release/substrate +// benchmark +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_membership +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./frame/membership/src/weights.rs +// --template=./.maintain/frame-weight-template.hbs + + +#![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_membership. +pub trait WeightInfo { + fn add_member(m: u32, ) -> Weight; + fn remove_member(m: u32, ) -> Weight; + fn swap_member(m: u32, ) -> Weight; + fn reset_member(m: u32, ) -> Weight; + fn change_key(m: u32, ) -> Weight; + fn set_prime(m: u32, ) -> Weight; + fn clear_prime(m: u32, ) -> Weight; +} + +/// Weights for pallet_membership using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + fn add_member(m: u32, ) -> Weight { + (25_448_000 as Weight) + // Standard Error: 3_000 + .saturating_add((257_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn remove_member(m: u32, ) -> Weight { + (31_317_000 as Weight) + // Standard Error: 0 + .saturating_add((215_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn swap_member(m: u32, ) -> Weight { + (31_208_000 as Weight) + // Standard Error: 0 + .saturating_add((229_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn reset_member(m: u32, ) -> Weight { + (31_673_000 as Weight) + // Standard Error: 1_000 + .saturating_add((455_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + fn change_key(m: u32, ) -> Weight { + (33_499_000 as Weight) + // Standard Error: 0 + .saturating_add((226_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + fn set_prime(m: u32, ) -> Weight { + (8_865_000 as Weight) + // Standard Error: 0 + .saturating_add((124_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn clear_prime(m: u32, ) -> Weight { + (3_397_000 as Weight) + // Standard Error: 0 + .saturating_add((1_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + fn add_member(m: u32, ) -> Weight { + (25_448_000 as Weight) + // Standard Error: 3_000 + .saturating_add((257_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(RocksDbWeight::get().reads(2 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn remove_member(m: u32, ) -> Weight { + (31_317_000 as Weight) + // Standard Error: 0 + .saturating_add((215_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn swap_member(m: u32, ) -> Weight { + (31_208_000 as Weight) + // Standard Error: 0 + .saturating_add((229_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn reset_member(m: u32, ) -> Weight { + (31_673_000 as Weight) + // Standard Error: 1_000 + .saturating_add((455_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(3 as Weight)) + } + fn change_key(m: u32, ) -> Weight { + (33_499_000 as Weight) + // Standard Error: 0 + .saturating_add((226_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(RocksDbWeight::get().reads(3 as Weight)) + .saturating_add(RocksDbWeight::get().writes(4 as Weight)) + } + fn set_prime(m: u32, ) -> Weight { + (8_865_000 as Weight) + // Standard Error: 0 + .saturating_add((124_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(RocksDbWeight::get().reads(1 as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } + fn clear_prime(m: u32, ) -> Weight { + (3_397_000 as Weight) + // Standard Error: 0 + .saturating_add((1_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(RocksDbWeight::get().writes(2 as Weight)) + } +}