add generated weight info for pallet-collective (#6789)

* add benchmark for disapprove_proposal

* use generated WeightInfo for pallet-collective weights

* order collective benchmark params alphabetically to get a consistent ordering

* address review comments

* remove default impl of WeightInfo for ()

* remove comments about weight changes

* add default weights

* Apply suggestions from code review

Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>

* whitelist voter account in benchmark

* update weights

* MaxMembers configurable

* remove base weight comment

* add weight to technical collective

* another DB whitelist optimization

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>
This commit is contained in:
Alexander Popiak
2020-08-28 10:46:43 +02:00
committed by GitHub
parent 37d0e00d83
commit ff1e8150e1
6 changed files with 402 additions and 277 deletions
+8 -4
View File
@@ -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<CouncilCollective> 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<TechnicalCollective> 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<
@@ -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;
@@ -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))
}
}
+92 -31
View File
@@ -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::<T, _>::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::<u32>() as u32;
@@ -126,7 +126,7 @@ benchmarks_instance! {
let caller: T::AccountId = whitelisted_caller();
members.push(caller.clone());
Collective::<T, _>::set_members(SystemOrigin::Root.into(), members, None, MAX_MEMBERS)?;
Collective::<T, _>::set_members(SystemOrigin::Root.into(), members, None, T::MaxMembers::get())?;
let proposal: T::Proposal = SystemCall::<T>::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::<u32>() as u32;
@@ -156,7 +156,7 @@ benchmarks_instance! {
let caller: T::AccountId = whitelisted_caller();
members.push(caller.clone());
Collective::<T, _>::set_members(SystemOrigin::Root.into(), members, None, MAX_MEMBERS)?;
Collective::<T, _>::set_members(SystemOrigin::Root.into(), members, None, T::MaxMembers::get())?;
let proposal: T::Proposal = SystemCall::<T>::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::<u32>() as u32;
@@ -186,7 +186,7 @@ benchmarks_instance! {
}
let caller: T::AccountId = whitelisted_caller();
members.push(caller.clone());
Collective::<T, _>::set_members(SystemOrigin::Root.into(), members, None, MAX_MEMBERS)?;
Collective::<T, _>::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::<T, _>::set_members(SystemOrigin::Root.into(), members.clone(), None, MAX_MEMBERS)?;
Collective::<T, _>::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::<T>::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::<u32>() as u32;
let bytes = 100;
let bytes_in_storage = bytes + size_of::<u32>() 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::<T, _>::set_members(SystemOrigin::Root.into(), members.clone(), None, MAX_MEMBERS)?;
Collective::<T, _>::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::<T>::remark(vec![i as u8; b as usize]).into();
let proposal: T::Proposal = SystemCall::<T>::remark(vec![i as u8; bytes as usize]).into();
Collective::<T, _>::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::<T>::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 {
// 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 p in 1 .. T::MaxProposals::get();
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 .. T::MaxMembers::get();
let p in 1 .. T::MaxProposals::get();
let bytes_in_storage = b + size_of::<u32>() as u32;
@@ -379,7 +385,7 @@ benchmarks_instance! {
}
let caller: T::AccountId = whitelisted_caller();
members.push(caller.clone());
Collective::<T, _>::set_members(SystemOrigin::Root.into(), members.clone(), None, MAX_MEMBERS)?;
Collective::<T, _>::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::<u32>() as u32;
let bytes = 100;
let bytes_in_storage = bytes + size_of::<u32>() 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::<T>::remark(vec![i as u8; b as usize]).into();
let proposal: T::Proposal = SystemCall::<T>::remark(vec![i as u8; bytes as usize]).into();
Collective::<T, _>::propose(
SystemOrigin::Signed(caller.clone()).into(),
threshold,
@@ -517,10 +523,10 @@ benchmarks_instance! {
}
close_approved {
// 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 p in 1 .. T::MaxProposals::get();
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 .. T::MaxMembers::get();
let p in 1 .. T::MaxProposals::get();
let bytes_in_storage = b + size_of::<u32>() 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::<T, _>::proposals().len(), (p - 1) as usize);
assert_last_event::<T, I>(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::<u32>() 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::<T, _>::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::<T>::remark(vec![i as u8; b as usize]).into();
Collective::<T, _>::propose(
SystemOrigin::Signed(caller.clone()).into(),
threshold,
Box::new(proposal.clone()),
bytes_in_storage,
)?;
last_hash = T::Hashing::hash_of(&proposal);
}
System::<T>::set_block_number(T::BlockNumber::max_value());
assert_eq!(Collective::<T, _>::proposals().len(), p as usize);
}: _(SystemOrigin::Root, last_hash)
verify {
assert_eq!(Collective::<T, _>::proposals().len(), (p - 1) as usize);
assert_last_event::<T, I>(RawEvent::Disapproved(last_hash).into());
}
}
#[cfg(test)]
@@ -649,4 +703,11 @@ mod tests {
assert_ok!(test_benchmark_close_approved::<Test>());
});
}
#[test]
fn disapprove_proposal() {
new_test_ext().execute_with(|| {
assert_ok!(test_benchmark_disapprove_proposal::<Test>());
});
}
}
@@ -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))
}
}
+107 -242
View File
@@ -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<I: Instance=DefaultInstance>: frame_system::Trait {
@@ -117,7 +101,14 @@ pub trait Trait<I: Instance=DefaultInstance>: frame_system::Trait {
type MotionDuration: Get<Self::BlockNumber>;
/// Maximum number of proposals allowed to be active in parallel.
type MaxProposals: Get<u32>;
type MaxProposals: Get<ProposalIndex>;
/// 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<MemberCount>;
/// 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<T: Trait<I>, 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<T: Trait<I>, 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<T: Trait<I>, 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<T: Trait<I>, 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<T: Trait<I>, 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<T: Trait<I>, I: Instance>(
members: Weight,
proposal_weight: Weight,
proposals: Weight,
length: Weight,
) -> Weight {
let db = T::DbWeight::get();
close_without_finalize::<T, I>(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<T: Trait<I>, 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.
///
/// # <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 = (
weight_for::set_members::<T, I>(
(*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! {
<Self as ChangeMembers<T::AccountId>>::set_members_sorted(&new_members, &old);
Prime::<T, I>::set(prime);
Ok(Some(weight_for::set_members::<T, I>(
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 = (
weight_for::execute::<T, I>(
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::<T, I>(
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>
#[weight = (
if *threshold < 2 {
weight_for::propose_execute::<T, I>(
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::<T, I>(
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::<T, I>(
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 =
<Proposals<T, I>>::try_mutate(|proposals| -> Result<usize, DispatchError> {
@@ -571,10 +437,10 @@ decl_module! {
Self::deposit_event(RawEvent::Proposed(who, index, proposal_hash, threshold));
Ok(Some(weight_for::propose_proposed::<T, I>(
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 = (
weight_for::vote::<T, I>(MAX_MEMBERS.into()),
T::WeightInfo::vote(T::MaxMembers::get()),
DispatchClass::Operational
)]
fn vote(origin,
@@ -636,7 +502,7 @@ decl_module! {
Voting::<T, I>::insert(&proposal, voting);
Ok(Some(weight_for::vote::<T, I>(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 = (
weight_for::close::<T, I>(
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::<T, I>(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::<T, I>(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::<T, I>(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::<T, I>(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! {
///
/// # <weight>
/// Complexity: O(P) where P is the number of max proposals
/// Base Weight: .49 * P
/// DB Weight:
/// * Reads: Proposals
/// * Writes: Voting, Proposals, ProposalOf
/// # </weight>
#[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<T: Trait<I>, I: Instance> Module<T, I> {
voting: Votes<T::AccountId, T::BlockNumber>,
proposal_hash: T::Hash,
proposal: <T as Trait<I>>::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<T: Trait<I>, I: Instance> Module<T, I> {
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::<T, I>::remove(&proposal_hash);
Voting::<T, I>::remove(&proposal_hash);
@@ -856,15 +719,14 @@ impl<T: Trait<I>, I: Instance> Module<T, I> {
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<T: Trait<I>, I: Instance> ChangeMembers<T::AccountId> for Module<T, I> {
/// 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.
///
/// # <weight>
@@ -884,10 +746,10 @@ impl<T: Trait<I>, I: Instance> ChangeMembers<T::AccountId> for Module<T, I> {
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));