mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 20:21:03 +00:00
Bound uses of Call (#11649)
* Introduce preimages module in traits * Multisize Preimages * Len not actually necessary * Tweaks to the preimage API * Fixes * Get Scheduler building with new API * Scheduler tests pass * Bounded Scheduler 🎉 * Use Agenda holes and introduce IncompleteSince to avoid need to reschedule * Tests pass with new weight system * New benchmarks * Add missing file * Drop preimage when permenantly overeight * Drop preimage when permenantly overeight * Referenda uses latest preimage API * Testing ok * Adding tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * fmt Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add preimage migration Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Docs * Remove dbg * Refactor Democracy * Refactor Democracy * Add final MEL * Remove silly maps * Fixes * Minor refactor * Formatting * Fixes * Fixes * Fixes * Update frame/preimage/src/lib.rs Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> * Add migrations to Democracy * WIP Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Resolve conflicts Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Revert "Resolve conflicts" This reverts commit 734d66d69e54553471ffa54fa52e3e304dc8f106. * Undo wrong resolves... Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * WIP Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Make compile Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * massage clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * clippy annoyance Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * clippy annoyance Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix benchmarks Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * add missing file * Test <Preimage as QueryPreimage> Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Clippy harassment Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fixup tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Remove old stuff Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * fmt Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Test <Scheduler as Anon> trait functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update pallet-ui tests Why is this needed? Should not be the case unless master is broken... Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More scheduler trait test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Apply review suggestion Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Beauty fixes Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add Scheduler test migration_v3_to_v4_works Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Merge fixup Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Keep referenda benchmarks instantiatable Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update weights Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use new scheduler weight functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use new democracy weight functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use weight compare functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Update pallet-ui tests Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More renaming… Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * More renaming… Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add comment Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Implement OnRuntimeUpgrade for scheduler::v3_to_v4 migration Put the migration into a proper `MigrateToV4` struct and implement the OnRuntimeUpgrade hooks for it. Also move the test to use that instead. This should make it easier for adding it to Polkadot. Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Clippy Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Handle undecodable Agendas Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Remove trash Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use new OnRuntimeUpgrade functions Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * fix test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix BoundedSlice::truncate_from Co-authored-by: jakoblell Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix pre_upgrade hook return values Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Add more error logging Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Find too large preimages in the pre_upgrade hook Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Test that too large Calls in agendas are ignored Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Use new OnRuntimeUpgrade hooks Why did the CI not catch this?! Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * works fine - just more logs Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix staking migration Causing issues on Kusama... Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix UI tests No idea why this is needed. This is actually undoing an earlier change. Maybe the CI has different rustc versions!? Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Remove multisig's Calls (#12072) * Remove multisig's Calls * Multisig: Fix tests and re-introduce reserve logic (#12241) * Fix tests and re-introduce reserve logic * fix benches * add todo * remove irrelevant bench * [Feature] Add a migration that drains and refunds stored calls (#12313) * [Feature] Add a migration that drains and refunds stored calls * migration fixes * fixes * address review comments * consume the whole block weight * fix assertions * license header * fix interface Co-authored-by: parity-processbot <> Co-authored-by: parity-processbot <> Co-authored-by: Roman Useinov <roman.useinov@gmail.com> * Fix test Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * Fix multisig benchmarks Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> * ".git/.scripts/bench-bot.sh" pallet dev pallet_democracy * ".git/.scripts/bench-bot.sh" pallet dev pallet_scheduler * ".git/.scripts/bench-bot.sh" pallet dev pallet_preimage Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: parity-processbot <> Co-authored-by: Roman Useinov <roman.useinov@gmail.com>
This commit is contained in:
@@ -22,24 +22,16 @@ use super::*;
|
||||
use frame_benchmarking::{account, benchmarks, whitelist_account};
|
||||
use frame_support::{
|
||||
assert_noop, assert_ok,
|
||||
codec::Decode,
|
||||
traits::{
|
||||
schedule::DispatchTime, Currency, EnsureOrigin, Get, OnInitialize, UnfilteredDispatchable,
|
||||
},
|
||||
traits::{Currency, EnsureOrigin, Get, OnInitialize, UnfilteredDispatchable},
|
||||
};
|
||||
use frame_system::{Pallet as System, RawOrigin};
|
||||
use sp_runtime::traits::{BadOrigin, Bounded, One};
|
||||
use frame_system::RawOrigin;
|
||||
use sp_core::H256;
|
||||
use sp_runtime::{traits::Bounded, BoundedVec};
|
||||
|
||||
use crate::Pallet as Democracy;
|
||||
|
||||
const REFERENDUM_COUNT_HINT: u32 = 10;
|
||||
const SEED: u32 = 0;
|
||||
const MAX_REFERENDUMS: u32 = 99;
|
||||
const MAX_SECONDERS: u32 = 100;
|
||||
const MAX_BYTES: u32 = 16_384;
|
||||
|
||||
fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
|
||||
frame_system::Pallet::<T>::assert_last_event(generic_event.into());
|
||||
}
|
||||
|
||||
fn funded_account<T: Config>(name: &'static str, index: u32) -> T::AccountId {
|
||||
let caller: T::AccountId = account(name, index, SEED);
|
||||
@@ -49,37 +41,32 @@ fn funded_account<T: Config>(name: &'static str, index: u32) -> T::AccountId {
|
||||
caller
|
||||
}
|
||||
|
||||
fn add_proposal<T: Config>(n: u32) -> Result<T::Hash, &'static str> {
|
||||
let other = funded_account::<T>("proposer", n);
|
||||
let value = T::MinimumDeposit::get();
|
||||
let proposal_hash: T::Hash = T::Hashing::hash_of(&n);
|
||||
|
||||
Democracy::<T>::propose(RawOrigin::Signed(other).into(), proposal_hash, value)?;
|
||||
|
||||
Ok(proposal_hash)
|
||||
fn make_proposal<T: Config>(n: u32) -> BoundedCallOf<T> {
|
||||
let call: CallOf<T> = frame_system::Call::remark { remark: n.encode() }.into();
|
||||
<T as Config>::Preimages::bound(call).unwrap()
|
||||
}
|
||||
|
||||
fn add_referendum<T: Config>(n: u32) -> Result<ReferendumIndex, &'static str> {
|
||||
let proposal_hash: T::Hash = T::Hashing::hash_of(&n);
|
||||
let vote_threshold = VoteThreshold::SimpleMajority;
|
||||
fn add_proposal<T: Config>(n: u32) -> Result<H256, &'static str> {
|
||||
let other = funded_account::<T>("proposer", n);
|
||||
let value = T::MinimumDeposit::get();
|
||||
let proposal = make_proposal::<T>(n);
|
||||
Democracy::<T>::propose(RawOrigin::Signed(other).into(), proposal.clone(), value)?;
|
||||
Ok(proposal.hash())
|
||||
}
|
||||
|
||||
Democracy::<T>::inject_referendum(
|
||||
T::LaunchPeriod::get(),
|
||||
proposal_hash,
|
||||
vote_threshold,
|
||||
0u32.into(),
|
||||
);
|
||||
let referendum_index: ReferendumIndex = ReferendumCount::<T>::get() - 1;
|
||||
T::Scheduler::schedule_named(
|
||||
(DEMOCRACY_ID, referendum_index).encode(),
|
||||
DispatchTime::At(2u32.into()),
|
||||
None,
|
||||
63,
|
||||
frame_system::RawOrigin::Root.into(),
|
||||
Call::enact_proposal { proposal_hash, index: referendum_index }.into(),
|
||||
fn add_referendum<T: Config>(n: u32) -> (ReferendumIndex, H256) {
|
||||
let vote_threshold = VoteThreshold::SimpleMajority;
|
||||
let proposal = make_proposal::<T>(n);
|
||||
let hash = proposal.hash();
|
||||
(
|
||||
Democracy::<T>::inject_referendum(
|
||||
T::LaunchPeriod::get(),
|
||||
proposal,
|
||||
vote_threshold,
|
||||
0u32.into(),
|
||||
),
|
||||
hash,
|
||||
)
|
||||
.map_err(|_| "failed to schedule named")?;
|
||||
Ok(referendum_index)
|
||||
}
|
||||
|
||||
fn account_vote<T: Config>(b: BalanceOf<T>) -> AccountVote<BalanceOf<T>> {
|
||||
@@ -97,95 +84,90 @@ benchmarks! {
|
||||
}
|
||||
|
||||
let caller = funded_account::<T>("caller", 0);
|
||||
let proposal_hash: T::Hash = T::Hashing::hash_of(&0);
|
||||
let proposal = make_proposal::<T>(0);
|
||||
let value = T::MinimumDeposit::get();
|
||||
whitelist_account!(caller);
|
||||
}: _(RawOrigin::Signed(caller), proposal_hash, value)
|
||||
}: _(RawOrigin::Signed(caller), proposal, value)
|
||||
verify {
|
||||
assert_eq!(Democracy::<T>::public_props().len(), p as usize, "Proposals not created.");
|
||||
}
|
||||
|
||||
second {
|
||||
let s in 0 .. MAX_SECONDERS;
|
||||
|
||||
let caller = funded_account::<T>("caller", 0);
|
||||
let proposal_hash = add_proposal::<T>(s)?;
|
||||
add_proposal::<T>(0)?;
|
||||
|
||||
// Create s existing "seconds"
|
||||
for i in 0 .. s {
|
||||
// we must reserve one deposit for the `proposal` and one for our benchmarked `second` call.
|
||||
for i in 0 .. T::MaxDeposits::get() - 2 {
|
||||
let seconder = funded_account::<T>("seconder", i);
|
||||
Democracy::<T>::second(RawOrigin::Signed(seconder).into(), 0, u32::MAX)?;
|
||||
Democracy::<T>::second(RawOrigin::Signed(seconder).into(), 0)?;
|
||||
}
|
||||
|
||||
let deposits = Democracy::<T>::deposit_of(0).ok_or("Proposal not created")?;
|
||||
assert_eq!(deposits.0.len(), (s + 1) as usize, "Seconds not recorded");
|
||||
assert_eq!(deposits.0.len(), (T::MaxDeposits::get() - 1) as usize, "Seconds not recorded");
|
||||
whitelist_account!(caller);
|
||||
}: _(RawOrigin::Signed(caller), 0, u32::MAX)
|
||||
}: _(RawOrigin::Signed(caller), 0)
|
||||
verify {
|
||||
let deposits = Democracy::<T>::deposit_of(0).ok_or("Proposal not created")?;
|
||||
assert_eq!(deposits.0.len(), (s + 2) as usize, "`second` benchmark did not work");
|
||||
assert_eq!(deposits.0.len(), (T::MaxDeposits::get()) as usize, "`second` benchmark did not work");
|
||||
}
|
||||
|
||||
vote_new {
|
||||
let r in 1 .. MAX_REFERENDUMS;
|
||||
|
||||
let caller = funded_account::<T>("caller", 0);
|
||||
let account_vote = account_vote::<T>(100u32.into());
|
||||
|
||||
// We need to create existing direct votes
|
||||
for i in 0 .. r {
|
||||
let ref_idx = add_referendum::<T>(i)?;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(caller.clone()).into(), ref_idx, account_vote)?;
|
||||
for i in 0 .. T::MaxVotes::get() - 1 {
|
||||
let ref_index = add_referendum::<T>(i).0;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(caller.clone()).into(), ref_index, account_vote)?;
|
||||
}
|
||||
let votes = match VotingOf::<T>::get(&caller) {
|
||||
Voting::Direct { votes, .. } => votes,
|
||||
_ => return Err("Votes are not direct".into()),
|
||||
};
|
||||
assert_eq!(votes.len(), r as usize, "Votes were not recorded.");
|
||||
assert_eq!(votes.len(), (T::MaxVotes::get() - 1) as usize, "Votes were not recorded.");
|
||||
|
||||
let referendum_index = add_referendum::<T>(r)?;
|
||||
let ref_index = add_referendum::<T>(T::MaxVotes::get() - 1).0;
|
||||
whitelist_account!(caller);
|
||||
}: vote(RawOrigin::Signed(caller.clone()), referendum_index, account_vote)
|
||||
}: vote(RawOrigin::Signed(caller.clone()), ref_index, account_vote)
|
||||
verify {
|
||||
let votes = match VotingOf::<T>::get(&caller) {
|
||||
Voting::Direct { votes, .. } => votes,
|
||||
_ => return Err("Votes are not direct".into()),
|
||||
};
|
||||
assert_eq!(votes.len(), (r + 1) as usize, "Vote was not recorded.");
|
||||
assert_eq!(votes.len(), T::MaxVotes::get() as usize, "Vote was not recorded.");
|
||||
}
|
||||
|
||||
vote_existing {
|
||||
let r in 1 .. MAX_REFERENDUMS;
|
||||
|
||||
let caller = funded_account::<T>("caller", 0);
|
||||
let account_vote = account_vote::<T>(100u32.into());
|
||||
|
||||
// We need to create existing direct votes
|
||||
for i in 0 ..=r {
|
||||
let ref_idx = add_referendum::<T>(i)?;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(caller.clone()).into(), ref_idx, account_vote)?;
|
||||
for i in 0..T::MaxVotes::get() {
|
||||
let ref_index = add_referendum::<T>(i).0;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(caller.clone()).into(), ref_index, account_vote)?;
|
||||
}
|
||||
let votes = match VotingOf::<T>::get(&caller) {
|
||||
Voting::Direct { votes, .. } => votes,
|
||||
_ => return Err("Votes are not direct".into()),
|
||||
};
|
||||
assert_eq!(votes.len(), (r + 1) as usize, "Votes were not recorded.");
|
||||
assert_eq!(votes.len(), T::MaxVotes::get() as usize, "Votes were not recorded.");
|
||||
|
||||
// Change vote from aye to nay
|
||||
let nay = Vote { aye: false, conviction: Conviction::Locked1x };
|
||||
let new_vote = AccountVote::Standard { vote: nay, balance: 1000u32.into() };
|
||||
let referendum_index = Democracy::<T>::referendum_count() - 1;
|
||||
let ref_index = Democracy::<T>::referendum_count() - 1;
|
||||
|
||||
// This tests when a user changes a vote
|
||||
whitelist_account!(caller);
|
||||
}: vote(RawOrigin::Signed(caller.clone()), referendum_index, new_vote)
|
||||
}: vote(RawOrigin::Signed(caller.clone()), ref_index, new_vote)
|
||||
verify {
|
||||
let votes = match VotingOf::<T>::get(&caller) {
|
||||
Voting::Direct { votes, .. } => votes,
|
||||
_ => return Err("Votes are not direct".into()),
|
||||
};
|
||||
assert_eq!(votes.len(), (r + 1) as usize, "Vote was incorrectly added");
|
||||
let referendum_info = Democracy::<T>::referendum_info(referendum_index)
|
||||
assert_eq!(votes.len(), T::MaxVotes::get() as usize, "Vote was incorrectly added");
|
||||
let referendum_info = Democracy::<T>::referendum_info(ref_index)
|
||||
.ok_or("referendum doesn't exist")?;
|
||||
let tally = match referendum_info {
|
||||
ReferendumInfo::Ongoing(r) => r.tally,
|
||||
@@ -196,61 +178,55 @@ benchmarks! {
|
||||
|
||||
emergency_cancel {
|
||||
let origin = T::CancellationOrigin::successful_origin();
|
||||
let referendum_index = add_referendum::<T>(0)?;
|
||||
assert_ok!(Democracy::<T>::referendum_status(referendum_index));
|
||||
}: _<T::RuntimeOrigin>(origin, referendum_index)
|
||||
let ref_index = add_referendum::<T>(0).0;
|
||||
assert_ok!(Democracy::<T>::referendum_status(ref_index));
|
||||
}: _<T::RuntimeOrigin>(origin, ref_index)
|
||||
verify {
|
||||
// Referendum has been canceled
|
||||
assert_noop!(
|
||||
Democracy::<T>::referendum_status(referendum_index),
|
||||
Democracy::<T>::referendum_status(ref_index),
|
||||
Error::<T>::ReferendumInvalid,
|
||||
);
|
||||
}
|
||||
|
||||
blacklist {
|
||||
let p in 1 .. T::MaxProposals::get();
|
||||
|
||||
// Place our proposal at the end to make sure it's worst case.
|
||||
for i in 0 .. p - 1 {
|
||||
for i in 0 .. T::MaxProposals::get() - 1 {
|
||||
add_proposal::<T>(i)?;
|
||||
}
|
||||
// We should really add a lot of seconds here, but we're not doing it elsewhere.
|
||||
|
||||
// Add a referendum of our proposal.
|
||||
let (ref_index, hash) = add_referendum::<T>(0);
|
||||
assert_ok!(Democracy::<T>::referendum_status(ref_index));
|
||||
// Place our proposal in the external queue, too.
|
||||
let hash = T::Hashing::hash_of(&0);
|
||||
assert_ok!(
|
||||
Democracy::<T>::external_propose(T::ExternalOrigin::successful_origin(), hash)
|
||||
Democracy::<T>::external_propose(T::ExternalOrigin::successful_origin(), make_proposal::<T>(0))
|
||||
);
|
||||
let origin = T::BlacklistOrigin::successful_origin();
|
||||
// Add a referendum of our proposal.
|
||||
let referendum_index = add_referendum::<T>(0)?;
|
||||
assert_ok!(Democracy::<T>::referendum_status(referendum_index));
|
||||
}: _<T::RuntimeOrigin>(origin, hash, Some(referendum_index))
|
||||
}: _<T::RuntimeOrigin>(origin, hash, Some(ref_index))
|
||||
verify {
|
||||
// Referendum has been canceled
|
||||
assert_noop!(
|
||||
Democracy::<T>::referendum_status(referendum_index),
|
||||
Democracy::<T>::referendum_status(ref_index),
|
||||
Error::<T>::ReferendumInvalid
|
||||
);
|
||||
}
|
||||
|
||||
// Worst case scenario, we external propose a previously blacklisted proposal
|
||||
external_propose {
|
||||
let v in 1 .. MAX_VETOERS as u32;
|
||||
|
||||
let origin = T::ExternalOrigin::successful_origin();
|
||||
let proposal_hash = T::Hashing::hash_of(&0);
|
||||
let proposal = make_proposal::<T>(0);
|
||||
// Add proposal to blacklist with block number 0
|
||||
|
||||
let addresses = (0..v)
|
||||
let addresses: BoundedVec<_, _> = (0..(T::MaxBlacklisted::get() - 1))
|
||||
.into_iter()
|
||||
.map(|i| account::<T::AccountId>("blacklist", i, SEED))
|
||||
.collect::<Vec<_>>();
|
||||
Blacklist::<T>::insert(
|
||||
proposal_hash,
|
||||
(T::BlockNumber::zero(), addresses),
|
||||
);
|
||||
}: _<T::RuntimeOrigin>(origin, proposal_hash)
|
||||
.collect::<Vec<_>>()
|
||||
.try_into()
|
||||
.unwrap();
|
||||
Blacklist::<T>::insert(proposal.hash(), (T::BlockNumber::zero(), addresses));
|
||||
}: _<T::RuntimeOrigin>(origin, proposal)
|
||||
verify {
|
||||
// External proposal created
|
||||
ensure!(<NextExternal<T>>::exists(), "External proposal didn't work");
|
||||
@@ -258,8 +234,8 @@ benchmarks! {
|
||||
|
||||
external_propose_majority {
|
||||
let origin = T::ExternalMajorityOrigin::successful_origin();
|
||||
let proposal_hash = T::Hashing::hash_of(&0);
|
||||
}: _<T::RuntimeOrigin>(origin, proposal_hash)
|
||||
let proposal = make_proposal::<T>(0);
|
||||
}: _<T::RuntimeOrigin>(origin, proposal)
|
||||
verify {
|
||||
// External proposal created
|
||||
ensure!(<NextExternal<T>>::exists(), "External proposal didn't work");
|
||||
@@ -267,8 +243,8 @@ benchmarks! {
|
||||
|
||||
external_propose_default {
|
||||
let origin = T::ExternalDefaultOrigin::successful_origin();
|
||||
let proposal_hash = T::Hashing::hash_of(&0);
|
||||
}: _<T::RuntimeOrigin>(origin, proposal_hash)
|
||||
let proposal = make_proposal::<T>(0);
|
||||
}: _<T::RuntimeOrigin>(origin, proposal)
|
||||
verify {
|
||||
// External proposal created
|
||||
ensure!(<NextExternal<T>>::exists(), "External proposal didn't work");
|
||||
@@ -276,8 +252,9 @@ benchmarks! {
|
||||
|
||||
fast_track {
|
||||
let origin_propose = T::ExternalDefaultOrigin::successful_origin();
|
||||
let proposal_hash: T::Hash = T::Hashing::hash_of(&0);
|
||||
Democracy::<T>::external_propose_default(origin_propose, proposal_hash)?;
|
||||
let proposal = make_proposal::<T>(0);
|
||||
let proposal_hash = proposal.hash();
|
||||
Democracy::<T>::external_propose_default(origin_propose, proposal)?;
|
||||
|
||||
// NOTE: Instant origin may invoke a little bit more logic, but may not always succeed.
|
||||
let origin_fast_track = T::FastTrackOrigin::successful_origin();
|
||||
@@ -289,17 +266,15 @@ benchmarks! {
|
||||
}
|
||||
|
||||
veto_external {
|
||||
// Existing veto-ers
|
||||
let v in 0 .. MAX_VETOERS as u32;
|
||||
|
||||
let proposal_hash: T::Hash = T::Hashing::hash_of(&v);
|
||||
let proposal = make_proposal::<T>(0);
|
||||
let proposal_hash = proposal.hash();
|
||||
|
||||
let origin_propose = T::ExternalDefaultOrigin::successful_origin();
|
||||
Democracy::<T>::external_propose_default(origin_propose, proposal_hash)?;
|
||||
Democracy::<T>::external_propose_default(origin_propose, proposal)?;
|
||||
|
||||
let mut vetoers: Vec<T::AccountId> = Vec::new();
|
||||
for i in 0 .. v {
|
||||
vetoers.push(account::<T::AccountId>("vetoer", i, SEED));
|
||||
let mut vetoers: BoundedVec<T::AccountId, _> = Default::default();
|
||||
for i in 0 .. (T::MaxBlacklisted::get() - 1) {
|
||||
vetoers.try_push(account::<T::AccountId>("vetoer", i, SEED)).unwrap();
|
||||
}
|
||||
vetoers.sort();
|
||||
Blacklist::<T>::insert(proposal_hash, (T::BlockNumber::zero(), vetoers));
|
||||
@@ -310,42 +285,27 @@ benchmarks! {
|
||||
verify {
|
||||
assert!(NextExternal::<T>::get().is_none());
|
||||
let (_, new_vetoers) = <Blacklist<T>>::get(&proposal_hash).ok_or("no blacklist")?;
|
||||
assert_eq!(new_vetoers.len(), (v + 1) as usize, "vetoers not added");
|
||||
assert_eq!(new_vetoers.len(), T::MaxBlacklisted::get() as usize, "vetoers not added");
|
||||
}
|
||||
|
||||
cancel_proposal {
|
||||
let p in 1 .. T::MaxProposals::get();
|
||||
|
||||
// Place our proposal at the end to make sure it's worst case.
|
||||
for i in 0 .. p {
|
||||
for i in 0 .. T::MaxProposals::get() {
|
||||
add_proposal::<T>(i)?;
|
||||
}
|
||||
|
||||
let cancel_origin = T::CancelProposalOrigin::successful_origin();
|
||||
}: _<T::RuntimeOrigin>(cancel_origin, 0)
|
||||
|
||||
cancel_referendum {
|
||||
let referendum_index = add_referendum::<T>(0)?;
|
||||
}: _(RawOrigin::Root, referendum_index)
|
||||
let ref_index = add_referendum::<T>(0).0;
|
||||
}: _(RawOrigin::Root, ref_index)
|
||||
|
||||
cancel_queued {
|
||||
let r in 1 .. MAX_REFERENDUMS;
|
||||
|
||||
for i in 0..r {
|
||||
add_referendum::<T>(i)?; // This add one element in the scheduler
|
||||
}
|
||||
|
||||
let referendum_index = add_referendum::<T>(r)?;
|
||||
}: _(RawOrigin::Root, referendum_index)
|
||||
|
||||
// This measures the path of `launch_next` external. Not currently used as we simply
|
||||
// assume the weight is `MaxBlockWeight` when executing.
|
||||
#[extra]
|
||||
on_initialize_external {
|
||||
let r in 0 .. MAX_REFERENDUMS;
|
||||
let r in 0 .. REFERENDUM_COUNT_HINT;
|
||||
|
||||
for i in 0..r {
|
||||
add_referendum::<T>(i)?;
|
||||
add_referendum::<T>(i);
|
||||
}
|
||||
|
||||
assert_eq!(Democracy::<T>::referendum_count(), r, "referenda not created");
|
||||
@@ -354,8 +314,8 @@ benchmarks! {
|
||||
LastTabledWasExternal::<T>::put(false);
|
||||
|
||||
let origin = T::ExternalMajorityOrigin::successful_origin();
|
||||
let proposal_hash = T::Hashing::hash_of(&r);
|
||||
let call = Call::<T>::external_propose_majority { proposal_hash };
|
||||
let proposal = make_proposal::<T>(r);
|
||||
let call = Call::<T>::external_propose_majority { proposal };
|
||||
call.dispatch_bypass_filter(origin)?;
|
||||
// External proposal created
|
||||
ensure!(<NextExternal<T>>::exists(), "External proposal didn't work");
|
||||
@@ -379,14 +339,12 @@ benchmarks! {
|
||||
}
|
||||
}
|
||||
|
||||
// This measures the path of `launch_next` public. Not currently used as we simply
|
||||
// assume the weight is `MaxBlockWeight` when executing.
|
||||
#[extra]
|
||||
on_initialize_public {
|
||||
let r in 1 .. MAX_REFERENDUMS;
|
||||
let r in 0 .. (T::MaxVotes::get() - 1);
|
||||
|
||||
for i in 0..r {
|
||||
add_referendum::<T>(i)?;
|
||||
add_referendum::<T>(i);
|
||||
}
|
||||
|
||||
assert_eq!(Democracy::<T>::referendum_count(), r, "referenda not created");
|
||||
@@ -415,10 +373,10 @@ benchmarks! {
|
||||
|
||||
// No launch no maturing referenda.
|
||||
on_initialize_base {
|
||||
let r in 1 .. MAX_REFERENDUMS;
|
||||
let r in 0 .. (T::MaxVotes::get() - 1);
|
||||
|
||||
for i in 0..r {
|
||||
add_referendum::<T>(i)?;
|
||||
add_referendum::<T>(i);
|
||||
}
|
||||
|
||||
for (key, mut info) in ReferendumInfoOf::<T>::iter() {
|
||||
@@ -445,10 +403,10 @@ benchmarks! {
|
||||
}
|
||||
|
||||
on_initialize_base_with_launch_period {
|
||||
let r in 1 .. MAX_REFERENDUMS;
|
||||
let r in 0 .. (T::MaxVotes::get() - 1);
|
||||
|
||||
for i in 0..r {
|
||||
add_referendum::<T>(i)?;
|
||||
add_referendum::<T>(i);
|
||||
}
|
||||
|
||||
for (key, mut info) in ReferendumInfoOf::<T>::iter() {
|
||||
@@ -477,7 +435,7 @@ benchmarks! {
|
||||
}
|
||||
|
||||
delegate {
|
||||
let r in 1 .. MAX_REFERENDUMS;
|
||||
let r in 0 .. (T::MaxVotes::get() - 1);
|
||||
|
||||
let initial_balance: BalanceOf<T> = 100u32.into();
|
||||
let delegated_balance: BalanceOf<T> = 1000u32.into();
|
||||
@@ -504,8 +462,8 @@ benchmarks! {
|
||||
let account_vote = account_vote::<T>(initial_balance);
|
||||
// We need to create existing direct votes for the `new_delegate`
|
||||
for i in 0..r {
|
||||
let ref_idx = add_referendum::<T>(i)?;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(new_delegate.clone()).into(), ref_idx, account_vote)?;
|
||||
let ref_index = add_referendum::<T>(i).0;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(new_delegate.clone()).into(), ref_index, account_vote)?;
|
||||
}
|
||||
let votes = match VotingOf::<T>::get(&new_delegate) {
|
||||
Voting::Direct { votes, .. } => votes,
|
||||
@@ -529,7 +487,7 @@ benchmarks! {
|
||||
}
|
||||
|
||||
undelegate {
|
||||
let r in 1 .. MAX_REFERENDUMS;
|
||||
let r in 0 .. (T::MaxVotes::get() - 1);
|
||||
|
||||
let initial_balance: BalanceOf<T> = 100u32.into();
|
||||
let delegated_balance: BalanceOf<T> = 1000u32.into();
|
||||
@@ -553,10 +511,10 @@ benchmarks! {
|
||||
// We need to create votes direct votes for the `delegate`
|
||||
let account_vote = account_vote::<T>(initial_balance);
|
||||
for i in 0..r {
|
||||
let ref_idx = add_referendum::<T>(i)?;
|
||||
let ref_index = add_referendum::<T>(i).0;
|
||||
Democracy::<T>::vote(
|
||||
RawOrigin::Signed(the_delegate.clone()).into(),
|
||||
ref_idx,
|
||||
ref_index,
|
||||
account_vote
|
||||
)?;
|
||||
}
|
||||
@@ -580,71 +538,9 @@ benchmarks! {
|
||||
|
||||
}: _(RawOrigin::Root)
|
||||
|
||||
note_preimage {
|
||||
// Num of bytes in encoded proposal
|
||||
let b in 0 .. MAX_BYTES;
|
||||
|
||||
let caller = funded_account::<T>("caller", 0);
|
||||
let encoded_proposal = vec![1; b as usize];
|
||||
whitelist_account!(caller);
|
||||
}: _(RawOrigin::Signed(caller), encoded_proposal.clone())
|
||||
verify {
|
||||
let proposal_hash = T::Hashing::hash(&encoded_proposal[..]);
|
||||
match Preimages::<T>::get(proposal_hash) {
|
||||
Some(PreimageStatus::Available { .. }) => (),
|
||||
_ => return Err("preimage not available".into())
|
||||
}
|
||||
}
|
||||
|
||||
note_imminent_preimage {
|
||||
// Num of bytes in encoded proposal
|
||||
let b in 0 .. MAX_BYTES;
|
||||
|
||||
// d + 1 to include the one we are testing
|
||||
let encoded_proposal = vec![1; b as usize];
|
||||
let proposal_hash = T::Hashing::hash(&encoded_proposal[..]);
|
||||
let block_number = T::BlockNumber::one();
|
||||
Preimages::<T>::insert(&proposal_hash, PreimageStatus::Missing(block_number));
|
||||
|
||||
let caller = funded_account::<T>("caller", 0);
|
||||
let encoded_proposal = vec![1; b as usize];
|
||||
whitelist_account!(caller);
|
||||
}: _(RawOrigin::Signed(caller), encoded_proposal.clone())
|
||||
verify {
|
||||
let proposal_hash = T::Hashing::hash(&encoded_proposal[..]);
|
||||
match Preimages::<T>::get(proposal_hash) {
|
||||
Some(PreimageStatus::Available { .. }) => (),
|
||||
_ => return Err("preimage not available".into())
|
||||
}
|
||||
}
|
||||
|
||||
reap_preimage {
|
||||
// Num of bytes in encoded proposal
|
||||
let b in 0 .. MAX_BYTES;
|
||||
|
||||
let encoded_proposal = vec![1; b as usize];
|
||||
let proposal_hash = T::Hashing::hash(&encoded_proposal[..]);
|
||||
|
||||
let submitter = funded_account::<T>("submitter", b);
|
||||
Democracy::<T>::note_preimage(RawOrigin::Signed(submitter).into(), encoded_proposal.clone())?;
|
||||
|
||||
// We need to set this otherwise we get `Early` error.
|
||||
let block_number = T::VotingPeriod::get() + T::EnactmentPeriod::get() + T::BlockNumber::one();
|
||||
System::<T>::set_block_number(block_number);
|
||||
|
||||
assert!(Preimages::<T>::contains_key(proposal_hash));
|
||||
|
||||
let caller = funded_account::<T>("caller", 0);
|
||||
whitelist_account!(caller);
|
||||
}: _(RawOrigin::Signed(caller), proposal_hash, u32::MAX)
|
||||
verify {
|
||||
let proposal_hash = T::Hashing::hash(&encoded_proposal[..]);
|
||||
assert!(!Preimages::<T>::contains_key(proposal_hash));
|
||||
}
|
||||
|
||||
// Test when unlock will remove locks
|
||||
unlock_remove {
|
||||
let r in 1 .. MAX_REFERENDUMS;
|
||||
let r in 0 .. (T::MaxVotes::get() - 1);
|
||||
|
||||
let locker = funded_account::<T>("locker", 0);
|
||||
let locker_lookup = T::Lookup::unlookup(locker.clone());
|
||||
@@ -653,9 +549,9 @@ benchmarks! {
|
||||
let small_vote = account_vote::<T>(base_balance);
|
||||
// Vote and immediately unvote
|
||||
for i in 0 .. r {
|
||||
let ref_idx = add_referendum::<T>(i)?;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(locker.clone()).into(), ref_idx, small_vote)?;
|
||||
Democracy::<T>::remove_vote(RawOrigin::Signed(locker.clone()).into(), ref_idx)?;
|
||||
let ref_index = add_referendum::<T>(i).0;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(locker.clone()).into(), ref_index, small_vote)?;
|
||||
Democracy::<T>::remove_vote(RawOrigin::Signed(locker.clone()).into(), ref_index)?;
|
||||
}
|
||||
|
||||
let caller = funded_account::<T>("caller", 0);
|
||||
@@ -669,7 +565,7 @@ benchmarks! {
|
||||
|
||||
// Test when unlock will set a new value
|
||||
unlock_set {
|
||||
let r in 1 .. MAX_REFERENDUMS;
|
||||
let r in 0 .. (T::MaxVotes::get() - 1);
|
||||
|
||||
let locker = funded_account::<T>("locker", 0);
|
||||
let locker_lookup = T::Lookup::unlookup(locker.clone());
|
||||
@@ -677,14 +573,14 @@ benchmarks! {
|
||||
let base_balance: BalanceOf<T> = 100u32.into();
|
||||
let small_vote = account_vote::<T>(base_balance);
|
||||
for i in 0 .. r {
|
||||
let ref_idx = add_referendum::<T>(i)?;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(locker.clone()).into(), ref_idx, small_vote)?;
|
||||
let ref_index = add_referendum::<T>(i).0;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(locker.clone()).into(), ref_index, small_vote)?;
|
||||
}
|
||||
|
||||
// Create a big vote so lock increases
|
||||
let big_vote = account_vote::<T>(base_balance * 10u32.into());
|
||||
let referendum_index = add_referendum::<T>(r)?;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(locker.clone()).into(), referendum_index, big_vote)?;
|
||||
let ref_index = add_referendum::<T>(r).0;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(locker.clone()).into(), ref_index, big_vote)?;
|
||||
|
||||
let votes = match VotingOf::<T>::get(&locker) {
|
||||
Voting::Direct { votes, .. } => votes,
|
||||
@@ -695,7 +591,7 @@ benchmarks! {
|
||||
let voting = VotingOf::<T>::get(&locker);
|
||||
assert_eq!(voting.locked_balance(), base_balance * 10u32.into());
|
||||
|
||||
Democracy::<T>::remove_vote(RawOrigin::Signed(locker.clone()).into(), referendum_index)?;
|
||||
Democracy::<T>::remove_vote(RawOrigin::Signed(locker.clone()).into(), ref_index)?;
|
||||
|
||||
let caller = funded_account::<T>("caller", 0);
|
||||
whitelist_account!(caller);
|
||||
@@ -709,18 +605,18 @@ benchmarks! {
|
||||
|
||||
let voting = VotingOf::<T>::get(&locker);
|
||||
// Note that we may want to add a `get_lock` api to actually verify
|
||||
assert_eq!(voting.locked_balance(), base_balance);
|
||||
assert_eq!(voting.locked_balance(), if r > 0 { base_balance } else { 0u32.into() });
|
||||
}
|
||||
|
||||
remove_vote {
|
||||
let r in 1 .. MAX_REFERENDUMS;
|
||||
let r in 1 .. T::MaxVotes::get();
|
||||
|
||||
let caller = funded_account::<T>("caller", 0);
|
||||
let account_vote = account_vote::<T>(100u32.into());
|
||||
|
||||
for i in 0 .. r {
|
||||
let ref_idx = add_referendum::<T>(i)?;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(caller.clone()).into(), ref_idx, account_vote)?;
|
||||
let ref_index = add_referendum::<T>(i).0;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(caller.clone()).into(), ref_index, account_vote)?;
|
||||
}
|
||||
|
||||
let votes = match VotingOf::<T>::get(&caller) {
|
||||
@@ -729,9 +625,9 @@ benchmarks! {
|
||||
};
|
||||
assert_eq!(votes.len(), r as usize, "Votes not created");
|
||||
|
||||
let referendum_index = r - 1;
|
||||
let ref_index = r - 1;
|
||||
whitelist_account!(caller);
|
||||
}: _(RawOrigin::Signed(caller.clone()), referendum_index)
|
||||
}: _(RawOrigin::Signed(caller.clone()), ref_index)
|
||||
verify {
|
||||
let votes = match VotingOf::<T>::get(&caller) {
|
||||
Voting::Direct { votes, .. } => votes,
|
||||
@@ -742,15 +638,15 @@ benchmarks! {
|
||||
|
||||
// Worst case is when target == caller and referendum is ongoing
|
||||
remove_other_vote {
|
||||
let r in 1 .. MAX_REFERENDUMS;
|
||||
let r in 1 .. T::MaxVotes::get();
|
||||
|
||||
let caller = funded_account::<T>("caller", r);
|
||||
let caller_lookup = T::Lookup::unlookup(caller.clone());
|
||||
let account_vote = account_vote::<T>(100u32.into());
|
||||
|
||||
for i in 0 .. r {
|
||||
let ref_idx = add_referendum::<T>(i)?;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(caller.clone()).into(), ref_idx, account_vote)?;
|
||||
let ref_index = add_referendum::<T>(i).0;
|
||||
Democracy::<T>::vote(RawOrigin::Signed(caller.clone()).into(), ref_index, account_vote)?;
|
||||
}
|
||||
|
||||
let votes = match VotingOf::<T>::get(&caller) {
|
||||
@@ -759,9 +655,9 @@ benchmarks! {
|
||||
};
|
||||
assert_eq!(votes.len(), r as usize, "Votes not created");
|
||||
|
||||
let referendum_index = r - 1;
|
||||
let ref_index = r - 1;
|
||||
whitelist_account!(caller);
|
||||
}: _(RawOrigin::Signed(caller.clone()), caller_lookup, referendum_index)
|
||||
}: _(RawOrigin::Signed(caller.clone()), caller_lookup, ref_index)
|
||||
verify {
|
||||
let votes = match VotingOf::<T>::get(&caller) {
|
||||
Voting::Direct { votes, .. } => votes,
|
||||
@@ -770,54 +666,6 @@ benchmarks! {
|
||||
assert_eq!(votes.len(), (r - 1) as usize, "Vote was not removed");
|
||||
}
|
||||
|
||||
#[extra]
|
||||
enact_proposal_execute {
|
||||
// Num of bytes in encoded proposal
|
||||
let b in 0 .. MAX_BYTES;
|
||||
|
||||
let proposer = funded_account::<T>("proposer", 0);
|
||||
let raw_call = Call::note_preimage { encoded_proposal: vec![1; b as usize] };
|
||||
let generic_call: T::Proposal = raw_call.into();
|
||||
let encoded_proposal = generic_call.encode();
|
||||
let proposal_hash = T::Hashing::hash(&encoded_proposal[..]);
|
||||
Democracy::<T>::note_preimage(RawOrigin::Signed(proposer).into(), encoded_proposal)?;
|
||||
|
||||
match Preimages::<T>::get(proposal_hash) {
|
||||
Some(PreimageStatus::Available { .. }) => (),
|
||||
_ => return Err("preimage not available".into())
|
||||
}
|
||||
}: enact_proposal(RawOrigin::Root, proposal_hash, 0)
|
||||
verify {
|
||||
// Fails due to mismatched origin
|
||||
assert_last_event::<T>(Event::<T>::Executed { ref_index: 0, result: Err(BadOrigin.into()) }.into());
|
||||
}
|
||||
|
||||
#[extra]
|
||||
enact_proposal_slash {
|
||||
// Num of bytes in encoded proposal
|
||||
let b in 0 .. MAX_BYTES;
|
||||
|
||||
let proposer = funded_account::<T>("proposer", 0);
|
||||
// Random invalid bytes
|
||||
let encoded_proposal = vec![200; b as usize];
|
||||
let proposal_hash = T::Hashing::hash(&encoded_proposal[..]);
|
||||
Democracy::<T>::note_preimage(RawOrigin::Signed(proposer).into(), encoded_proposal)?;
|
||||
|
||||
match Preimages::<T>::get(proposal_hash) {
|
||||
Some(PreimageStatus::Available { .. }) => (),
|
||||
_ => return Err("preimage not available".into())
|
||||
}
|
||||
let origin = RawOrigin::Root.into();
|
||||
let call = Call::<T>::enact_proposal { proposal_hash, index: 0 }.encode();
|
||||
}: {
|
||||
assert_eq!(
|
||||
<Call<T> as Decode>::decode(&mut &*call)
|
||||
.expect("call is encoded above, encoding must be correct")
|
||||
.dispatch_bypass_filter(origin),
|
||||
Err(Error::<T>::PreimageInvalid.into())
|
||||
);
|
||||
}
|
||||
|
||||
impl_benchmark_test_suite!(
|
||||
Democracy,
|
||||
crate::tests::new_test_ext(),
|
||||
|
||||
Reference in New Issue
Block a user