mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 15:21:08 +00:00
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:
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user