Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Referendum proposal's metadata (#12568)
Browse files Browse the repository at this point in the history
* referenda metadata

* todo comment

* remove TODO, update rustdocs

* referenda clear_metadata origin signed or root

* referenda metadata unit tests

* drop schema type for referenda metadata

* remove metadata type

* referenda metadata benches

* note different preimages

* metadata for democracy pallet

* metadata democracy pallet tests and benches

* fix cargo clippy

* update docs

* ".git/.scripts/bench-bot.sh" pallet dev pallet_democracy

* ".git/.scripts/bench-bot.sh" pallet dev pallet_referenda

* Update the doc frame/democracy/src/lib.rs

Co-authored-by: Roman Useinov <roman.useinov@gmail.com>

* Update the doc frame/democracy/src/lib.rs

Co-authored-by: Anthony Alaribe <anthonyalaribe@gmail.com>

* reference instead clone for take

Co-authored-by: Anthony Alaribe <anthonyalaribe@gmail.com>

* error rename BadMetadata to PreimageNotExist

* clear metadata within internal_cancel_referendum fn

* remove redundant clone

* collapse metadata api into one set_metadata method

* fmt

* review fixes

* not request preimage on set_metadata

* rename events and update docs

* ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_democracy

* ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_referenda

* rename reset_metadata to transfer_metadata

---------

Co-authored-by: command-bot <>
Co-authored-by: Roman Useinov <roman.useinov@gmail.com>
Co-authored-by: Anthony Alaribe <anthonyalaribe@gmail.com>
  • Loading branch information
3 people authored Feb 8, 2023
1 parent 38c3e5e commit 2f16448
Show file tree
Hide file tree
Showing 13 changed files with 1,367 additions and 350 deletions.
203 changes: 186 additions & 17 deletions frame/democracy/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,20 @@ fn add_proposal<T: Config>(n: u32) -> Result<H256, &'static str> {
Ok(proposal.hash())
}

fn add_referendum<T: Config>(n: u32) -> (ReferendumIndex, H256) {
// add a referendum with a metadata.
fn add_referendum<T: Config>(n: u32) -> (ReferendumIndex, H256, PreimageHash) {
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,
)
let index = Democracy::<T>::inject_referendum(
T::LaunchPeriod::get(),
proposal,
vote_threshold,
0u32.into(),
);
let preimage_hash = note_preimage::<T>();
MetadataOf::<T>::insert(crate::MetadataOwner::Referendum(index), preimage_hash.clone());
(index, hash, preimage_hash)
}

fn account_vote<T: Config>(b: BalanceOf<T>) -> AccountVote<BalanceOf<T>> {
Expand All @@ -75,6 +76,25 @@ fn account_vote<T: Config>(b: BalanceOf<T>) -> AccountVote<BalanceOf<T>> {
AccountVote::Standard { vote: v, balance: b }
}

fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
frame_system::Pallet::<T>::assert_last_event(generic_event.into());
}

fn assert_has_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
frame_system::Pallet::<T>::assert_has_event(generic_event.into());
}

// note a new preimage.
fn note_preimage<T: Config>() -> PreimageHash {
use core::sync::atomic::{AtomicU8, Ordering};
use sp_std::borrow::Cow;
// note a new preimage on every function invoke.
static COUNTER: AtomicU8 = AtomicU8::new(0);
let data = Cow::from(vec![COUNTER.fetch_add(1, Ordering::Relaxed)]);
let hash = <T as Config>::Preimages::note(data).unwrap();
hash
}

benchmarks! {
propose {
let p = T::MaxProposals::get();
Expand Down Expand Up @@ -179,7 +199,7 @@ benchmarks! {
emergency_cancel {
let origin =
T::CancellationOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
let ref_index = add_referendum::<T>(0).0;
let (ref_index, _, preimage_hash) = add_referendum::<T>(0);
assert_ok!(Democracy::<T>::referendum_status(ref_index));
}: _<T::RuntimeOrigin>(origin, ref_index)
verify {
Expand All @@ -188,6 +208,10 @@ benchmarks! {
Democracy::<T>::referendum_status(ref_index),
Error::<T>::ReferendumInvalid,
);
assert_last_event::<T>(crate::Event::MetadataCleared {
owner: MetadataOwner::Referendum(ref_index),
hash: preimage_hash,
}.into());
}

blacklist {
Expand All @@ -198,7 +222,7 @@ benchmarks! {
// 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);
let (ref_index, hash, preimage_hash) = add_referendum::<T>(0);
assert_ok!(Democracy::<T>::referendum_status(ref_index));
// Place our proposal in the external queue, too.
assert_ok!(Democracy::<T>::external_propose(
Expand All @@ -215,6 +239,10 @@ benchmarks! {
Democracy::<T>::referendum_status(ref_index),
Error::<T>::ReferendumInvalid
);
assert_has_event::<T>(crate::Event::MetadataCleared {
owner: MetadataOwner::Referendum(ref_index),
hash: preimage_hash,
}.into());
}

// Worst case scenario, we external propose a previously blacklisted proposal
Expand Down Expand Up @@ -262,16 +290,26 @@ benchmarks! {
.expect("ExternalDefaultOrigin has no successful origin required for the benchmark");
let proposal = make_proposal::<T>(0);
let proposal_hash = proposal.hash();
Democracy::<T>::external_propose_default(origin_propose, proposal)?;

Democracy::<T>::external_propose_default(origin_propose.clone(), proposal)?;
// Set metadata to the external proposal.
let preimage_hash = note_preimage::<T>();
assert_ok!(Democracy::<T>::set_metadata(
origin_propose,
MetadataOwner::External,
Some(preimage_hash)));
// NOTE: Instant origin may invoke a little bit more logic, but may not always succeed.
let origin_fast_track =
T::FastTrackOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
let voting_period = T::FastTrackVotingPeriod::get();
let delay = 0u32;
}: _<T::RuntimeOrigin>(origin_fast_track, proposal_hash, voting_period, delay.into())
verify {
assert_eq!(Democracy::<T>::referendum_count(), 1, "referendum not created")
assert_eq!(Democracy::<T>::referendum_count(), 1, "referendum not created");
assert_last_event::<T>(crate::Event::MetadataTransferred {
prev_owner: MetadataOwner::External,
owner: MetadataOwner::Referendum(0),
hash: preimage_hash,
}.into());
}

veto_external {
Expand All @@ -280,7 +318,14 @@ benchmarks! {

let origin_propose = T::ExternalDefaultOrigin::try_successful_origin()
.expect("ExternalDefaultOrigin has no successful origin required for the benchmark");
Democracy::<T>::external_propose_default(origin_propose, proposal)?;
Democracy::<T>::external_propose_default(origin_propose.clone(), proposal)?;

let preimage_hash = note_preimage::<T>();
assert_ok!(Democracy::<T>::set_metadata(
origin_propose,
MetadataOwner::External,
Some(preimage_hash))
);

let mut vetoers: BoundedVec<T::AccountId, _> = Default::default();
for i in 0 .. (T::MaxBlacklisted::get() - 1) {
Expand All @@ -303,13 +348,32 @@ benchmarks! {
for i in 0 .. T::MaxProposals::get() {
add_proposal::<T>(i)?;
}
// Add metadata to the first proposal.
let proposer = funded_account::<T>("proposer", 0);
let preimage_hash = note_preimage::<T>();
assert_ok!(Democracy::<T>::set_metadata(
RawOrigin::Signed(proposer).into(),
MetadataOwner::Proposal(0),
Some(preimage_hash)));
let cancel_origin = T::CancelProposalOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?;
}: _<T::RuntimeOrigin>(cancel_origin, 0)
verify {
assert_last_event::<T>(crate::Event::MetadataCleared {
owner: MetadataOwner::Proposal(0),
hash: preimage_hash,
}.into());
}

cancel_referendum {
let ref_index = add_referendum::<T>(0).0;
let (ref_index, _, preimage_hash) = add_referendum::<T>(0);
}: _(RawOrigin::Root, ref_index)
verify {
assert_last_event::<T>(crate::Event::MetadataCleared {
owner: MetadataOwner::Referendum(0),
hash: preimage_hash,
}.into());
}

#[extra]
on_initialize_external {
Expand Down Expand Up @@ -678,6 +742,111 @@ benchmarks! {
assert_eq!(votes.len(), (r - 1) as usize, "Vote was not removed");
}

set_external_metadata {
let origin = T::ExternalOrigin::try_successful_origin()
.expect("ExternalOrigin has no successful origin required for the benchmark");
assert_ok!(
Democracy::<T>::external_propose(origin.clone(), make_proposal::<T>(0))
);
let owner = MetadataOwner::External;
let hash = note_preimage::<T>();
}: set_metadata<T::RuntimeOrigin>(origin, owner.clone(), Some(hash))
verify {
assert_last_event::<T>(crate::Event::MetadataSet {
owner,
hash,
}.into());
}

clear_external_metadata {
let origin = T::ExternalOrigin::try_successful_origin()
.expect("ExternalOrigin has no successful origin required for the benchmark");
assert_ok!(
Democracy::<T>::external_propose(origin.clone(), make_proposal::<T>(0))
);
let owner = MetadataOwner::External;
let proposer = funded_account::<T>("proposer", 0);
let hash = note_preimage::<T>();
assert_ok!(Democracy::<T>::set_metadata(origin.clone(), owner.clone(), Some(hash)));
}: set_metadata<T::RuntimeOrigin>(origin, owner.clone(), None)
verify {
assert_last_event::<T>(crate::Event::MetadataCleared {
owner,
hash,
}.into());
}

set_proposal_metadata {
// Place our proposal at the end to make sure it's worst case.
for i in 0 .. T::MaxProposals::get() {
add_proposal::<T>(i)?;
}
let owner = MetadataOwner::Proposal(0);
let proposer = funded_account::<T>("proposer", 0);
let hash = note_preimage::<T>();
}: set_metadata<T::RuntimeOrigin>(RawOrigin::Signed(proposer).into(), owner.clone(), Some(hash))
verify {
assert_last_event::<T>(crate::Event::MetadataSet {
owner,
hash,
}.into());
}

clear_proposal_metadata {
// Place our proposal at the end to make sure it's worst case.
for i in 0 .. T::MaxProposals::get() {
add_proposal::<T>(i)?;
}
let proposer = funded_account::<T>("proposer", 0);
let owner = MetadataOwner::Proposal(0);
let hash = note_preimage::<T>();
assert_ok!(Democracy::<T>::set_metadata(
RawOrigin::Signed(proposer.clone()).into(),
owner.clone(),
Some(hash)));
}: set_metadata<T::RuntimeOrigin>(RawOrigin::Signed(proposer).into(), owner.clone(), None)
verify {
assert_last_event::<T>(crate::Event::MetadataCleared {
owner,
hash,
}.into());
}

set_referendum_metadata {
// create not ongoing referendum.
ReferendumInfoOf::<T>::insert(
0,
ReferendumInfo::Finished { end: T::BlockNumber::zero(), approved: true },
);
let owner = MetadataOwner::Referendum(0);
let caller = funded_account::<T>("caller", 0);
let hash = note_preimage::<T>();
}: set_metadata<T::RuntimeOrigin>(RawOrigin::Root.into(), owner.clone(), Some(hash))
verify {
assert_last_event::<T>(crate::Event::MetadataSet {
owner,
hash,
}.into());
}

clear_referendum_metadata {
// create not ongoing referendum.
ReferendumInfoOf::<T>::insert(
0,
ReferendumInfo::Finished { end: T::BlockNumber::zero(), approved: true },
);
let owner = MetadataOwner::Referendum(0);
let hash = note_preimage::<T>();
MetadataOf::<T>::insert(owner.clone(), hash);
let caller = funded_account::<T>("caller", 0);
}: set_metadata<T::RuntimeOrigin>(RawOrigin::Signed(caller).into(), owner.clone(), None)
verify {
assert_last_event::<T>(crate::Event::MetadataCleared {
owner,
hash,
}.into());
}

impl_benchmark_test_suite!(
Democracy,
crate::tests::new_test_ext(),
Expand Down
Loading

0 comments on commit 2f16448

Please sign in to comment.