This repository was archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Introduce cancel_proposal to rid us of those pesky proposals
#7111
Merged
Merged
Changes from 11 commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
aadfd4b
Introduce `cancel_proposal`
gavofyork a67a018
Support proposal cancellation from runtime.
gavofyork bec8bad
Fixes
gavofyork 06c97f2
Fixes
gavofyork 693fc82
Fixes
gavofyork bbe86b6
Fixes
gavofyork 083ba8d
Fixes
gavofyork 3626e8e
Fixes
gavofyork c93eedb
Fixes
gavofyork 2274fa3
Merge remote-tracking branch 'origin/master' into gav-cancel-proposal
gavofyork 400d8e4
Merge remote-tracking branch 'origin/master' into gav-cancel-proposal
gavofyork a8e9fe8
Fix benchmarks
shawntabrizi 764ea77
fix benchmark
shawntabrizi a5dfded
whitelisted caller weights
shawntabrizi 4aaa1e8
Merge branch 'master' into gav-cancel-proposal
shawntabrizi a36189f
fix build
shawntabrizi 1254cf6
Merge remote-tracking branch 'origin/master' into gav-cancel-proposal
gavofyork f60cccc
Fixes
gavofyork 13cace0
Fixes
gavofyork 02e4fe8
Fixes
gavofyork 88dc626
Fixes
gavofyork a1ebcb1
Merge remote-tracking branch 'origin/master' into gav-cancel-proposal
gavofyork 775b637
Update frame/democracy/src/lib.rs
gavofyork 9c0cf8d
Fixes
gavofyork 2ba9cdd
Fixes
gavofyork 847414f
Merge branch 'gav-cancel-proposal' of github.com:paritytech/substrate…
gavofyork 4ecbddf
Fixes
gavofyork 2f84c91
Fixes
gavofyork 42b9093
Fixes
gavofyork 97af811
doc updates
shawntabrizi b466e1f
new weights
shawntabrizi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -155,7 +155,7 @@ | |
| use sp_std::prelude::*; | ||
| use sp_runtime::{ | ||
| DispatchResult, DispatchError, RuntimeDebug, | ||
| traits::{Zero, Hash, Dispatchable, Saturating}, | ||
| traits::{Zero, Hash, Dispatchable, Saturating, Bounded}, | ||
| }; | ||
| use codec::{Encode, Decode, Input}; | ||
| use frame_support::{ | ||
|
|
@@ -192,6 +192,9 @@ const DEMOCRACY_ID: LockIdentifier = *b"democrac"; | |
| /// NOTE: This is not enforced by any logic. | ||
| pub const MAX_VETOERS: u32 = 100; | ||
|
|
||
| /// The maximum number of public proposals that can exist at any time. | ||
| pub const MAX_PROPOSALS: u32 = 1000; | ||
|
|
||
| /// A proposal index. | ||
| pub type PropIndex = u32; | ||
|
|
||
|
|
@@ -203,17 +206,19 @@ type NegativeImbalanceOf<T> = | |
| <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::NegativeImbalance; | ||
|
|
||
| pub trait WeightInfo { | ||
| fn propose() -> Weight; | ||
| fn propose(p: u32, ) -> Weight; | ||
| fn second(s: u32, ) -> Weight; | ||
| fn vote_new(r: u32, ) -> Weight; | ||
| fn vote_existing(r: u32, ) -> Weight; | ||
| fn emergency_cancel() -> Weight; | ||
| fn blacklist() -> Weight; | ||
| fn external_propose(v: u32, ) -> Weight; | ||
| fn external_propose_majority() -> Weight; | ||
| fn external_propose_default() -> Weight; | ||
| fn fast_track() -> Weight; | ||
| fn veto_external(v: u32, ) -> Weight; | ||
| fn cancel_referendum() -> Weight; | ||
| fn cancel_proposal() -> Weight; | ||
| fn cancel_queued(r: u32, ) -> Weight; | ||
| fn on_initialize_base(r: u32, ) -> Weight; | ||
| fn delegate(r: u32, ) -> Weight; | ||
|
|
@@ -285,6 +290,12 @@ pub trait Trait: frame_system::Trait + Sized { | |
| /// Origin from which any referendum may be cancelled in an emergency. | ||
| type CancellationOrigin: EnsureOrigin<Self::Origin>; | ||
|
|
||
| /// Origin from which proposals may be blacklisted. | ||
| type BlacklistOrigin: EnsureOrigin<Self::Origin>; | ||
|
|
||
| /// Origin from which a proposal may be cancelled and its backers slashed. | ||
| type CancelProposalOrigin: EnsureOrigin<Self::Origin>; | ||
|
|
||
| /// Origin for anyone able to veto proposals. | ||
| /// | ||
| /// # Warning | ||
|
|
@@ -414,8 +425,7 @@ decl_storage! { | |
|
|
||
| /// A record of who vetoed what. Maps proposal hash to a possible existent block number | ||
| /// (until when it may not be resubmitted) and who vetoed it. | ||
| pub Blacklist get(fn blacklist): | ||
| map hasher(identity) T::Hash => Option<(T::BlockNumber, Vec<T::AccountId>)>; | ||
| pub Blacklist: map hasher(identity) T::Hash => Option<(T::BlockNumber, Vec<T::AccountId>)>; | ||
|
|
||
| /// Record of all proposals that have been subject to emergency cancellation. | ||
| pub Cancellations: map hasher(identity) T::Hash => bool; | ||
|
|
@@ -472,6 +482,8 @@ decl_event! { | |
| PreimageReaped(Hash, AccountId, Balance, AccountId), | ||
| /// An \[account\] has been unlocked successfully. | ||
| Unlocked(AccountId), | ||
| /// A proposal \[hash\] has been blacklisted permanently. | ||
| Blacklisted(Hash), | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -544,6 +556,10 @@ decl_error! { | |
| WrongUpperBound, | ||
| /// Maximum number of votes reached. | ||
| MaxVotesReached, | ||
| /// The provided witness data is wrong. | ||
| InvalidWitness, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. self/random note that some other modules can generally use this terminology: Some data that is passed in for sanity/weight should be called witness data. |
||
| /// Maximum number of proposals reached. | ||
| TooManyProposals, | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -596,14 +612,28 @@ decl_module! { | |
| /// - Db reads: `PublicPropCount`, `PublicProps` | ||
| /// - Db writes: `PublicPropCount`, `PublicProps`, `DepositOf` | ||
| /// # </weight> | ||
| #[weight = T::WeightInfo::propose()] | ||
| fn propose(origin, proposal_hash: T::Hash, #[compact] value: BalanceOf<T>) { | ||
| #[weight = T::WeightInfo::propose(*prop_count)] | ||
| fn propose(origin, | ||
| proposal_hash: T::Hash, | ||
| #[compact] value: BalanceOf<T>, | ||
| #[compact] prop_count: u32, | ||
|
gavofyork marked this conversation as resolved.
Outdated
gavofyork marked this conversation as resolved.
Outdated
|
||
| ) { | ||
| let who = ensure_signed(origin)?; | ||
| ensure!(value >= T::MinimumDeposit::get(), Error::<T>::ValueLow); | ||
|
|
||
| T::Currency::reserve(&who, value)?; | ||
|
|
||
| let index = Self::public_prop_count(); | ||
| let real_prop_count = PublicProps::<T>::decode_len().unwrap_or(0) as u32; | ||
| ensure!(real_prop_count <= prop_count, Error::<T>::InvalidWitness); | ||
| ensure!(real_prop_count < MAX_PROPOSALS, Error::<T>::TooManyProposals); | ||
|
|
||
| if let Some((until, _)) = <Blacklist<T>>::get(proposal_hash) { | ||
| ensure!( | ||
| <frame_system::Module<T>>::block_number() >= until, | ||
| Error::<T>::ProposalBlacklisted, | ||
| ); | ||
| } | ||
|
|
||
| T::Currency::reserve(&who, value)?; | ||
| PublicPropCount::put(index + 1); | ||
| <DepositOf<T>>::insert(index, (&[&who][..], value)); | ||
|
|
||
|
|
@@ -688,6 +718,58 @@ decl_module! { | |
| Self::internal_cancel_referendum(ref_index); | ||
| } | ||
|
|
||
| /// Permanently place a proposal into the blacklist. This prevents it from ever being | ||
| /// proposed again. | ||
| /// | ||
| /// If called on an queued public or external proposal, then this will result in it being | ||
|
gavofyork marked this conversation as resolved.
Outdated
|
||
| /// removed. If the `ref_index` supplied is an active referendum with the proposal hash, | ||
| /// then it will be cancelled. | ||
| /// | ||
| /// The dispatch origin of this call must be `BlacklistOrigin`. | ||
| /// | ||
| /// - `proposal_hash`: The proposal hash to blacklist permanently. | ||
| /// - `ref_index`: An ongoing referendum whose hash is `proposal_hash`, which will be | ||
| /// cancelled. | ||
|
gavofyork marked this conversation as resolved.
Outdated
|
||
| #[weight = (T::WeightInfo::blacklist(), DispatchClass::Operational)] | ||
| fn blacklist(origin, | ||
| proposal_hash: T::Hash, | ||
| maybe_ref_index: Option<ReferendumIndex>, | ||
| ) { | ||
| T::BlacklistOrigin::ensure_origin(origin)?; | ||
|
|
||
| // Insert the proposal into the blacklist. | ||
| let permanent = (T::BlockNumber::max_value(), Vec::<T::AccountId>::new()); | ||
| Blacklist::<T>::insert(&proposal_hash, permanent); | ||
|
|
||
| // Remove the queued proposal, if it's there. | ||
| PublicProps::<T>::mutate(|props| { | ||
|
gui1117 marked this conversation as resolved.
Outdated
|
||
| if let Some(index) = props.iter().position(|p| p.1 == proposal_hash) { | ||
| let (prop_index, ..) = props.remove(index); | ||
| if let Some((whos, amount)) = DepositOf::<T>::take(prop_index) { | ||
| for who in whos.into_iter() { | ||
| T::Slash::on_unbalanced(T::Currency::slash_reserved(&who, amount).0); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| // Remove the external queued referendum, if it's there. | ||
| if matches!(NextExternal::<T>::get(), Some((h, ..)) if h == proposal_hash) { | ||
| NextExternal::<T>::kill(); | ||
| } | ||
|
|
||
| // Remove the referendum, if it's there. | ||
| if let Some(ref_index) = maybe_ref_index { | ||
| let status = Self::referendum_status(ref_index)?; | ||
| let h = status.proposal_hash; | ||
| if h == proposal_hash { | ||
| Self::internal_cancel_referendum(ref_index); | ||
| } | ||
| } | ||
|
|
||
| Self::deposit_event(RawEvent::Blacklisted(proposal_hash)); | ||
| } | ||
|
|
||
| /// Schedule a referendum to be tabled once it is legal to schedule an external | ||
| /// referendum. | ||
| /// | ||
|
|
@@ -848,6 +930,29 @@ decl_module! { | |
| <NextExternal<T>>::kill(); | ||
| } | ||
|
|
||
| /// Remove a proposal. | ||
| /// | ||
| /// The dispatch origin of this call must be _Root_. | ||
| /// | ||
| /// - `ref_index`: The index of the proposal to cancel. | ||
|
gavofyork marked this conversation as resolved.
Outdated
|
||
| /// | ||
| /// # <weight> | ||
| /// - Complexity: `O(1)`. | ||
| /// - Db writes: `ReferendumInfoOf` | ||
|
gavofyork marked this conversation as resolved.
Outdated
|
||
| /// - Base Weight: 21.57 µs | ||
| /// # </weight> | ||
| #[weight = T::WeightInfo::cancel_proposal()] | ||
| fn cancel_proposal(origin, #[compact] prop_index: PropIndex) { | ||
|
gavofyork marked this conversation as resolved.
Outdated
|
||
| T::CancelProposalOrigin::ensure_origin(origin)?; | ||
|
|
||
| PublicProps::<T>::mutate(|props| props.retain(|p| p.0 != prop_index)); | ||
|
gavofyork marked this conversation as resolved.
Outdated
|
||
| if let Some((whos, amount)) = DepositOf::<T>::take(prop_index) { | ||
| for who in whos.into_iter() { | ||
| T::Slash::on_unbalanced(T::Currency::slash_reserved(&who, amount).0); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Remove a referendum. | ||
| /// | ||
| /// The dispatch origin of this call must be _Root_. | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.