diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 17c02eca17b4a..54dea704bd7f6 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -509,6 +509,7 @@ impl pallet_democracy::Trait for Runtime { parameter_types! { pub const CouncilMotionDuration: BlockNumber = 5 * DAYS; pub const CouncilMaxProposals: u32 = 100; + pub const CouncilMaxMembers: u32 = 100; } type CouncilCollective = pallet_collective::Instance1; @@ -518,7 +519,8 @@ impl pallet_collective::Trait for Runtime { type Event = Event; type MotionDuration = CouncilMotionDuration; type MaxProposals = CouncilMaxProposals; - type WeightInfo = (); + type MaxMembers = CouncilMaxMembers; + type WeightInfo = weights::pallet_collective::WeightInfo; } parameter_types! { @@ -530,8 +532,8 @@ parameter_types! { pub const ElectionsPhragmenModuleId: LockIdentifier = *b"phrelect"; } -// Make sure that there are no more than `MAX_MEMBERS` members elected via elections-phragmen. -const_assert!(DesiredMembers::get() <= pallet_collective::MAX_MEMBERS); +// Make sure that there are no more than `MaxMembers` members elected via elections-phragmen. +const_assert!(DesiredMembers::get() <= CouncilMaxMembers::get()); impl pallet_elections_phragmen::Trait for Runtime { type Event = Event; @@ -556,6 +558,7 @@ impl pallet_elections_phragmen::Trait for Runtime { parameter_types! { pub const TechnicalMotionDuration: BlockNumber = 5 * DAYS; pub const TechnicalMaxProposals: u32 = 100; + pub const TechnicalMaxMembers: u32 = 100; } type TechnicalCollective = pallet_collective::Instance2; @@ -565,7 +568,8 @@ impl pallet_collective::Trait for Runtime { type Event = Event; type MotionDuration = TechnicalMotionDuration; type MaxProposals = TechnicalMaxProposals; - type WeightInfo = (); + type MaxMembers = TechnicalMaxMembers; + type WeightInfo = weights::pallet_collective::WeightInfo; } type EnsureRootOrHalfCouncil = EnsureOneOf< diff --git a/bin/node/runtime/src/weights/mod.rs b/bin/node/runtime/src/weights/mod.rs index 322fb8886c0f4..372b13a093e27 100644 --- a/bin/node/runtime/src/weights/mod.rs +++ b/bin/node/runtime/src/weights/mod.rs @@ -17,6 +17,7 @@ pub mod frame_system; pub mod pallet_balances; +pub mod pallet_collective; pub mod pallet_democracy; pub mod pallet_proxy; pub mod pallet_timestamp; diff --git a/bin/node/runtime/src/weights/pallet_collective.rs b/bin/node/runtime/src/weights/pallet_collective.rs new file mode 100644 index 0000000000000..32b4ad02d7aa9 --- /dev/null +++ b/bin/node/runtime/src/weights/pallet_collective.rs @@ -0,0 +1,97 @@ +// Copyright (C) 2020 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. + +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc6 + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +pub struct WeightInfo; +impl pallet_collective::WeightInfo for WeightInfo { + fn set_members(m: u32, n: u32, p: u32, ) -> Weight { + (0 as Weight) + .saturating_add((21040000 as Weight).saturating_mul(m as Weight)) + .saturating_add((173000 as Weight).saturating_mul(n as Weight)) + .saturating_add((31595000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(p as Weight))) + .saturating_add(DbWeight::get().writes(2 as Weight)) + .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(p as Weight))) + } + fn execute(b: u32, m: u32, ) -> Weight { + (43359000 as Weight) + .saturating_add((4000 as Weight).saturating_mul(b as Weight)) + .saturating_add((123000 as Weight).saturating_mul(m as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + } + fn propose_execute(b: u32, m: u32, ) -> Weight { + (54134000 as Weight) + .saturating_add((4000 as Weight).saturating_mul(b as Weight)) + .saturating_add((239000 as Weight).saturating_mul(m as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + } + fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { + (90650000 as Weight) + .saturating_add((5000 as Weight).saturating_mul(b as Weight)) + .saturating_add((152000 as Weight).saturating_mul(m as Weight)) + .saturating_add((970000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(4 as Weight)) + .saturating_add(DbWeight::get().writes(4 as Weight)) + } + fn vote(m: u32, ) -> Weight { + (74460000 as Weight) + .saturating_add((290000 as Weight).saturating_mul(m as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn close_early_disapproved(m: u32, p: u32, ) -> Weight { + (86360000 as Weight) + .saturating_add((232000 as Weight).saturating_mul(m as Weight)) + .saturating_add((954000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { + (123653000 as Weight) + .saturating_add((1000 as Weight).saturating_mul(b as Weight)) + .saturating_add((287000 as Weight).saturating_mul(m as Weight)) + .saturating_add((920000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(4 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn close_disapproved(m: u32, p: u32, ) -> Weight { + (95395000 as Weight) + .saturating_add((236000 as Weight).saturating_mul(m as Weight)) + .saturating_add((965000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(4 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { + (135284000 as Weight) + .saturating_add((4000 as Weight).saturating_mul(b as Weight)) + .saturating_add((218000 as Weight).saturating_mul(m as Weight)) + .saturating_add((951000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(5 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn disapprove_proposal(p: u32, ) -> Weight { + (50500000 as Weight) + .saturating_add((966000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } +} diff --git a/frame/collective/src/benchmarking.rs b/frame/collective/src/benchmarking.rs index 2c777fadc4cc4..d4e80d515941f 100644 --- a/frame/collective/src/benchmarking.rs +++ b/frame/collective/src/benchmarking.rs @@ -45,8 +45,8 @@ benchmarks_instance! { _{ } set_members { - let m in 1 .. MAX_MEMBERS; - let n in 1 .. MAX_MEMBERS; + let m in 1 .. T::MaxMembers::get(); + let n in 1 .. T::MaxMembers::get(); let p in 1 .. T::MaxProposals::get(); // Set old members. @@ -63,7 +63,7 @@ benchmarks_instance! { SystemOrigin::Root.into(), old_members.clone(), Some(last_old_member.clone()), - MAX_MEMBERS, + T::MaxMembers::get(), )?; // Set a high threshold for proposals passing so that they stay around. @@ -104,15 +104,15 @@ benchmarks_instance! { new_members.push(last_member.clone()); } - }: _(SystemOrigin::Root, new_members.clone(), Some(last_member), MAX_MEMBERS) + }: _(SystemOrigin::Root, new_members.clone(), Some(last_member), T::MaxMembers::get()) verify { new_members.sort(); assert_eq!(Collective::::members(), new_members); } execute { - let m in 1 .. MAX_MEMBERS; let b in 1 .. MAX_BYTES; + let m in 1 .. T::MaxMembers::get(); let bytes_in_storage = b + size_of::() as u32; @@ -126,7 +126,7 @@ benchmarks_instance! { let caller: T::AccountId = whitelisted_caller(); members.push(caller.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members, None, MAX_MEMBERS)?; + Collective::::set_members(SystemOrigin::Root.into(), members, None, T::MaxMembers::get())?; let proposal: T::Proposal = SystemCall::::remark(vec![1; b as usize]).into(); @@ -141,8 +141,8 @@ benchmarks_instance! { // This tests when execution would happen immediately after proposal propose_execute { - let m in 1 .. MAX_MEMBERS; let b in 1 .. MAX_BYTES; + let m in 1 .. T::MaxMembers::get(); let bytes_in_storage = b + size_of::() as u32; @@ -156,7 +156,7 @@ benchmarks_instance! { let caller: T::AccountId = whitelisted_caller(); members.push(caller.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members, None, MAX_MEMBERS)?; + Collective::::set_members(SystemOrigin::Root.into(), members, None, T::MaxMembers::get())?; let proposal: T::Proposal = SystemCall::::remark(vec![1; b as usize]).into(); let threshold = 1; @@ -172,9 +172,9 @@ benchmarks_instance! { // This tests when proposal is created and queued as "proposed" propose_proposed { - let m in 2 .. MAX_MEMBERS; - let p in 1 .. T::MaxProposals::get(); let b in 1 .. MAX_BYTES; + let m in 2 .. T::MaxMembers::get(); + let p in 1 .. T::MaxProposals::get(); let bytes_in_storage = b + size_of::() as u32; @@ -186,7 +186,7 @@ benchmarks_instance! { } let caller: T::AccountId = whitelisted_caller(); members.push(caller.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members, None, MAX_MEMBERS)?; + Collective::::set_members(SystemOrigin::Root.into(), members, None, T::MaxMembers::get())?; let threshold = m; // Add previous proposals. @@ -215,7 +215,7 @@ benchmarks_instance! { vote { // We choose 5 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) - let m in 5 .. MAX_MEMBERS; + let m in 5 .. T::MaxMembers::get(); let p = T::MaxProposals::get(); let b = MAX_BYTES; @@ -231,7 +231,7 @@ benchmarks_instance! { } let voter: T::AccountId = account("voter", 0, SEED); members.push(voter.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, MAX_MEMBERS)?; + Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; // Threshold is 1 less than the number of members so that one person can vote nay let threshold = m - 1; @@ -277,6 +277,9 @@ benchmarks_instance! { // Voter switches vote to nay, but does not kill the vote, just updates + inserts let approve = false; + // Whitelist voter account from further DB operations. + let voter_key = frame_system::Account::::hashed_key_for(&voter); + frame_benchmarking::benchmarking::add_to_whitelist(voter_key.into()); }: _(SystemOrigin::Signed(voter), last_hash.clone(), index, approve) verify { // All proposals exist and the last proposal has just been updated. @@ -288,11 +291,11 @@ benchmarks_instance! { close_early_disapproved { // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) - let m in 4 .. MAX_MEMBERS; + let m in 4 .. T::MaxMembers::get(); let p in 1 .. T::MaxProposals::get(); - let b in 1 .. MAX_BYTES; - let bytes_in_storage = b + size_of::() as u32; + let bytes = 100; + let bytes_in_storage = bytes + size_of::() as u32; // Construct `members`. let mut members = vec![]; @@ -304,7 +307,7 @@ benchmarks_instance! { } let voter: T::AccountId = account("voter", 0, SEED); members.push(voter.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, MAX_MEMBERS)?; + Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; // Threshold is total members so that one nay will disapprove the vote let threshold = m; @@ -313,7 +316,7 @@ benchmarks_instance! { let mut last_hash = T::Hash::default(); for i in 0 .. p { // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = SystemCall::::remark(vec![i as u8; b as usize]).into(); + let proposal: T::Proposal = SystemCall::::remark(vec![i as u8; bytes as usize]).into(); Collective::::propose( SystemOrigin::Signed(proposer.clone()).into(), threshold, @@ -356,6 +359,9 @@ benchmarks_instance! { approve, )?; + // Whitelist voter account from further DB operations. + let voter_key = frame_system::Account::::hashed_key_for(&voter); + frame_benchmarking::benchmarking::add_to_whitelist(voter_key.into()); }: close(SystemOrigin::Signed(voter), last_hash.clone(), index, Weight::max_value(), bytes_in_storage) verify { // The last proposal is removed. @@ -364,10 +370,10 @@ benchmarks_instance! { } close_early_approved { + let b in 1 .. MAX_BYTES; // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) - let m in 4 .. MAX_MEMBERS; + let m in 4 .. T::MaxMembers::get(); let p in 1 .. T::MaxProposals::get(); - let b in 1 .. MAX_BYTES; let bytes_in_storage = b + size_of::() as u32; @@ -379,7 +385,7 @@ benchmarks_instance! { } let caller: T::AccountId = whitelisted_caller(); members.push(caller.clone()); - Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, MAX_MEMBERS)?; + Collective::::set_members(SystemOrigin::Root.into(), members.clone(), None, T::MaxMembers::get())?; // Threshold is 2 so any two ayes will approve the vote let threshold = 2; @@ -446,11 +452,11 @@ benchmarks_instance! { close_disapproved { // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) - let m in 4 .. MAX_MEMBERS; + let m in 4 .. T::MaxMembers::get(); let p in 1 .. T::MaxProposals::get(); - let b in 1 .. MAX_BYTES; - let bytes_in_storage = b + size_of::() as u32; + let bytes = 100; + let bytes_in_storage = bytes + size_of::() as u32; // Construct `members`. let mut members = vec![]; @@ -464,7 +470,7 @@ benchmarks_instance! { SystemOrigin::Root.into(), members.clone(), Some(caller.clone()), - MAX_MEMBERS, + T::MaxMembers::get(), )?; // Threshold is one less than total members so that two nays will disapprove the vote @@ -474,7 +480,7 @@ benchmarks_instance! { let mut last_hash = T::Hash::default(); for i in 0 .. p { // Proposals should be different so that different proposal hashes are generated - let proposal: T::Proposal = SystemCall::::remark(vec![i as u8; b as usize]).into(); + let proposal: T::Proposal = SystemCall::::remark(vec![i as u8; bytes as usize]).into(); Collective::::propose( SystemOrigin::Signed(caller.clone()).into(), threshold, @@ -517,10 +523,10 @@ benchmarks_instance! { } close_approved { + let b in 1 .. MAX_BYTES; // We choose 4 as a minimum so we always trigger a vote in the voting loop (`for j in ...`) - let m in 4 .. MAX_MEMBERS; + let m in 4 .. T::MaxMembers::get(); let p in 1 .. T::MaxProposals::get(); - let b in 1 .. MAX_BYTES; let bytes_in_storage = b + size_of::() as u32; @@ -536,7 +542,7 @@ benchmarks_instance! { SystemOrigin::Root.into(), members.clone(), Some(caller.clone()), - MAX_MEMBERS, + T::MaxMembers::get(), )?; // Threshold is two, so any two ayes will pass the vote @@ -579,6 +585,54 @@ benchmarks_instance! { assert_eq!(Collective::::proposals().len(), (p - 1) as usize); assert_last_event::(RawEvent::Executed(last_hash, Err(DispatchError::BadOrigin)).into()); } + + disapprove_proposal { + let p in 1 .. T::MaxProposals::get(); + + let m = 3; + let b = MAX_BYTES; + let bytes_in_storage = b + size_of::() as u32; + + // Construct `members`. + let mut members = vec![]; + for i in 0 .. m - 1 { + let member = account("member", i, SEED); + members.push(member); + } + let caller: T::AccountId = account("caller", 0, SEED); + members.push(caller.clone()); + Collective::::set_members( + SystemOrigin::Root.into(), + members.clone(), + Some(caller.clone()), + T::MaxMembers::get(), + )?; + + // Threshold is one less than total members so that two nays will disapprove the vote + let threshold = m - 1; + + // Add proposals + let mut last_hash = T::Hash::default(); + for i in 0 .. p { + // Proposals should be different so that different proposal hashes are generated + let proposal: T::Proposal = SystemCall::::remark(vec![i as u8; b as usize]).into(); + Collective::::propose( + SystemOrigin::Signed(caller.clone()).into(), + threshold, + Box::new(proposal.clone()), + bytes_in_storage, + )?; + last_hash = T::Hashing::hash_of(&proposal); + } + + System::::set_block_number(T::BlockNumber::max_value()); + assert_eq!(Collective::::proposals().len(), p as usize); + + }: _(SystemOrigin::Root, last_hash) + verify { + assert_eq!(Collective::::proposals().len(), (p - 1) as usize); + assert_last_event::(RawEvent::Disapproved(last_hash).into()); + } } #[cfg(test)] @@ -649,4 +703,11 @@ mod tests { assert_ok!(test_benchmark_close_approved::()); }); } + + #[test] + fn disapprove_proposal() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_disapprove_proposal::()); + }); + } } diff --git a/frame/collective/src/default_weight.rs b/frame/collective/src/default_weight.rs new file mode 100644 index 0000000000000..bb6fe0ea25312 --- /dev/null +++ b/frame/collective/src/default_weight.rs @@ -0,0 +1,97 @@ +// Copyright (C) 2020 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. + +//! Default weights for the Collective Pallet +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 2.0.0-rc6 + +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::weights::{Weight, constants::RocksDbWeight as DbWeight}; + +impl crate::WeightInfo for () { + fn set_members(m: u32, n: u32, p: u32, ) -> Weight { + (0 as Weight) + .saturating_add((21040000 as Weight).saturating_mul(m as Weight)) + .saturating_add((173000 as Weight).saturating_mul(n as Weight)) + .saturating_add((31595000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().reads((1 as Weight).saturating_mul(p as Weight))) + .saturating_add(DbWeight::get().writes(2 as Weight)) + .saturating_add(DbWeight::get().writes((1 as Weight).saturating_mul(p as Weight))) + } + fn execute(b: u32, m: u32, ) -> Weight { + (43359000 as Weight) + .saturating_add((4000 as Weight).saturating_mul(b as Weight)) + .saturating_add((123000 as Weight).saturating_mul(m as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + } + fn propose_execute(b: u32, m: u32, ) -> Weight { + (54134000 as Weight) + .saturating_add((4000 as Weight).saturating_mul(b as Weight)) + .saturating_add((239000 as Weight).saturating_mul(m as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + } + fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight { + (90650000 as Weight) + .saturating_add((5000 as Weight).saturating_mul(b as Weight)) + .saturating_add((152000 as Weight).saturating_mul(m as Weight)) + .saturating_add((970000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(4 as Weight)) + .saturating_add(DbWeight::get().writes(4 as Weight)) + } + fn vote(m: u32, ) -> Weight { + (74460000 as Weight) + .saturating_add((290000 as Weight).saturating_mul(m as Weight)) + .saturating_add(DbWeight::get().reads(2 as Weight)) + .saturating_add(DbWeight::get().writes(1 as Weight)) + } + fn close_early_disapproved(m: u32, p: u32, ) -> Weight { + (86360000 as Weight) + .saturating_add((232000 as Weight).saturating_mul(m as Weight)) + .saturating_add((954000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(3 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight { + (123653000 as Weight) + .saturating_add((1000 as Weight).saturating_mul(b as Weight)) + .saturating_add((287000 as Weight).saturating_mul(m as Weight)) + .saturating_add((920000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(4 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn close_disapproved(m: u32, p: u32, ) -> Weight { + (95395000 as Weight) + .saturating_add((236000 as Weight).saturating_mul(m as Weight)) + .saturating_add((965000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(4 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn close_approved(b: u32, m: u32, p: u32, ) -> Weight { + (135284000 as Weight) + .saturating_add((4000 as Weight).saturating_mul(b as Weight)) + .saturating_add((218000 as Weight).saturating_mul(m as Weight)) + .saturating_add((951000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(5 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } + fn disapprove_proposal(p: u32, ) -> Weight { + (50500000 as Weight) + .saturating_add((966000 as Weight).saturating_mul(p as Weight)) + .saturating_add(DbWeight::get().reads(1 as Weight)) + .saturating_add(DbWeight::get().writes(3 as Weight)) + } +} diff --git a/frame/collective/src/lib.rs b/frame/collective/src/lib.rs index 1edd8c75b90b0..949484a5957b4 100644 --- a/frame/collective/src/lib.rs +++ b/frame/collective/src/lib.rs @@ -20,7 +20,7 @@ //! //! The membership can be provided in one of two ways: either directly, using the Root-dispatchable //! function `set_members`, or indirectly, through implementing the `ChangeMembers`. -//! The pallet assumes that the amount of members stays at or below `MAX_MEMBERS` for its weight +//! The pallet assumes that the amount of members stays at or below `MaxMembers` for its weight //! calculations, but enforces this neither in `set_members` nor in `change_members_sorted`. //! //! A "prime" member may be set allowing their vote to act as the default vote in case of any @@ -60,6 +60,8 @@ use frame_system::{self as system, ensure_signed, ensure_root}; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; +mod default_weight; + /// Simple index type for proposal counting. pub type ProposalIndex = u32; @@ -69,35 +71,17 @@ pub type ProposalIndex = u32; /// vote exactly once, therefore also the number of votes for any given motion. pub type MemberCount = u32; -/// The maximum number of members supported by the pallet. Used for weight estimation. -/// -/// NOTE: -/// + Benchmarks will need to be re-run and weights adjusted if this changes. -/// + This pallet assumes that dependents keep to the limit without enforcing it. -pub const MAX_MEMBERS: MemberCount = 100; - pub trait WeightInfo { fn set_members(m: u32, n: u32, p: u32, ) -> Weight; - fn execute(m: u32, b: u32, ) -> Weight; - fn propose_execute(m: u32, b: u32, ) -> Weight; - fn propose_proposed(m: u32, p: u32, b: u32, ) -> Weight; + fn execute(b: u32, m: u32, ) -> Weight; + fn propose_execute(b: u32, m: u32, ) -> Weight; + fn propose_proposed(b: u32, m: u32, p: u32, ) -> Weight; fn vote(m: u32, ) -> Weight; - fn close_early_disapproved(m: u32, p: u32, b: u32, ) -> Weight; - fn close_early_approved(m: u32, p: u32, b: u32, ) -> Weight; - fn close_disapproved(m: u32, p: u32, b: u32, ) -> Weight; - fn close_approved(m: u32, p: u32, b: u32, ) -> Weight; -} - -impl WeightInfo for () { - fn set_members(_m: u32, _n: u32, _p: u32, ) -> Weight { 1_000_000_000 } - fn execute(_m: u32, _b: u32, ) -> Weight { 1_000_000_000 } - fn propose_execute(_m: u32, _b: u32, ) -> Weight { 1_000_000_000 } - fn propose_proposed(_m: u32, _p: u32, _b: u32, ) -> Weight { 1_000_000_000 } - fn vote(_m: u32, ) -> Weight { 1_000_000_000 } - fn close_early_disapproved(_m: u32, _p: u32, _b: u32, ) -> Weight { 1_000_000_000 } - fn close_early_approved(_m: u32, _p: u32, _b: u32, ) -> Weight { 1_000_000_000 } - fn close_disapproved(_m: u32, _p: u32, _b: u32, ) -> Weight { 1_000_000_000 } - fn close_approved(_m: u32, _p: u32, _b: u32, ) -> Weight { 1_000_000_000 } + fn close_early_disapproved(m: u32, p: u32, ) -> Weight; + fn close_early_approved(b: u32, m: u32, p: u32, ) -> Weight; + fn close_disapproved(m: u32, p: u32, ) -> Weight; + fn close_approved(b: u32, m: u32, p: u32, ) -> Weight; + fn disapprove_proposal(p: u32, ) -> Weight; } pub trait Trait: frame_system::Trait { @@ -117,7 +101,14 @@ pub trait Trait: frame_system::Trait { type MotionDuration: Get; /// Maximum number of proposals allowed to be active in parallel. - type MaxProposals: Get; + type MaxProposals: Get; + + /// The maximum number of members supported by the pallet. Used for weight estimation. + /// + /// NOTE: + /// + Benchmarks will need to be re-run and weights adjusted if this changes. + /// + This pallet assumes that dependents keep to the limit without enforcing it. + type MaxMembers: Get; /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; @@ -233,131 +224,6 @@ decl_error! { } } -/// Functions for calcuating the weight of dispatchables. -mod weight_for { - use frame_support::{traits::Get, weights::Weight}; - use super::{Trait, Instance}; - - /// Calculate the weight for `set_members`. - /// - /// Based on benchmark: - /// 0 + M * 20.47 + N * 0.109 + P * 26.29 µs (min squares analysis) - /// - /// Note: The complexity of `set_members` is quadratic (`O(MP + N)`), so the linear approximation - /// of the benchmark is not always permissible. It is here, though, because the linear approximation - /// covered the range of possible values and we estimate weight via the worst case (max paramter - /// values) before execution so we can be sure that we are only overestimating. - pub(crate) fn set_members, I: Instance>( - old_count: Weight, - new_count: Weight, - proposals: Weight, - ) -> Weight { - let db = T::DbWeight::get(); - db.reads_writes(1, 1) // mutate `Members` - .saturating_add(db.writes(1)) // set `Prime` - .saturating_add(db.reads(1)) // read `Proposals` - .saturating_add(db.reads_writes(proposals, proposals)) // update votes (`Voting`) - .saturating_add(old_count.saturating_mul(21_000_000)) // M - .saturating_add(new_count.saturating_mul(110_000)) // N - .saturating_add(proposals.saturating_mul(27_000_000)) // P - } - - /// Calculate the weight for `execute`. - /// - /// Based on benchmark: - /// 22.62 + M * 0.115 + B * 0.003 µs (min squares analysis) - pub(crate) fn execute, I: Instance>( - members: Weight, - proposal: Weight, - length: Weight, - ) -> Weight { - T::DbWeight::get().reads(1) // read members for `is_member` - .saturating_add(23_000_000) // constant - .saturating_add(length.saturating_mul(4_000)) // B - .saturating_add(members.saturating_mul(120_000)) // M - .saturating_add(proposal) // P - } - - /// Calculate the weight for `propose` if the proposal is executed straight away (`threshold < 2`). - /// - /// Based on benchmark: - /// 28.12 + M * 0.218 + B * 0.003 µs (min squares analysis) - pub(crate) fn propose_execute, I: Instance>( - members: Weight, - proposal: Weight, - length: Weight, - ) -> Weight { - T::DbWeight::get().reads(2) // `is_member` + `contains_key` - .saturating_add(29_000_000) // constant - .saturating_add(length.saturating_mul(3_000)) // B - .saturating_add(members.saturating_mul(220_000)) // M - .saturating_add(proposal) // P1 - } - - /// Calculate the weight for `propose` if the proposal is put up for a vote (`threshold >= 2`). - /// - /// Based on benchmark: - /// 49.75 + M * 0.105 + P2 0.502 + B * 0.006 µs (min squares analysis) - pub(crate) fn propose_proposed, I: Instance>( - members: Weight, - proposals: Weight, - length: Weight, - ) -> Weight { - T::DbWeight::get().reads(2) // `is_member` + `contains_key` - .saturating_add(T::DbWeight::get().reads_writes(2, 4)) // `proposal` insertion - .saturating_add(50_000_000) // constant - .saturating_add(length.saturating_mul(6_000)) // B - .saturating_add(members.saturating_mul(110_000)) // M - .saturating_add(proposals.saturating_mul(510_000)) // P2 - } - - /// Calculate the weight for `vote`. - /// - /// Based on benchmark: - /// 24.03 + M * 0.349 + P * 0.119 + B * 0.003 µs (min squares analysis) - pub(crate) fn vote, I: Instance>( - members: Weight, - ) -> Weight { - T::DbWeight::get().reads(1) // read `Members` - .saturating_add(T::DbWeight::get().reads_writes(1, 1)) // mutate `Voting` - .saturating_add(30_000_000) // constant - .saturating_add(members.saturating_mul(500_000)) // M - } - - /// Calculate the weight for `close`. - /// - /// Based on benchmarks: - /// - early disapproved: 37.21 + M * 0.239 + P2 * 0.466 + B * 0.002 µs (min squares analysis) - /// - early approved: 50.82 + M * 0.211 + P2 * 0.478 + B * 0.008 µs (min squares analysis) - /// - disapproved: 51.08 + M * 0.224 + P2 * 0.475 + B * 0.003 µs (min squares analysis) - /// - approved: 65.95 + M * 0.226 + P2 * 0.487 + B * 0.005 µs (min squares analysis) - pub(crate) fn close, I: Instance>( - members: Weight, - proposal_weight: Weight, - proposals: Weight, - length: Weight, - ) -> Weight { - let db = T::DbWeight::get(); - close_without_finalize::(members, length) - .saturating_add(db.reads(1)) // `Prime` - .saturating_add(db.writes(1)) // `Proposals` - .saturating_add(db.writes(1)) // `Voting` - .saturating_add(proposal_weight) // P1 - .saturating_add(proposals.saturating_mul(490_000)) // P2 - } - - /// Calculate the weight for `close` without the call to `approve/disapprove_proposal`. - pub(crate) fn close_without_finalize, I: Instance>( - members: Weight, - length: Weight, - ) -> Weight { - T::DbWeight::get().reads(3) // `Members`, `Voting`, `ProposalOf` - .saturating_add(66_000_000) // constant - .saturating_add(length.saturating_mul(8_000)) // B - .saturating_add(members.saturating_mul(250_000)) // M - } -} - /// Return the weight of a dispatch call result as an `Option`. /// /// Will return the weight regardless of what the state of the result is. @@ -385,7 +251,7 @@ decl_module! { /// /// Requires root origin. /// - /// NOTE: Does not enforce the expected `MAX_MEMBERS` limit on the amount of members, but + /// NOTE: Does not enforce the expected `MaxMembers` limit on the amount of members, but /// the weight estimations rely on it to estimate dispatchable weight. /// /// # @@ -401,10 +267,10 @@ decl_module! { /// - 1 storage write (codec `O(1)`) for deleting the old `prime` and setting the new one /// # #[weight = ( - weight_for::set_members::( - (*old_count).into(), // M - new_members.len() as Weight, // N - T::MaxProposals::get().into(), // P + T::WeightInfo::set_members( + *old_count, // M + new_members.len() as u32, // N + T::MaxProposals::get() // P ), DispatchClass::Operational )] @@ -414,10 +280,10 @@ decl_module! { old_count: MemberCount, ) -> DispatchResultWithPostInfo { ensure_root(origin)?; - if new_members.len() > MAX_MEMBERS as usize { + if new_members.len() > T::MaxMembers::get() as usize { debug::error!( "New members count exceeds maximum amount of members expected. (expected: {}, actual: {})", - MAX_MEMBERS, + T::MaxMembers::get(), new_members.len() ); } @@ -435,10 +301,10 @@ decl_module! { >::set_members_sorted(&new_members, &old); Prime::::set(prime); - Ok(Some(weight_for::set_members::( - old.len() as Weight, // M - new_members.len() as Weight, // N - T::MaxProposals::get().into(), // P + Ok(Some(T::WeightInfo::set_members( + old.len() as u32, // M + new_members.len() as u32, // N + T::MaxProposals::get(), // P )).into()) } @@ -453,11 +319,10 @@ decl_module! { /// - 1 event /// # #[weight = ( - weight_for::execute::( - MAX_MEMBERS.into(), - proposal.get_dispatch_info().weight, - *length_bound as Weight, - ), + T::WeightInfo::execute( + *length_bound, // B + T::MaxMembers::get(), // M + ).saturating_add(proposal.get_dispatch_info().weight), // P DispatchClass::Operational )] fn execute(origin, @@ -476,11 +341,12 @@ decl_module! { RawEvent::MemberExecuted(proposal_hash, result.map(|_| ()).map_err(|e| e.error)) ); - Ok(get_result_weight(result).map(|w| weight_for::execute::( - members.len() as Weight, - w, - proposal_len as Weight - )).into()) + Ok(get_result_weight(result).map(|w| { + T::WeightInfo::execute( + proposal_len as u32, // B + members.len() as u32, // M + ).saturating_add(w) // P + }).into()) } /// Add a new proposal to either be voted on or executed directly. @@ -512,16 +378,15 @@ decl_module! { /// # #[weight = ( if *threshold < 2 { - weight_for::propose_execute::( - MAX_MEMBERS.into(), // M - proposal.get_dispatch_info().weight, // P1 - *length_bound as Weight, // B - ) + T::WeightInfo::propose_execute( + *length_bound, // B + T::MaxMembers::get(), // M + ).saturating_add(proposal.get_dispatch_info().weight) // P1 } else { - weight_for::propose_proposed::( - MAX_MEMBERS.into(), // M - T::MaxProposals::get().into(), // P2 - *length_bound as Weight, // B + T::WeightInfo::propose_proposed( + *length_bound, // B + T::MaxMembers::get(), // M + T::MaxProposals::get(), // P2 ) }, DispatchClass::Operational @@ -547,11 +412,12 @@ decl_module! { RawEvent::Executed(proposal_hash, result.map(|_| ()).map_err(|e| e.error)) ); - Ok(get_result_weight(result).map(|w| weight_for::propose_execute::( - members.len() as Weight, // M - w, // P1 - proposal_len as Weight, // B - )).into()) + Ok(get_result_weight(result).map(|w| { + T::WeightInfo::propose_execute( + proposal_len as u32, // B + members.len() as u32, // M + ).saturating_add(w) // P1 + }).into()) } else { let active_proposals = >::try_mutate(|proposals| -> Result { @@ -571,10 +437,10 @@ decl_module! { Self::deposit_event(RawEvent::Proposed(who, index, proposal_hash, threshold)); - Ok(Some(weight_for::propose_proposed::( - members.len() as Weight, // M - active_proposals as Weight, // P2 - proposal_len as Weight, // B + Ok(Some(T::WeightInfo::propose_proposed( + proposal_len as u32, // B + members.len() as u32, // M + active_proposals as u32, // P2 )).into()) } } @@ -592,7 +458,7 @@ decl_module! { /// - 1 event /// # #[weight = ( - weight_for::vote::(MAX_MEMBERS.into()), + T::WeightInfo::vote(T::MaxMembers::get()), DispatchClass::Operational )] fn vote(origin, @@ -636,7 +502,7 @@ decl_module! { Voting::::insert(&proposal, voting); - Ok(Some(weight_for::vote::(members.len() as Weight)).into()) + Ok(Some(T::WeightInfo::vote(members.len() as u32)).into()) } /// Close a vote that is either approved, disapproved or whose voting period has ended. @@ -667,12 +533,17 @@ decl_module! { /// - up to 3 events /// # #[weight = ( - weight_for::close::( - MAX_MEMBERS.into(), // `M` - *proposal_weight_bound, // `P1` - T::MaxProposals::get().into(), // `P2` - *length_bound as Weight, // B - ), + { + let b = *length_bound; + let m = T::MaxMembers::get(); + let p1 = *proposal_weight_bound; + let p2 = T::MaxProposals::get(); + T::WeightInfo::close_early_approved(b, m, p2) + .max(T::WeightInfo::close_early_disapproved(m, p2)) + .max(T::WeightInfo::close_approved(b, m, p2)) + .max(T::WeightInfo::close_disapproved(m, p2)) + .saturating_add(p1) + }, DispatchClass::Operational )] fn close(origin, @@ -699,17 +570,17 @@ decl_module! { proposal_weight_bound )?; Self::deposit_event(RawEvent::Closed(proposal_hash, yes_votes, no_votes)); - let approve_weight = Self::do_approve_proposal(seats, voting, proposal_hash, proposal); + let (proposal_weight, proposal_count) = + Self::do_approve_proposal(seats, voting, proposal_hash, proposal); return Ok(Some( - weight_for::close_without_finalize::(seats.into(), len as Weight) - .saturating_add(approve_weight) + T::WeightInfo::close_early_approved(len as u32, seats, proposal_count) + .saturating_add(proposal_weight) ).into()); } else if disapproved { Self::deposit_event(RawEvent::Closed(proposal_hash, yes_votes, no_votes)); - let disapprove_weight = Self::do_disapprove_proposal(proposal_hash); + let proposal_count = Self::do_disapprove_proposal(proposal_hash); return Ok(Some( - weight_for::close_without_finalize::(seats.into(), 0) - .saturating_add(disapprove_weight) + T::WeightInfo::close_early_disapproved(seats, proposal_count) ).into()); } @@ -733,19 +604,17 @@ decl_module! { proposal_weight_bound )?; Self::deposit_event(RawEvent::Closed(proposal_hash, yes_votes, no_votes)); - let approve_weight = Self::do_approve_proposal(seats, voting, proposal_hash, proposal); + let (proposal_weight, proposal_count) = + Self::do_approve_proposal(seats, voting, proposal_hash, proposal); return Ok(Some( - weight_for::close_without_finalize::(seats.into(), len as Weight) - .saturating_add(T::DbWeight::get().reads(1)) // read `Prime` - .saturating_add(approve_weight) + T::WeightInfo::close_approved(len as u32, seats, proposal_count) + .saturating_add(proposal_weight) ).into()); } else { Self::deposit_event(RawEvent::Closed(proposal_hash, yes_votes, no_votes)); - let disapprove_weight = Self::do_disapprove_proposal(proposal_hash); + let proposal_count = Self::do_disapprove_proposal(proposal_hash); return Ok(Some( - weight_for::close_without_finalize::(seats.into(), 0) - .saturating_add(T::DbWeight::get().reads(1)) // read `Prime` - .saturating_add(disapprove_weight) + T::WeightInfo::close_disapproved(seats, proposal_count) ).into()); } } @@ -759,18 +628,15 @@ decl_module! { /// /// # /// Complexity: O(P) where P is the number of max proposals - /// Base Weight: .49 * P /// DB Weight: /// * Reads: Proposals /// * Writes: Voting, Proposals, ProposalOf /// # - #[weight = T::DbWeight::get().reads_writes(1, 3) // `Voting`, `Proposals`, `ProposalOf` - .saturating_add(490_000 * Weight::from(T::MaxProposals::get())) // P2 - ] + #[weight = T::WeightInfo::disapprove_proposal(T::MaxProposals::get())] fn disapprove_proposal(origin, proposal_hash: T::Hash) -> DispatchResultWithPostInfo { ensure_root(origin)?; - let actual_weight = Self::do_disapprove_proposal(proposal_hash); - Ok(Some(actual_weight).into()) + let proposal_count = Self::do_disapprove_proposal(proposal_hash); + Ok(Some(T::WeightInfo::disapprove_proposal(proposal_count)).into()) } } } @@ -822,8 +688,7 @@ impl, I: Instance> Module { voting: Votes, proposal_hash: T::Hash, proposal: >::Proposal, - ) -> Weight { - let mut weight: Weight = 0; + ) -> (Weight, u32) { Self::deposit_event(RawEvent::Approved(proposal_hash)); let dispatch_weight = proposal.get_dispatch_info().weight; @@ -832,23 +697,21 @@ impl, I: Instance> Module { Self::deposit_event( RawEvent::Executed(proposal_hash, result.map(|_| ()).map_err(|e| e.error)) ); - weight = weight.saturating_add( - // default to the dispatch info weight for safety - get_result_weight(result).unwrap_or(dispatch_weight) // P1 - ); + // default to the dispatch info weight for safety + let proposal_weight = get_result_weight(result).unwrap_or(dispatch_weight); // P1 - let remove_proposal_weight = Self::remove_proposal(proposal_hash); - weight.saturating_add(remove_proposal_weight) + let proposal_count = Self::remove_proposal(proposal_hash); + (proposal_weight, proposal_count) } - fn do_disapprove_proposal(proposal_hash: T::Hash) -> Weight { + fn do_disapprove_proposal(proposal_hash: T::Hash) -> u32 { // disapproved Self::deposit_event(RawEvent::Disapproved(proposal_hash)); Self::remove_proposal(proposal_hash) } // Removes a proposal from the pallet, cleaning up votes and the vector of proposals. - fn remove_proposal(proposal_hash: T::Hash) -> Weight { + fn remove_proposal(proposal_hash: T::Hash) -> u32 { // remove proposal and vote ProposalOf::::remove(&proposal_hash); Voting::::remove(&proposal_hash); @@ -856,15 +719,14 @@ impl, I: Instance> Module { proposals.retain(|h| h != &proposal_hash); proposals.len() + 1 // calculate weight based on original length }); - T::DbWeight::get().reads_writes(1, 3) // `Voting`, `Proposals`, `ProposalOf` - .saturating_add(490_000 * num_proposals as Weight) // P2 + num_proposals as u32 } } impl, I: Instance> ChangeMembers for Module { /// Update the members of the collective. Votes are updated and the prime is reset. /// - /// NOTE: Does not enforce the expected `MAX_MEMBERS` limit on the amount of members, but + /// NOTE: Does not enforce the expected `MaxMembers` limit on the amount of members, but /// the weight estimations rely on it to estimate dispatchable weight. /// /// # @@ -884,10 +746,10 @@ impl, I: Instance> ChangeMembers for Module { outgoing: &[T::AccountId], new: &[T::AccountId], ) { - if new.len() > MAX_MEMBERS as usize { + if new.len() > T::MaxMembers::get() as usize { debug::error!( "New members count exceeds maximum amount of members expected. (expected: {}, actual: {})", - MAX_MEMBERS, + T::MaxMembers::get(), new.len() ); } @@ -1047,6 +909,7 @@ mod tests { pub const AvailableBlockRatio: Perbill = Perbill::one(); pub const MotionDuration: u64 = 3; pub const MaxProposals: u32 = 100; + pub const MaxMembers: u32 = 100; } impl frame_system::Trait for Test { type BaseCallFilter = (); @@ -1081,6 +944,7 @@ mod tests { type Event = Event; type MotionDuration = MotionDuration; type MaxProposals = MaxProposals; + type MaxMembers = MaxMembers; type WeightInfo = (); } impl Trait for Test { @@ -1089,6 +953,7 @@ mod tests { type Event = Event; type MotionDuration = MotionDuration; type MaxProposals = MaxProposals; + type MaxMembers = MaxMembers; type WeightInfo = (); } @@ -1164,7 +1029,7 @@ mod tests { #[test] fn proposal_weight_limit_works_on_approve() { new_test_ext().execute_with(|| { - let proposal = Call::Collective(crate::Call::set_members(vec![1, 2, 3], None, MAX_MEMBERS)); + let proposal = Call::Collective(crate::Call::set_members(vec![1, 2, 3], None, MaxMembers::get())); let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let proposal_weight = proposal.get_dispatch_info().weight; let hash = BlakeTwo256::hash_of(&proposal); @@ -1184,7 +1049,7 @@ mod tests { #[test] fn proposal_weight_limit_ignored_on_disapprove() { new_test_ext().execute_with(|| { - let proposal = Call::Collective(crate::Call::set_members(vec![1, 2, 3], None, MAX_MEMBERS)); + let proposal = Call::Collective(crate::Call::set_members(vec![1, 2, 3], None, MaxMembers::get())); let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let proposal_weight = proposal.get_dispatch_info().weight; let hash = BlakeTwo256::hash_of(&proposal); @@ -1205,7 +1070,7 @@ mod tests { let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let proposal_weight = proposal.get_dispatch_info().weight; let hash = BlakeTwo256::hash_of(&proposal); - assert_ok!(Collective::set_members(Origin::root(), vec![1, 2, 3], Some(3), MAX_MEMBERS)); + assert_ok!(Collective::set_members(Origin::root(), vec![1, 2, 3], Some(3), MaxMembers::get())); assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, true)); @@ -1230,7 +1095,7 @@ mod tests { let proposal_len: u32 = proposal.using_encoded(|p| p.len() as u32); let proposal_weight = proposal.get_dispatch_info().weight; let hash = BlakeTwo256::hash_of(&proposal); - assert_ok!(Collective::set_members(Origin::root(), vec![1, 2, 3], Some(1), MAX_MEMBERS)); + assert_ok!(Collective::set_members(Origin::root(), vec![1, 2, 3], Some(1), MaxMembers::get())); assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), proposal_len)); assert_ok!(Collective::vote(Origin::signed(2), hash.clone(), 0, true)); @@ -1298,7 +1163,7 @@ mod tests { Collective::voting(&hash), Some(Votes { index: 0, threshold: 3, ayes: vec![1, 2], nays: vec![], end }) ); - assert_ok!(Collective::set_members(Origin::root(), vec![2, 3, 4], None, MAX_MEMBERS)); + assert_ok!(Collective::set_members(Origin::root(), vec![2, 3, 4], None, MaxMembers::get())); assert_eq!( Collective::voting(&hash), Some(Votes { index: 0, threshold: 3, ayes: vec![2], nays: vec![], end }) @@ -1313,7 +1178,7 @@ mod tests { Collective::voting(&hash), Some(Votes { index: 1, threshold: 2, ayes: vec![2], nays: vec![3], end }) ); - assert_ok!(Collective::set_members(Origin::root(), vec![2, 4], None, MAX_MEMBERS)); + assert_ok!(Collective::set_members(Origin::root(), vec![2, 4], None, MaxMembers::get())); assert_eq!( Collective::voting(&hash), Some(Votes { index: 1, threshold: 2, ayes: vec![2], nays: vec![], end }) @@ -1371,7 +1236,7 @@ mod tests { #[test] fn correct_validate_and_get_proposal() { new_test_ext().execute_with(|| { - let proposal = Call::Collective(crate::Call::set_members(vec![1, 2, 3], None, MAX_MEMBERS)); + let proposal = Call::Collective(crate::Call::set_members(vec![1, 2, 3], None, MaxMembers::get())); let length = proposal.encode().len() as u32; assert_ok!(Collective::propose(Origin::signed(1), 3, Box::new(proposal.clone()), length));