Run cargo fmt on the whole code base (#9394)

* Run cargo fmt on the whole code base

* Second run

* Add CI check

* Fix compilation

* More unnecessary braces

* Handle weights

* Use --all

* Use correct attributes...

* Fix UI tests

* AHHHHHHHHH

* 🤦

* Docs

* Fix compilation

* 🤷

* Please stop

* 🤦 x 2

* More

* make rustfmt.toml consistent with polkadot

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-07-21 16:32:32 +02:00
committed by GitHub
parent d451c38c1c
commit 7b56ab15b4
1010 changed files with 53339 additions and 51208 deletions
+17 -29
View File
@@ -19,13 +19,15 @@
use super::*;
use frame_benchmarking::{benchmarks, account, whitelist_account, impl_benchmark_test_suite};
use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite, whitelist_account};
use frame_support::{
assert_noop, assert_ok,
traits::{Currency, Get, EnsureOrigin, OnInitialize, UnfilteredDispatchable, schedule::DispatchTime},
traits::{
schedule::DispatchTime, Currency, EnsureOrigin, Get, OnInitialize, UnfilteredDispatchable,
},
};
use frame_system::{RawOrigin, Pallet as System, self};
use sp_runtime::traits::{Bounded, One, BadOrigin};
use frame_system::{Pallet as System, RawOrigin};
use sp_runtime::traits::{BadOrigin, Bounded, One};
use crate::Pallet as Democracy;
@@ -49,11 +51,7 @@ fn add_proposal<T: Config>(n: u32) -> Result<T::Hash, &'static str> {
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.into(),
)?;
Democracy::<T>::propose(RawOrigin::Signed(other).into(), proposal_hash, value.into())?;
Ok(proposal_hash)
}
@@ -76,20 +74,15 @@ fn add_referendum<T: Config>(n: u32) -> Result<ReferendumIndex, &'static str> {
63,
frame_system::RawOrigin::Root.into(),
Call::enact_proposal(proposal_hash, referendum_index).into(),
).map_err(|_| "failed to schedule named")?;
)
.map_err(|_| "failed to schedule named")?;
Ok(referendum_index)
}
fn account_vote<T: Config>(b: BalanceOf<T>) -> AccountVote<BalanceOf<T>> {
let v = Vote {
aye: true,
conviction: Conviction::Locked1x,
};
let v = Vote { aye: true, conviction: Conviction::Locked1x };
AccountVote::Standard {
vote: v,
balance: b,
}
AccountVote::Standard { vote: v, balance: b }
}
benchmarks! {
@@ -224,8 +217,8 @@ benchmarks! {
// 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.clone())
);
Democracy::<T>::external_propose(T::ExternalOrigin::successful_origin(), hash.clone())
);
// Add a referendum of our proposal.
let referendum_index = add_referendum::<T>(0)?;
@@ -237,9 +230,9 @@ benchmarks! {
verify {
// Referendum has been canceled
assert_noop!(
Democracy::<T>::referendum_status(referendum_index),
Error::<T>::ReferendumInvalid
);
Democracy::<T>::referendum_status(referendum_index),
Error::<T>::ReferendumInvalid
);
}
// Worst case scenario, we external propose a previously blacklisted proposal
@@ -785,9 +778,4 @@ benchmarks! {
}
}
impl_benchmark_test_suite!(
Democracy,
crate::tests::new_test_ext(),
crate::tests::Test,
);
impl_benchmark_test_suite!(Democracy, crate::tests::new_test_ext(), crate::tests::Test,);
+10 -6
View File
@@ -17,10 +17,13 @@
//! The conviction datatype.
use sp_std::{result::Result, convert::TryFrom};
use sp_runtime::{RuntimeDebug, traits::{Zero, Bounded, CheckedMul, CheckedDiv}};
use codec::{Encode, Decode};
use crate::types::Delegations;
use codec::{Decode, Encode};
use sp_runtime::{
traits::{Bounded, CheckedDiv, CheckedMul, Zero},
RuntimeDebug,
};
use sp_std::{convert::TryFrom, result::Result};
/// A value denoting the strength of conviction of a vote.
#[derive(Encode, Decode, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)]
@@ -93,9 +96,10 @@ impl Conviction {
}
/// The votes of a voter of the given `balance` with our conviction.
pub fn votes<
B: From<u8> + Zero + Copy + CheckedMul + CheckedDiv + Bounded
>(self, capital: B) -> Delegations<B> {
pub fn votes<B: From<u8> + Zero + Copy + CheckedMul + CheckedDiv + Bounded>(
self,
capital: B,
) -> Delegations<B> {
let votes = match self {
Conviction::None => capital.checked_div(&10u8.into()).unwrap_or_else(Zero::zero),
x => capital.checked_mul(&u8::from(x).into()).unwrap_or_else(B::max_value),
+164 -136
View File
@@ -121,7 +121,7 @@
//! This call can only be made by the `ExternalMajorityOrigin`.
//!
//! - `external_propose_majority` - Schedules a proposal to become a majority-carries
//! referendum once it is legal for an externally proposed referendum.
//! referendum once it is legal for an externally proposed referendum.
//!
//! #### External Default Origin
//!
@@ -149,34 +149,36 @@
//! - `cancel_queued` - Cancels a proposal that is queued for enactment.
//! - `clear_public_proposal` - Removes all public proposals.
#![recursion_limit="128"]
#![recursion_limit = "128"]
#![cfg_attr(not(feature = "std"), no_std)]
use sp_std::prelude::*;
use sp_runtime::{
DispatchResult, DispatchError, ArithmeticError, RuntimeDebug,
traits::{Zero, Hash, Dispatchable, Saturating, Bounded},
};
use codec::{Encode, Decode, Input};
use codec::{Decode, Encode, Input};
use frame_support::{
ensure, weights::Weight,
ensure,
traits::{
Currency, ReservableCurrency, LockableCurrency, WithdrawReasons, LockIdentifier, Get,
OnUnbalanced, BalanceStatus, schedule::{Named as ScheduleNamed, DispatchTime},
schedule::{DispatchTime, Named as ScheduleNamed},
BalanceStatus, Currency, Get, LockIdentifier, LockableCurrency, OnUnbalanced,
ReservableCurrency, WithdrawReasons,
},
weights::Weight,
};
use sp_runtime::{
traits::{Bounded, Dispatchable, Hash, Saturating, Zero},
ArithmeticError, DispatchError, DispatchResult, RuntimeDebug,
};
use sp_std::prelude::*;
mod vote_threshold;
mod vote;
mod conviction;
mod types;
mod vote;
mod vote_threshold;
pub mod weights;
pub use weights::WeightInfo;
pub use vote_threshold::{Approved, VoteThreshold};
pub use vote::{Vote, AccountVote, Voting};
pub use conviction::Conviction;
pub use types::{ReferendumInfo, ReferendumStatus, Tally, UnvoteScope, Delegations};
pub use pallet::*;
pub use types::{Delegations, ReferendumInfo, ReferendumStatus, Tally, UnvoteScope};
pub use vote::{AccountVote, Vote, Voting};
pub use vote_threshold::{Approved, VoteThreshold};
pub use weights::WeightInfo;
#[cfg(test)]
mod tests;
@@ -197,9 +199,11 @@ pub type PropIndex = u32;
/// A referendum index.
pub type ReferendumIndex = u32;
type BalanceOf<T> = <<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
type NegativeImbalanceOf<T> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;
type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
type NegativeImbalanceOf<T> = <<T as Config>::Currency as Currency<
<T as frame_system::Config>::AccountId,
>>::NegativeImbalance;
#[derive(Clone, Encode, Decode, RuntimeDebug)]
pub enum PreimageStatus<AccountId, Balance, BlockNumber> {
@@ -235,13 +239,16 @@ enum Releases {
#[frame_support::pallet]
pub mod pallet {
use sp_runtime::DispatchResult;
use frame_support::{
pallet_prelude::*, Parameter,
weights::{DispatchClass, Pays}, traits::EnsureOrigin, dispatch::DispatchResultWithPostInfo,
};
use frame_system::{pallet_prelude::*, ensure_signed, ensure_root};
use super::*;
use frame_support::{
dispatch::DispatchResultWithPostInfo,
pallet_prelude::*,
traits::EnsureOrigin,
weights::{DispatchClass, Pays},
Parameter,
};
use frame_system::{ensure_root, ensure_signed, pallet_prelude::*};
use sp_runtime::DispatchResult;
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
@@ -249,12 +256,12 @@ pub mod pallet {
#[pallet::config]
pub trait Config: frame_system::Config + Sized {
type Proposal: Parameter + Dispatchable<Origin=Self::Origin> + From<Call<Self>>;
type Proposal: Parameter + Dispatchable<Origin = Self::Origin> + From<Call<Self>>;
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
/// Currency type for this pallet.
type Currency: ReservableCurrency<Self::AccountId>
+ LockableCurrency<Self::AccountId, Moment=Self::BlockNumber>;
+ LockableCurrency<Self::AccountId, Moment = Self::BlockNumber>;
/// The minimum period of locking and the period between a proposal being approved and enacted.
///
@@ -323,7 +330,7 @@ pub mod pallet {
///
/// The number of Vetoers for a proposal must be small, extrinsics are weighted according to
/// [MAX_VETOERS](./const.MAX_VETOERS.html)
type VetoOrigin: EnsureOrigin<Self::Origin, Success=Self::AccountId>;
type VetoOrigin: EnsureOrigin<Self::Origin, Success = Self::AccountId>;
/// Period in blocks where an external proposal may not be re-submitted after being vetoed.
#[pallet::constant]
@@ -334,7 +341,7 @@ pub mod pallet {
type PreimageByteDeposit: Get<BalanceOf<Self>>;
/// An origin that can provide a preimage using operational extrinsics.
type OperationalPreimageOrigin: EnsureOrigin<Self::Origin, Success=Self::AccountId>;
type OperationalPreimageOrigin: EnsureOrigin<Self::Origin, Success = Self::AccountId>;
/// Handler for the unbalanced reduction when slashing a preimage deposit.
type Slash: OnUnbalanced<NegativeImbalanceOf<Self>>;
@@ -370,18 +377,16 @@ pub mod pallet {
/// The public proposals. Unsorted. The second item is the proposal's hash.
#[pallet::storage]
#[pallet::getter(fn public_props)]
pub type PublicProps<T: Config> = StorageValue<_, Vec<(PropIndex, T::Hash, T::AccountId)>, ValueQuery>;
pub type PublicProps<T: Config> =
StorageValue<_, Vec<(PropIndex, T::Hash, T::AccountId)>, ValueQuery>;
/// Those who have locked a deposit.
///
/// TWOX-NOTE: Safe, as increasing integer keys are safe.
#[pallet::storage]
#[pallet::getter(fn deposit_of)]
pub type DepositOf<T: Config> = StorageMap<
_,
Twox64Concat, PropIndex,
(Vec<T::AccountId>, BalanceOf<T>),
>;
pub type DepositOf<T: Config> =
StorageMap<_, Twox64Concat, PropIndex, (Vec<T::AccountId>, BalanceOf<T>)>;
/// Map of hashes to the proposal preimage, along with who registered it and their deposit.
/// The block number is the block at which it was deposited.
@@ -390,7 +395,8 @@ pub mod pallet {
#[pallet::storage]
pub type Preimages<T: Config> = StorageMap<
_,
Identity, T::Hash,
Identity,
T::Hash,
PreimageStatus<T::AccountId, BalanceOf<T>, T::BlockNumber>,
>;
@@ -412,7 +418,8 @@ pub mod pallet {
#[pallet::getter(fn referendum_info)]
pub type ReferendumInfoOf<T: Config> = StorageMap<
_,
Twox64Concat, ReferendumIndex,
Twox64Concat,
ReferendumIndex,
ReferendumInfo<T::BlockNumber, T::Hash, BalanceOf<T>>,
>;
@@ -422,7 +429,9 @@ pub mod pallet {
/// TWOX-NOTE: SAFE as `AccountId`s are crypto hashes anyway.
#[pallet::storage]
pub type VotingOf<T: Config> = StorageMap<
_, Twox64Concat, T::AccountId,
_,
Twox64Concat,
T::AccountId,
Voting<BalanceOf<T>, T::AccountId, T::BlockNumber>,
ValueQuery,
>;
@@ -452,7 +461,8 @@ pub mod pallet {
/// 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.
#[pallet::storage]
pub type Blacklist<T: Config> = StorageMap<_, Identity, T::Hash, (T::BlockNumber, Vec<T::AccountId>)>;
pub type Blacklist<T: Config> =
StorageMap<_, Identity, T::Hash, (T::BlockNumber, Vec<T::AccountId>)>;
/// Record of all proposals that have been subject to emergency cancellation.
#[pallet::storage]
@@ -472,9 +482,7 @@ pub mod pallet {
#[cfg(feature = "std")]
impl<T: Config> Default for GenesisConfig<T> {
fn default() -> Self {
GenesisConfig {
_phantom: Default::default(),
}
GenesisConfig { _phantom: Default::default() }
}
}
@@ -684,11 +692,10 @@ pub mod pallet {
) -> DispatchResult {
let who = ensure_signed(origin)?;
let seconds = Self::len_of_deposit_of(proposal)
.ok_or_else(|| Error::<T>::ProposalMissing)?;
let seconds =
Self::len_of_deposit_of(proposal).ok_or_else(|| Error::<T>::ProposalMissing)?;
ensure!(seconds <= seconds_upper_bound, Error::<T>::WrongUpperBound);
let mut deposit = Self::deposit_of(proposal)
.ok_or(Error::<T>::ProposalMissing)?;
let mut deposit = Self::deposit_of(proposal).ok_or(Error::<T>::ProposalMissing)?;
T::Currency::reserve(&who, deposit.1)?;
deposit.0.push(who);
<DepositOf<T>>::insert(proposal, deposit);
@@ -726,7 +733,10 @@ pub mod pallet {
///
/// Weight: `O(1)`.
#[pallet::weight((T::WeightInfo::emergency_cancel(), DispatchClass::Operational))]
pub fn emergency_cancel(origin: OriginFor<T>, ref_index: ReferendumIndex) -> DispatchResult {
pub fn emergency_cancel(
origin: OriginFor<T>,
ref_index: ReferendumIndex,
) -> DispatchResult {
T::CancellationOrigin::ensure_origin(origin)?;
let status = Self::referendum_status(ref_index)?;
@@ -842,8 +852,8 @@ pub mod pallet {
ensure!(T::InstantAllowed::get(), Error::<T>::InstantNotAllowed);
}
let (e_proposal_hash, threshold) = <NextExternal<T>>::get()
.ok_or(Error::<T>::ProposalMissing)?;
let (e_proposal_hash, threshold) =
<NextExternal<T>>::get().ok_or(Error::<T>::ProposalMissing)?;
ensure!(
threshold != VoteThreshold::SuperMajorityApprove,
Error::<T>::NotSimpleMajority,
@@ -875,11 +885,10 @@ pub mod pallet {
Err(Error::<T>::NoProposal)?;
}
let mut existing_vetoers = <Blacklist<T>>::get(&proposal_hash)
.map(|pair| pair.1)
.unwrap_or_else(Vec::new);
let insert_position = existing_vetoers.binary_search(&who)
.err().ok_or(Error::<T>::AlreadyVetoed)?;
let mut existing_vetoers =
<Blacklist<T>>::get(&proposal_hash).map(|pair| pair.1).unwrap_or_else(Vec::new);
let insert_position =
existing_vetoers.binary_search(&who).err().ok_or(Error::<T>::AlreadyVetoed)?;
existing_vetoers.insert(insert_position, who.clone());
let until = <frame_system::Pallet<T>>::block_number() + T::CooloffPeriod::get();
@@ -949,7 +958,7 @@ pub mod pallet {
origin: OriginFor<T>,
to: T::AccountId,
conviction: Conviction,
balance: BalanceOf<T>
balance: BalanceOf<T>,
) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
let votes = Self::try_delegate(who, to, conviction, balance)?;
@@ -1089,10 +1098,11 @@ pub mod pallet {
let (provider, deposit, since, expiry) = <Preimages<T>>::get(&proposal_hash)
.and_then(|m| match m {
PreimageStatus::Available { provider, deposit, since, expiry, .. }
=> Some((provider, deposit, since, expiry)),
PreimageStatus::Available { provider, deposit, since, expiry, .. } =>
Some((provider, deposit, since, expiry)),
_ => None,
}).ok_or(Error::<T>::PreimageMissing)?;
})
.ok_or(Error::<T>::PreimageMissing)?;
let now = <frame_system::Pallet<T>>::block_number();
let (voting, enactment) = (T::VotingPeriod::get(), T::EnactmentPeriod::get());
@@ -1100,7 +1110,8 @@ pub mod pallet {
ensure!(now >= since + voting + additional, Error::<T>::TooEarly);
ensure!(expiry.map_or(true, |e| now > e), Error::<T>::Imminent);
let res = T::Currency::repatriate_reserved(&provider, &who, deposit, BalanceStatus::Free);
let res =
T::Currency::repatriate_reserved(&provider, &who, deposit, BalanceStatus::Free);
debug_assert!(res.is_ok());
<Preimages<T>>::remove(&proposal_hash);
Self::deposit_event(Event::<T>::PreimageReaped(proposal_hash, provider, deposit, who));
@@ -1211,7 +1222,8 @@ pub mod pallet {
/// Weight: `O(p)` (though as this is an high-privilege dispatch, we assume it has a
/// reasonable value).
#[pallet::weight((T::WeightInfo::blacklist(T::MaxProposals::get()), DispatchClass::Operational))]
pub fn blacklist(origin: OriginFor<T>,
pub fn blacklist(
origin: OriginFor<T>,
proposal_hash: T::Hash,
maybe_ref_index: Option<ReferendumIndex>,
) -> DispatchResult {
@@ -1288,7 +1300,7 @@ impl<T: Config> Pallet<T> {
/// Get all referenda ready for tally at block `n`.
pub fn maturing_referenda_at(
n: T::BlockNumber
n: T::BlockNumber,
) -> Vec<(ReferendumIndex, ReferendumStatus<T::BlockNumber, T::Hash, BalanceOf<T>>)> {
let next = Self::lowest_unbaked();
let last = Self::referendum_count();
@@ -1299,7 +1311,8 @@ impl<T: Config> Pallet<T> {
n: T::BlockNumber,
range: core::ops::Range<PropIndex>,
) -> Vec<(ReferendumIndex, ReferendumStatus<T::BlockNumber, T::Hash, BalanceOf<T>>)> {
range.into_iter()
range
.into_iter()
.map(|i| (i, Self::referendum_info(i)))
.filter_map(|(i, maybe_info)| match maybe_info {
Some(ReferendumInfo::Ongoing(status)) => Some((i, status)),
@@ -1315,13 +1328,13 @@ impl<T: Config> Pallet<T> {
pub fn internal_start_referendum(
proposal_hash: T::Hash,
threshold: VoteThreshold,
delay: T::BlockNumber
delay: T::BlockNumber,
) -> ReferendumIndex {
<Pallet<T>>::inject_referendum(
<frame_system::Pallet<T>>::block_number() + T::VotingPeriod::get(),
proposal_hash,
threshold,
delay
delay,
)
}
@@ -1334,25 +1347,28 @@ impl<T: Config> Pallet<T> {
// private.
/// Ok if the given referendum is active, Err otherwise
fn ensure_ongoing(r: ReferendumInfo<T::BlockNumber, T::Hash, BalanceOf<T>>)
-> Result<ReferendumStatus<T::BlockNumber, T::Hash, BalanceOf<T>>, DispatchError>
{
fn ensure_ongoing(
r: ReferendumInfo<T::BlockNumber, T::Hash, BalanceOf<T>>,
) -> Result<ReferendumStatus<T::BlockNumber, T::Hash, BalanceOf<T>>, DispatchError> {
match r {
ReferendumInfo::Ongoing(s) => Ok(s),
_ => Err(Error::<T>::ReferendumInvalid.into()),
}
}
fn referendum_status(ref_index: ReferendumIndex)
-> Result<ReferendumStatus<T::BlockNumber, T::Hash, BalanceOf<T>>, DispatchError>
{
let info = ReferendumInfoOf::<T>::get(ref_index)
.ok_or(Error::<T>::ReferendumInvalid)?;
fn referendum_status(
ref_index: ReferendumIndex,
) -> Result<ReferendumStatus<T::BlockNumber, T::Hash, BalanceOf<T>>, DispatchError> {
let info = ReferendumInfoOf::<T>::get(ref_index).ok_or(Error::<T>::ReferendumInvalid)?;
Self::ensure_ongoing(info)
}
/// Actually enact a vote, if legit.
fn try_vote(who: &T::AccountId, ref_index: ReferendumIndex, vote: AccountVote<BalanceOf<T>>) -> DispatchResult {
fn try_vote(
who: &T::AccountId,
ref_index: ReferendumIndex,
vote: AccountVote<BalanceOf<T>>,
) -> DispatchResult {
let mut status = Self::referendum_status(ref_index)?;
ensure!(vote.balance() <= T::Currency::free_balance(who), Error::<T>::InsufficientFunds);
VotingOf::<T>::try_mutate(who, |voting| -> DispatchResult {
@@ -1365,11 +1381,14 @@ impl<T: Config> Pallet<T> {
status.tally.reduce(approve, *delegations);
}
votes[i].1 = vote;
}
},
Err(i) => {
ensure!(votes.len() as u32 <= T::MaxVotes::get(), Error::<T>::MaxVotesReached);
ensure!(
votes.len() as u32 <= T::MaxVotes::get(),
Error::<T>::MaxVotesReached
);
votes.insert(i, (ref_index, vote));
}
},
}
// Shouldn't be possible to fail, but we handle it gracefully.
status.tally.add(vote).ok_or(ArithmeticError::Overflow)?;
@@ -1383,12 +1402,7 @@ impl<T: Config> Pallet<T> {
})?;
// Extend the lock to `balance` (rather than setting it) since we don't know what other
// votes are in place.
T::Currency::extend_lock(
DEMOCRACY_ID,
who,
vote.balance(),
WithdrawReasons::TRANSFER
);
T::Currency::extend_lock(DEMOCRACY_ID, who, vote.balance(), WithdrawReasons::TRANSFER);
ReferendumInfoOf::<T>::insert(ref_index, ReferendumInfo::Ongoing(status));
Ok(())
}
@@ -1399,11 +1413,17 @@ impl<T: Config> Pallet<T> {
/// - The referendum has finished and the voter's lock period is up.
///
/// This will generally be combined with a call to `unlock`.
fn try_remove_vote(who: &T::AccountId, ref_index: ReferendumIndex, scope: UnvoteScope) -> DispatchResult {
fn try_remove_vote(
who: &T::AccountId,
ref_index: ReferendumIndex,
scope: UnvoteScope,
) -> DispatchResult {
let info = ReferendumInfoOf::<T>::get(ref_index);
VotingOf::<T>::try_mutate(who, |voting| -> DispatchResult {
if let Voting::Direct { ref mut votes, delegations, ref mut prior } = voting {
let i = votes.binary_search_by_key(&ref_index, |i| i.0).map_err(|_| Error::<T>::NotVoter)?;
let i = votes
.binary_search_by_key(&ref_index, |i| i.0)
.map_err(|_| Error::<T>::NotVoter)?;
match info {
Some(ReferendumInfo::Ongoing(mut status)) => {
ensure!(matches!(scope, UnvoteScope::Any), Error::<T>::NoPermission);
@@ -1413,17 +1433,20 @@ impl<T: Config> Pallet<T> {
status.tally.reduce(approve, *delegations);
}
ReferendumInfoOf::<T>::insert(ref_index, ReferendumInfo::Ongoing(status));
}
Some(ReferendumInfo::Finished{end, approved}) =>
},
Some(ReferendumInfo::Finished { end, approved }) =>
if let Some((lock_periods, balance)) = votes[i].1.locked_if(approved) {
let unlock_at = end + T::EnactmentPeriod::get() * lock_periods.into();
let now = frame_system::Pallet::<T>::block_number();
if now < unlock_at {
ensure!(matches!(scope, UnvoteScope::Any), Error::<T>::NoPermission);
ensure!(
matches!(scope, UnvoteScope::Any),
Error::<T>::NoPermission
);
prior.accumulate(unlock_at, balance)
}
},
None => {} // Referendum was cancelled.
None => {}, // Referendum was cancelled.
}
votes.remove(i);
}
@@ -1444,15 +1467,15 @@ impl<T: Config> Pallet<T> {
*delegations = delegations.saturating_add(amount);
for &(ref_index, account_vote) in votes.iter() {
if let AccountVote::Standard { vote, .. } = account_vote {
ReferendumInfoOf::<T>::mutate(ref_index, |maybe_info|
ReferendumInfoOf::<T>::mutate(ref_index, |maybe_info| {
if let Some(ReferendumInfo::Ongoing(ref mut status)) = maybe_info {
status.tally.increase(vote.aye, amount);
}
);
});
}
}
votes.len() as u32
}
},
})
}
@@ -1463,20 +1486,20 @@ impl<T: Config> Pallet<T> {
// We don't support second level delegating, so we don't need to do anything more.
*delegations = delegations.saturating_sub(amount);
1
}
},
Voting::Direct { votes, delegations, .. } => {
*delegations = delegations.saturating_sub(amount);
for &(ref_index, account_vote) in votes.iter() {
if let AccountVote::Standard { vote, .. } = account_vote {
ReferendumInfoOf::<T>::mutate(ref_index, |maybe_info|
ReferendumInfoOf::<T>::mutate(ref_index, |maybe_info| {
if let Some(ReferendumInfo::Ongoing(ref mut status)) = maybe_info {
status.tally.reduce(vote.aye, amount);
}
);
});
}
}
votes.len() as u32
}
},
})
}
@@ -1505,22 +1528,17 @@ impl<T: Config> Pallet<T> {
// remove any delegation votes to our current target.
Self::reduce_upstream_delegation(&target, conviction.votes(balance));
voting.set_common(delegations, prior);
}
},
Voting::Direct { votes, delegations, prior } => {
// here we just ensure that we're currently idling with no votes recorded.
ensure!(votes.is_empty(), Error::<T>::VotesExist);
voting.set_common(delegations, prior);
}
},
}
let votes = Self::increase_upstream_delegation(&target, conviction.votes(balance));
// Extend the lock to `balance` (rather than setting it) since we don't know what other
// votes are in place.
T::Currency::extend_lock(
DEMOCRACY_ID,
&who,
balance,
WithdrawReasons::TRANSFER
);
T::Currency::extend_lock(DEMOCRACY_ID, &who, balance, WithdrawReasons::TRANSFER);
Ok(votes)
})?;
Self::deposit_event(Event::<T>::Delegated(who, target));
@@ -1535,25 +1553,18 @@ impl<T: Config> Pallet<T> {
let mut old = Voting::default();
sp_std::mem::swap(&mut old, voting);
match old {
Voting::Delegating {
balance,
target,
conviction,
delegations,
mut prior,
} => {
Voting::Delegating { balance, target, conviction, delegations, mut prior } => {
// remove any delegation votes to our current target.
let votes = Self::reduce_upstream_delegation(&target, conviction.votes(balance));
let votes =
Self::reduce_upstream_delegation(&target, conviction.votes(balance));
let now = frame_system::Pallet::<T>::block_number();
let lock_periods = conviction.lock_periods().into();
prior.accumulate(now + T::EnactmentPeriod::get() * lock_periods, balance);
voting.set_common(delegations, prior);
Ok(votes)
}
Voting::Direct { .. } => {
Err(Error::<T>::NotDelegating.into())
}
},
Voting::Direct { .. } => Err(Error::<T>::NotDelegating.into()),
}
})?;
Self::deposit_event(Event::<T>::Undelegated(who));
@@ -1583,7 +1594,8 @@ impl<T: Config> Pallet<T> {
) -> ReferendumIndex {
let ref_index = Self::referendum_count();
ReferendumCount::<T>::put(ref_index + 1);
let status = ReferendumStatus { end, proposal_hash, threshold, delay, tally: Default::default() };
let status =
ReferendumStatus { end, proposal_hash, threshold, delay, tally: Default::default() };
let item = ReferendumInfo::Ongoing(status);
<ReferendumInfoOf<T>>::insert(ref_index, item);
Self::deposit_event(Event::<T>::Started(ref_index, threshold));
@@ -1596,7 +1608,8 @@ impl<T: Config> Pallet<T> {
Self::launch_public(now).or_else(|_| Self::launch_external(now))
} else {
Self::launch_external(now).or_else(|_| Self::launch_public(now))
}.map_err(|_| Error::<T>::NoneWaiting.into())
}
.map_err(|_| Error::<T>::NoneWaiting.into())
}
/// Table the waiting external proposal for a vote, if there is one.
@@ -1654,8 +1667,10 @@ impl<T: Config> Pallet<T> {
debug_assert!(err_amount.is_zero());
Self::deposit_event(Event::<T>::PreimageUsed(proposal_hash, provider, deposit));
let res = proposal.dispatch(frame_system::RawOrigin::Root.into())
.map(|_| ()).map_err(|e| e.error);
let res = proposal
.dispatch(frame_system::RawOrigin::Root.into())
.map(|_| ())
.map_err(|e| e.error);
Self::deposit_event(Event::<T>::Executed(index, res));
Ok(())
@@ -1685,10 +1700,14 @@ impl<T: Config> Pallet<T> {
} else {
let when = now + status.delay;
// Note that we need the preimage now.
Preimages::<T>::mutate_exists(&status.proposal_hash, |maybe_pre| match *maybe_pre {
Some(PreimageStatus::Available { ref mut expiry, .. }) => *expiry = Some(when),
ref mut a => *a = Some(PreimageStatus::Missing(when)),
});
Preimages::<T>::mutate_exists(
&status.proposal_hash,
|maybe_pre| match *maybe_pre {
Some(PreimageStatus::Available { ref mut expiry, .. }) =>
*expiry = Some(when),
ref mut a => *a = Some(PreimageStatus::Missing(when)),
},
);
if T::Scheduler::schedule_named(
(DEMOCRACY_ID, index).encode(),
@@ -1697,7 +1716,9 @@ impl<T: Config> Pallet<T> {
63,
frame_system::RawOrigin::Root.into(),
Call::enact_proposal(status.proposal_hash, index).into(),
).is_err() {
)
.is_err()
{
frame_support::print("LOGIC ERROR: bake_referendum/schedule_named failed");
}
}
@@ -1762,7 +1783,8 @@ impl<T: Config> Pallet<T> {
// To decode the enum variant we only need the first byte.
let mut buf = [0u8; 1];
let key = <Preimages<T>>::hashed_key_for(proposal_hash);
let bytes = sp_io::storage::read(&key, &mut buf, 0).ok_or_else(|| Error::<T>::NotImminent)?;
let bytes =
sp_io::storage::read(&key, &mut buf, 0).ok_or_else(|| Error::<T>::NotImminent)?;
// The value may be smaller that 1 byte.
let mut input = &buf[0..buf.len().min(bytes as usize)];
@@ -1772,7 +1794,7 @@ impl<T: Config> Pallet<T> {
_ => {
sp_runtime::print("Failed to decode `PreimageStatus` variant");
Err(Error::<T>::NotImminent.into())
}
},
}
}
@@ -1790,7 +1812,8 @@ impl<T: Config> Pallet<T> {
// * at most 5 bytes to decode a `Compact<u32>`
let mut buf = [0u8; 6];
let key = <Preimages<T>>::hashed_key_for(proposal_hash);
let bytes = sp_io::storage::read(&key, &mut buf, 0).ok_or_else(|| Error::<T>::PreimageMissing)?;
let bytes =
sp_io::storage::read(&key, &mut buf, 0).ok_or_else(|| Error::<T>::PreimageMissing)?;
// The value may be smaller that 6 bytes.
let mut input = &buf[0..buf.len().min(bytes as usize)];
@@ -1799,15 +1822,17 @@ impl<T: Config> Pallet<T> {
Ok(0) => return Err(Error::<T>::PreimageMissing.into()),
_ => {
sp_runtime::print("Failed to decode `PreimageStatus` variant");
return Err(Error::<T>::PreimageMissing.into());
}
return Err(Error::<T>::PreimageMissing.into())
},
}
// Decode the length of the vector.
let len = codec::Compact::<u32>::decode(&mut input).map_err(|_| {
sp_runtime::print("Failed to decode `PreimageStatus` variant");
DispatchError::from(Error::<T>::PreimageMissing)
})?.0;
let len = codec::Compact::<u32>::decode(&mut input)
.map_err(|_| {
sp_runtime::print("Failed to decode `PreimageStatus` variant");
DispatchError::from(Error::<T>::PreimageMissing)
})?
.0;
Ok(len)
}
@@ -1837,7 +1862,10 @@ impl<T: Config> Pallet<T> {
}
// See `note_imminent_preimage`
fn note_imminent_preimage_inner(who: T::AccountId, encoded_proposal: Vec<u8>) -> DispatchResult {
fn note_imminent_preimage_inner(
who: T::AccountId,
encoded_proposal: Vec<u8>,
) -> DispatchResult {
let proposal_hash = T::Hashing::hash(&encoded_proposal[..]);
Self::check_pre_image_is_missing(proposal_hash)?;
let status = Preimages::<T>::get(&proposal_hash).ok_or(Error::<T>::NotImminent)?;
@@ -1873,6 +1901,6 @@ fn decode_compact_u32_at(key: &[u8]) -> Option<u32> {
sp_runtime::print("Failed to decode compact u32 at:");
sp_runtime::print(key);
None
}
},
}
}
+18 -21
View File
@@ -17,23 +17,25 @@
//! The crate's tests.
use crate as pallet_democracy;
use super::*;
use crate as pallet_democracy;
use codec::Encode;
use frame_support::{
assert_noop, assert_ok, parameter_types, ord_parameter_types,
traits::{SortedMembers, OnInitialize, Filter, GenesisBuild},
assert_noop, assert_ok, ord_parameter_types, parameter_types,
traits::{Filter, GenesisBuild, OnInitialize, SortedMembers},
weights::Weight,
};
use frame_system::{EnsureRoot, EnsureSignedBy};
use pallet_balances::{BalanceLock, Error as BalancesError};
use sp_core::H256;
use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup, BadOrigin},
testing::Header, Perbill,
testing::Header,
traits::{BadOrigin, BlakeTwo256, IdentityLookup},
Perbill,
};
use pallet_balances::{BalanceLock, Error as BalancesError};
use frame_system::{EnsureSignedBy, EnsureRoot};
mod cancellation;
mod decoders;
mod delegation;
mod external_proposing;
mod fast_tracking;
@@ -42,7 +44,6 @@ mod preimage;
mod public_proposals;
mod scheduling;
mod voting;
mod decoders;
const AYE: Vote = Vote { aye: true, conviction: Conviction::None };
const NAY: Vote = Vote { aye: false, conviction: Conviction::None };
@@ -194,10 +195,14 @@ impl Config for Test {
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
pallet_balances::GenesisConfig::<Test>{
pallet_balances::GenesisConfig::<Test> {
balances: vec![(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)],
}.assimilate_storage(&mut t).unwrap();
pallet_democracy::GenesisConfig::<Test>::default().assimilate_storage(&mut t).unwrap();
}
.assimilate_storage(&mut t)
.unwrap();
pallet_democracy::GenesisConfig::<Test>::default()
.assimilate_storage(&mut t)
.unwrap();
let mut ext = sp_io::TestExternalities::new(t);
ext.execute_with(|| System::set_block_number(1));
ext
@@ -246,19 +251,11 @@ fn set_balance_proposal_hash_and_note(value: u64) -> H256 {
}
fn propose_set_balance(who: u64, value: u64, delay: u64) -> DispatchResult {
Democracy::propose(
Origin::signed(who),
set_balance_proposal_hash(value),
delay,
)
Democracy::propose(Origin::signed(who), set_balance_proposal_hash(value), delay)
}
fn propose_set_balance_and_note(who: u64, value: u64, delay: u64) -> DispatchResult {
Democracy::propose(
Origin::signed(who),
set_balance_proposal_hash_and_note(value),
delay,
)
Democracy::propose(Origin::signed(who), set_balance_proposal_hash_and_note(value), delay)
}
fn next_block() {
@@ -26,7 +26,7 @@ fn cancel_referendum_should_work() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1)));
assert_ok!(Democracy::cancel_referendum(Origin::root(), r.into()));
@@ -67,7 +67,7 @@ fn emergency_cancel_should_work() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
2
2,
);
assert!(Democracy::referendum_status(r).is_ok());
@@ -81,7 +81,7 @@ fn emergency_cancel_should_work() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
2
2,
);
assert!(Democracy::referendum_status(r).is_ok());
assert_noop!(
@@ -66,7 +66,7 @@ fn pre_image() {
assert_noop!(Democracy::check_pre_image_is_missing(key), Error::<Test>::NotImminent);
for l in vec![0, 10, 100, 1000u32] {
let available = PreimageStatus::Available{
let available = PreimageStatus::Available {
data: (0..l).map(|i| i as u8).collect(),
provider: 0,
deposit: 0,
@@ -76,8 +76,10 @@ fn pre_image() {
Preimages::<Test>::insert(key, available);
assert_eq!(Democracy::pre_image_data_len(key), Ok(l));
assert_noop!(Democracy::check_pre_image_is_missing(key),
Error::<Test>::DuplicatePreimage);
assert_noop!(
Democracy::check_pre_image_is_missing(key),
Error::<Test>::DuplicatePreimage
);
}
})
}
@@ -34,17 +34,17 @@ fn veto_external_works() {
// cancelled.
assert!(!<NextExternal<Test>>::exists());
// fails - same proposal can't be resubmitted.
assert_noop!(Democracy::external_propose(
Origin::signed(2),
set_balance_proposal_hash(2),
), Error::<Test>::ProposalBlacklisted);
assert_noop!(
Democracy::external_propose(Origin::signed(2), set_balance_proposal_hash(2),),
Error::<Test>::ProposalBlacklisted
);
fast_forward_to(1);
// fails as we're still in cooloff period.
assert_noop!(Democracy::external_propose(
Origin::signed(2),
set_balance_proposal_hash(2),
), Error::<Test>::ProposalBlacklisted);
assert_noop!(
Democracy::external_propose(Origin::signed(2), set_balance_proposal_hash(2),),
Error::<Test>::ProposalBlacklisted
);
fast_forward_to(2);
// works; as we're out of the cooloff period.
@@ -67,10 +67,10 @@ fn veto_external_works() {
fast_forward_to(3);
// same proposal fails as we're still in cooloff
assert_noop!(Democracy::external_propose(
Origin::signed(2),
set_balance_proposal_hash(2),
), Error::<Test>::ProposalBlacklisted);
assert_noop!(
Democracy::external_propose(Origin::signed(2), set_balance_proposal_hash(2),),
Error::<Test>::ProposalBlacklisted
);
// different proposal works fine.
assert_ok!(Democracy::external_propose(
Origin::signed(2),
@@ -96,10 +96,7 @@ fn external_blacklisting_should_work() {
assert_noop!(Democracy::referendum_status(0), Error::<Test>::ReferendumInvalid);
assert_noop!(
Democracy::external_propose(
Origin::signed(2),
set_balance_proposal_hash_and_note(2),
),
Democracy::external_propose(Origin::signed(2), set_balance_proposal_hash_and_note(2),),
Error::<Test>::ProposalBlacklisted,
);
});
@@ -110,20 +107,17 @@ fn external_referendum_works() {
new_test_ext().execute_with(|| {
System::set_block_number(0);
assert_noop!(
Democracy::external_propose(
Origin::signed(1),
set_balance_proposal_hash(2),
),
Democracy::external_propose(Origin::signed(1), set_balance_proposal_hash(2),),
BadOrigin,
);
assert_ok!(Democracy::external_propose(
Origin::signed(2),
set_balance_proposal_hash_and_note(2),
));
assert_noop!(Democracy::external_propose(
Origin::signed(2),
set_balance_proposal_hash(1),
), Error::<Test>::DuplicateProposal);
assert_noop!(
Democracy::external_propose(Origin::signed(2), set_balance_proposal_hash(1),),
Error::<Test>::DuplicateProposal
);
fast_forward_to(2);
assert_eq!(
Democracy::referendum_status(0),
@@ -143,10 +137,7 @@ fn external_majority_referendum_works() {
new_test_ext().execute_with(|| {
System::set_block_number(0);
assert_noop!(
Democracy::external_propose_majority(
Origin::signed(1),
set_balance_proposal_hash(2)
),
Democracy::external_propose_majority(Origin::signed(1), set_balance_proposal_hash(2)),
BadOrigin,
);
assert_ok!(Democracy::external_propose_majority(
@@ -172,10 +163,7 @@ fn external_default_referendum_works() {
new_test_ext().execute_with(|| {
System::set_block_number(0);
assert_noop!(
Democracy::external_propose_default(
Origin::signed(3),
set_balance_proposal_hash(2)
),
Democracy::external_propose_default(Origin::signed(3), set_balance_proposal_hash(2)),
BadOrigin,
);
assert_ok!(Democracy::external_propose_default(
@@ -196,7 +184,6 @@ fn external_default_referendum_works() {
});
}
#[test]
fn external_and_public_interleaving_works() {
new_test_ext().execute_with(|| {
@@ -222,9 +209,9 @@ fn external_and_public_interleaving_works() {
);
// replenish external
assert_ok!(Democracy::external_propose(
Origin::signed(2),
set_balance_proposal_hash_and_note(3),
));
Origin::signed(2),
set_balance_proposal_hash_and_note(3),
));
fast_forward_to(4);
@@ -256,9 +243,9 @@ fn external_and_public_interleaving_works() {
);
// replenish external
assert_ok!(Democracy::external_propose(
Origin::signed(2),
set_balance_proposal_hash_and_note(5),
));
Origin::signed(2),
set_balance_proposal_hash_and_note(5),
));
fast_forward_to(8);
@@ -24,7 +24,10 @@ fn fast_track_referendum_works() {
new_test_ext().execute_with(|| {
System::set_block_number(0);
let h = set_balance_proposal_hash_and_note(2);
assert_noop!(Democracy::fast_track(Origin::signed(5), h, 3, 2), Error::<Test>::ProposalMissing);
assert_noop!(
Democracy::fast_track(Origin::signed(5), h, 3, 2),
Error::<Test>::ProposalMissing
);
assert_ok!(Democracy::external_propose_majority(
Origin::signed(3),
set_balance_proposal_hash_and_note(2)
@@ -49,14 +52,20 @@ fn instant_referendum_works() {
new_test_ext().execute_with(|| {
System::set_block_number(0);
let h = set_balance_proposal_hash_and_note(2);
assert_noop!(Democracy::fast_track(Origin::signed(5), h, 3, 2), Error::<Test>::ProposalMissing);
assert_noop!(
Democracy::fast_track(Origin::signed(5), h, 3, 2),
Error::<Test>::ProposalMissing
);
assert_ok!(Democracy::external_propose_majority(
Origin::signed(3),
set_balance_proposal_hash_and_note(2)
));
assert_noop!(Democracy::fast_track(Origin::signed(1), h, 3, 2), BadOrigin);
assert_noop!(Democracy::fast_track(Origin::signed(5), h, 1, 0), BadOrigin);
assert_noop!(Democracy::fast_track(Origin::signed(6), h, 1, 0), Error::<Test>::InstantNotAllowed);
assert_noop!(
Democracy::fast_track(Origin::signed(6), h, 1, 0),
Error::<Test>::InstantNotAllowed
);
INSTANT_ALLOWED.with(|v| *v.borrow_mut() = true);
assert_ok!(Democracy::fast_track(Origin::signed(6), h, 1, 0));
assert_eq!(
@@ -23,23 +23,19 @@ use std::convert::TryFrom;
fn aye(x: u8, balance: u64) -> AccountVote<u64> {
AccountVote::Standard {
vote: Vote { aye: true, conviction: Conviction::try_from(x).unwrap() },
balance
balance,
}
}
fn nay(x: u8, balance: u64) -> AccountVote<u64> {
AccountVote::Standard {
vote: Vote { aye: false, conviction: Conviction::try_from(x).unwrap() },
balance
balance,
}
}
fn the_lock(amount: u64) -> BalanceLock<u64> {
BalanceLock {
id: DEMOCRACY_ID,
amount,
reasons: pallet_balances::Reasons::Misc,
}
BalanceLock { id: DEMOCRACY_ID, amount, reasons: pallet_balances::Reasons::Misc }
}
#[test]
@@ -50,7 +46,7 @@ fn lock_voting_should_work() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(1), r, nay(5, 10)));
assert_ok!(Democracy::vote(Origin::signed(2), r, aye(4, 20)));
@@ -74,7 +70,10 @@ fn lock_voting_should_work() {
assert_ok!(Democracy::unlock(Origin::signed(2), 5));
// 2, 3, 4 got their way with the vote, so they cannot be reaped by others.
assert_noop!(Democracy::remove_other_vote(Origin::signed(1), 2, r), Error::<Test>::NoPermission);
assert_noop!(
Democracy::remove_other_vote(Origin::signed(1), 2, r),
Error::<Test>::NoPermission
);
// However, they can be unvoted by the owner, though it will make no difference to the lock.
assert_ok!(Democracy::remove_vote(Origin::signed(2), r));
assert_ok!(Democracy::unlock(Origin::signed(2), 2));
@@ -86,10 +85,12 @@ fn lock_voting_should_work() {
assert_eq!(Balances::locks(5), vec![]);
assert_eq!(Balances::free_balance(42), 2);
fast_forward_to(5);
// No change yet...
assert_noop!(Democracy::remove_other_vote(Origin::signed(1), 4, r), Error::<Test>::NoPermission);
assert_noop!(
Democracy::remove_other_vote(Origin::signed(1), 4, r),
Error::<Test>::NoPermission
);
assert_ok!(Democracy::unlock(Origin::signed(1), 4));
assert_eq!(Balances::locks(4), vec![the_lock(40)]);
fast_forward_to(6);
@@ -99,7 +100,10 @@ fn lock_voting_should_work() {
assert_eq!(Balances::locks(4), vec![]);
fast_forward_to(9);
assert_noop!(Democracy::remove_other_vote(Origin::signed(1), 3, r), Error::<Test>::NoPermission);
assert_noop!(
Democracy::remove_other_vote(Origin::signed(1), 3, r),
Error::<Test>::NoPermission
);
assert_ok!(Democracy::unlock(Origin::signed(1), 3));
assert_eq!(Balances::locks(3), vec![the_lock(30)]);
fast_forward_to(10);
@@ -145,7 +149,7 @@ fn lock_voting_should_work_with_delegation() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(1), r, nay(5, 10)));
assert_ok!(Democracy::vote(Origin::signed(2), r, aye(4, 20)));
@@ -168,7 +172,7 @@ fn setup_three_referenda() -> (u32, u32, u32) {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SimpleMajority,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(5), r1, aye(4, 10)));
@@ -176,7 +180,7 @@ fn setup_three_referenda() -> (u32, u32, u32) {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SimpleMajority,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(5), r2, aye(3, 20)));
@@ -184,7 +188,7 @@ fn setup_three_referenda() -> (u32, u32, u32) {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SimpleMajority,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(5), r3, aye(2, 50)));
@@ -202,7 +206,10 @@ fn prior_lockvotes_should_be_enforced() {
// r.2 locked 50 until #6.
fast_forward_to(5);
assert_noop!(Democracy::remove_other_vote(Origin::signed(1), 5, r.2), Error::<Test>::NoPermission);
assert_noop!(
Democracy::remove_other_vote(Origin::signed(1), 5, r.2),
Error::<Test>::NoPermission
);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(50)]);
fast_forward_to(6);
@@ -210,7 +217,10 @@ fn prior_lockvotes_should_be_enforced() {
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(20)]);
fast_forward_to(9);
assert_noop!(Democracy::remove_other_vote(Origin::signed(1), 5, r.1), Error::<Test>::NoPermission);
assert_noop!(
Democracy::remove_other_vote(Origin::signed(1), 5, r.1),
Error::<Test>::NoPermission
);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(20)]);
fast_forward_to(10);
@@ -218,7 +228,10 @@ fn prior_lockvotes_should_be_enforced() {
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(10)]);
fast_forward_to(17);
assert_noop!(Democracy::remove_other_vote(Origin::signed(1), 5, r.0), Error::<Test>::NoPermission);
assert_noop!(
Democracy::remove_other_vote(Origin::signed(1), 5, r.0),
Error::<Test>::NoPermission
);
assert_ok!(Democracy::unlock(Origin::signed(5), 5));
assert_eq!(Balances::locks(5), vec![the_lock(10)]);
fast_forward_to(18);
@@ -296,7 +309,7 @@ fn locks_should_persist_from_voting_to_delegation() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SimpleMajority,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(5), r, aye(4, 10)));
fast_forward_to(2);
+47 -25
View File
@@ -26,7 +26,7 @@ fn missing_preimage_should_fail() {
2,
set_balance_proposal_hash(2),
VoteThreshold::SuperMajorityApprove,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1)));
@@ -43,8 +43,11 @@ fn preimage_deposit_should_be_required_and_returned() {
// fee of 100 is too much.
PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 100);
assert_noop!(
if operational { Democracy::note_preimage_operational(Origin::signed(6), vec![0; 500]) }
else { Democracy::note_preimage(Origin::signed(6), vec![0; 500]) },
if operational {
Democracy::note_preimage_operational(Origin::signed(6), vec![0; 500])
} else {
Democracy::note_preimage(Origin::signed(6), vec![0; 500])
},
BalancesError::<Test, _>::InsufficientBalance,
);
// fee of 1 is reasonable.
@@ -53,7 +56,7 @@ fn preimage_deposit_should_be_required_and_returned() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1)));
@@ -72,10 +75,11 @@ fn preimage_deposit_should_be_required_and_returned() {
fn preimage_deposit_should_be_reapable_earlier_by_owner() {
new_test_ext_execute_with_cond(|operational| {
PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1);
assert_ok!(
if operational { Democracy::note_preimage_operational(Origin::signed(6), set_balance_proposal(2)) }
else { Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2)) }
);
assert_ok!(if operational {
Democracy::note_preimage_operational(Origin::signed(6), set_balance_proposal(2))
} else {
Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2))
});
assert_eq!(Balances::reserved_balance(6), 12);
@@ -85,7 +89,11 @@ fn preimage_deposit_should_be_reapable_earlier_by_owner() {
Error::<Test>::TooEarly
);
next_block();
assert_ok!(Democracy::reap_preimage(Origin::signed(6), set_balance_proposal_hash(2), u32::MAX));
assert_ok!(Democracy::reap_preimage(
Origin::signed(6),
set_balance_proposal_hash(2),
u32::MAX
));
assert_eq!(Balances::free_balance(6), 60);
assert_eq!(Balances::reserved_balance(6), 0);
@@ -96,27 +104,32 @@ fn preimage_deposit_should_be_reapable_earlier_by_owner() {
fn preimage_deposit_should_be_reapable() {
new_test_ext_execute_with_cond(|operational| {
assert_noop!(
Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2), u32::MAX),
Error::<Test>::PreimageMissing
);
Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2), u32::MAX),
Error::<Test>::PreimageMissing
);
PREIMAGE_BYTE_DEPOSIT.with(|v| *v.borrow_mut() = 1);
assert_ok!(
if operational { Democracy::note_preimage_operational(Origin::signed(6), set_balance_proposal(2)) }
else { Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2)) }
);
assert_ok!(if operational {
Democracy::note_preimage_operational(Origin::signed(6), set_balance_proposal(2))
} else {
Democracy::note_preimage(Origin::signed(6), set_balance_proposal(2))
});
assert_eq!(Balances::reserved_balance(6), 12);
next_block();
next_block();
next_block();
assert_noop!(
Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2), u32::MAX),
Error::<Test>::TooEarly
);
Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2), u32::MAX),
Error::<Test>::TooEarly
);
next_block();
assert_ok!(Democracy::reap_preimage(Origin::signed(5), set_balance_proposal_hash(2), u32::MAX));
assert_ok!(Democracy::reap_preimage(
Origin::signed(5),
set_balance_proposal_hash(2),
u32::MAX
));
assert_eq!(Balances::reserved_balance(6), 0);
assert_eq!(Balances::free_balance(6), 48);
assert_eq!(Balances::free_balance(5), 62);
@@ -132,13 +145,19 @@ fn noting_imminent_preimage_for_free_should_work() {
2,
set_balance_proposal_hash(2),
VoteThreshold::SuperMajorityApprove,
1
1,
);
assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1)));
assert_noop!(
if operational { Democracy::note_imminent_preimage_operational(Origin::signed(6), set_balance_proposal(2)) }
else { Democracy::note_imminent_preimage(Origin::signed(6), set_balance_proposal(2)) },
if operational {
Democracy::note_imminent_preimage_operational(
Origin::signed(6),
set_balance_proposal(2),
)
} else {
Democracy::note_imminent_preimage(Origin::signed(6), set_balance_proposal(2))
},
Error::<Test>::NotImminent
);
@@ -161,7 +180,10 @@ fn reaping_imminent_preimage_should_fail() {
assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1)));
next_block();
next_block();
assert_noop!(Democracy::reap_preimage(Origin::signed(6), h, u32::MAX), Error::<Test>::Imminent);
assert_noop!(
Democracy::reap_preimage(Origin::signed(6), h, u32::MAX),
Error::<Test>::Imminent
);
});
}
@@ -174,7 +196,7 @@ fn note_imminent_preimage_can_only_be_successful_once() {
2,
set_balance_proposal_hash(2),
VoteThreshold::SuperMajorityApprove,
1
1,
);
assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1)));
next_block();
@@ -89,10 +89,7 @@ fn poor_seconder_should_not_work() {
fn invalid_seconds_upper_bound_should_not_work() {
new_test_ext().execute_with(|| {
assert_ok!(propose_set_balance_and_note(1, 2, 5));
assert_noop!(
Democracy::second(Origin::signed(2), 0, 0),
Error::<Test>::WrongUpperBound
);
assert_noop!(Democracy::second(Origin::signed(2), 0, 0), Error::<Test>::WrongUpperBound);
});
}
@@ -26,7 +26,7 @@ fn simple_passing_should_work() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1)));
assert_eq!(tally(r), Tally { ayes: 1, nays: 0, turnout: 10 });
@@ -43,7 +43,7 @@ fn simple_failing_should_work() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(1), r, nay(1)));
assert_eq!(tally(r), Tally { ayes: 0, nays: 1, turnout: 10 });
@@ -62,13 +62,13 @@ fn ooo_inject_referendums_should_work() {
3,
set_balance_proposal_hash_and_note(3),
VoteThreshold::SuperMajorityApprove,
0
0,
);
let r2 = Democracy::inject_referendum(
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(1), r2, aye(1)));
@@ -92,7 +92,7 @@ fn delayed_enactment_should_work() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
1
1,
);
assert_ok!(Democracy::vote(Origin::signed(1), r, aye(1)));
assert_ok!(Democracy::vote(Origin::signed(2), r, aye(2)));
@@ -23,7 +23,10 @@ use super::*;
fn overvoting_should_fail() {
new_test_ext().execute_with(|| {
let r = begin_referendum();
assert_noop!(Democracy::vote(Origin::signed(1), r, aye(2)), Error::<Test>::InsufficientFunds);
assert_noop!(
Democracy::vote(Origin::signed(1), r, aye(2)),
Error::<Test>::InsufficientFunds
);
});
}
@@ -102,7 +105,7 @@ fn controversial_voting_should_work() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(1), r, big_aye(1)));
@@ -128,7 +131,7 @@ fn controversial_low_turnout_voting_should_work() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(5), r, big_nay(5)));
assert_ok!(Democracy::vote(Origin::signed(6), r, big_aye(6)));
@@ -152,7 +155,7 @@ fn passing_low_turnout_voting_should_work() {
2,
set_balance_proposal_hash_and_note(2),
VoteThreshold::SuperMajorityApprove,
0
0,
);
assert_ok!(Democracy::vote(Origin::signed(4), r, big_aye(4)));
assert_ok!(Democracy::vote(Origin::signed(5), r, big_nay(5)));
+37 -39
View File
@@ -17,29 +17,31 @@
//! Miscellaneous additional datatypes.
use codec::{Encode, Decode};
use sp_runtime::RuntimeDebug;
use sp_runtime::traits::{Zero, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, Saturating};
use crate::{Vote, VoteThreshold, AccountVote, Conviction};
use crate::{AccountVote, Conviction, Vote, VoteThreshold};
use codec::{Decode, Encode};
use sp_runtime::{
traits::{Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, Saturating, Zero},
RuntimeDebug,
};
/// Info regarding an ongoing referendum.
#[derive(Encode, Decode, Default, Clone, PartialEq, Eq, RuntimeDebug)]
pub struct Tally<Balance> {
/// The number of aye votes, expressed in terms of post-conviction lock-vote.
pub (crate) ayes: Balance,
pub(crate) ayes: Balance,
/// The number of nay votes, expressed in terms of post-conviction lock-vote.
pub (crate) nays: Balance,
pub(crate) nays: Balance,
/// The amount of funds currently expressing its opinion. Pre-conviction.
pub (crate) turnout: Balance,
pub(crate) turnout: Balance,
}
/// Amount of votes and capital placed in delegation for an account.
#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq, RuntimeDebug)]
pub struct Delegations<Balance> {
/// The number of votes (this is post-conviction).
pub (crate) votes: Balance,
pub(crate) votes: Balance,
/// The amount of raw capital, used for the turnout.
pub (crate) capital: Balance,
pub(crate) capital: Balance,
}
impl<Balance: Saturating> Saturating for Delegations<Balance> {
@@ -65,22 +67,24 @@ impl<Balance: Saturating> Saturating for Delegations<Balance> {
}
fn saturating_pow(self, exp: usize) -> Self {
Self {
votes: self.votes.saturating_pow(exp),
capital: self.capital.saturating_pow(exp),
}
Self { votes: self.votes.saturating_pow(exp), capital: self.capital.saturating_pow(exp) }
}
}
impl<
Balance: From<u8> + Zero + Copy + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + Bounded +
Saturating
> Tally<Balance> {
Balance: From<u8>
+ Zero
+ Copy
+ CheckedAdd
+ CheckedSub
+ CheckedMul
+ CheckedDiv
+ Bounded
+ Saturating,
> Tally<Balance>
{
/// Create a new tally.
pub fn new(
vote: Vote,
balance: Balance,
) -> Self {
pub fn new(vote: Vote, balance: Balance) -> Self {
let Delegations { votes, capital } = vote.conviction.votes(balance);
Self {
ayes: if vote.aye { votes } else { Zero::zero() },
@@ -90,10 +94,7 @@ impl<
}
/// Add an account's vote into the tally.
pub fn add(
&mut self,
vote: AccountVote<Balance>,
) -> Option<()> {
pub fn add(&mut self, vote: AccountVote<Balance>) -> Option<()> {
match vote {
AccountVote::Standard { vote, balance } => {
let Delegations { votes, capital } = vote.conviction.votes(balance);
@@ -102,23 +103,20 @@ impl<
true => self.ayes = self.ayes.checked_add(&votes)?,
false => self.nays = self.nays.checked_add(&votes)?,
}
}
},
AccountVote::Split { aye, nay } => {
let aye = Conviction::None.votes(aye);
let nay = Conviction::None.votes(nay);
self.turnout = self.turnout.checked_add(&aye.capital)?.checked_add(&nay.capital)?;
self.ayes = self.ayes.checked_add(&aye.votes)?;
self.nays = self.nays.checked_add(&nay.votes)?;
}
},
}
Some(())
}
/// Remove an account's vote from the tally.
pub fn remove(
&mut self,
vote: AccountVote<Balance>,
) -> Option<()> {
pub fn remove(&mut self, vote: AccountVote<Balance>) -> Option<()> {
match vote {
AccountVote::Standard { vote, balance } => {
let Delegations { votes, capital } = vote.conviction.votes(balance);
@@ -127,14 +125,14 @@ impl<
true => self.ayes = self.ayes.checked_sub(&votes)?,
false => self.nays = self.nays.checked_sub(&votes)?,
}
}
},
AccountVote::Split { aye, nay } => {
let aye = Conviction::None.votes(aye);
let nay = Conviction::None.votes(nay);
self.turnout = self.turnout.checked_sub(&aye.capital)?.checked_sub(&nay.capital)?;
self.ayes = self.ayes.checked_sub(&aye.votes)?;
self.nays = self.nays.checked_sub(&nay.votes)?;
}
},
}
Some(())
}
@@ -164,15 +162,15 @@ impl<
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)]
pub struct ReferendumStatus<BlockNumber, Hash, Balance> {
/// When voting on this referendum will end.
pub (crate) end: BlockNumber,
pub(crate) end: BlockNumber,
/// The hash of the proposal being voted on.
pub (crate) proposal_hash: Hash,
pub(crate) proposal_hash: Hash,
/// The thresholding mechanism to determine whether it passed.
pub (crate) threshold: VoteThreshold,
pub(crate) threshold: VoteThreshold,
/// The delay (in blocks) to wait after a successful referendum before deploying.
pub (crate) delay: BlockNumber,
pub(crate) delay: BlockNumber,
/// The current tally of votes in this referendum.
pub (crate) tally: Tally<Balance>,
pub(crate) tally: Tally<Balance>,
}
/// Info regarding a referendum, present or past.
@@ -181,7 +179,7 @@ pub enum ReferendumInfo<BlockNumber, Hash, Balance> {
/// Referendum is happening, the arg is the block number at which it will end.
Ongoing(ReferendumStatus<BlockNumber, Hash, Balance>),
/// Referendum finished at `end`, and has been `approved` or rejected.
Finished{approved: bool, end: BlockNumber},
Finished { approved: bool, end: BlockNumber },
}
impl<BlockNumber, Hash, Balance: Default> ReferendumInfo<BlockNumber, Hash, Balance> {
@@ -192,7 +190,7 @@ impl<BlockNumber, Hash, Balance: Default> ReferendumInfo<BlockNumber, Hash, Bala
threshold: VoteThreshold,
delay: BlockNumber,
) -> Self {
let s = ReferendumStatus{ end, proposal_hash, threshold, delay, tally: Tally::default() };
let s = ReferendumStatus { end, proposal_hash, threshold, delay, tally: Tally::default() };
ReferendumInfo::Ongoing(s)
}
}
+20 -16
View File
@@ -17,10 +17,13 @@
//! The vote datatype.
use sp_std::{prelude::*, result::Result, convert::TryFrom};
use codec::{Encode, EncodeLike, Decode, Output, Input};
use sp_runtime::{RuntimeDebug, traits::{Saturating, Zero}};
use crate::{Conviction, ReferendumIndex, Delegations};
use crate::{Conviction, Delegations, ReferendumIndex};
use codec::{Decode, Encode, EncodeLike, Input, Output};
use sp_runtime::{
traits::{Saturating, Zero},
RuntimeDebug,
};
use sp_std::{convert::TryFrom, prelude::*, result::Result};
/// A number of lock periods, plus a vote, one way or the other.
#[derive(Copy, Clone, Eq, PartialEq, Default, RuntimeDebug)]
@@ -136,7 +139,9 @@ pub enum Voting<Balance, AccountId, BlockNumber> {
},
}
impl<Balance: Default, AccountId, BlockNumber: Zero> Default for Voting<Balance, AccountId, BlockNumber> {
impl<Balance: Default, AccountId, BlockNumber: Zero> Default
for Voting<Balance, AccountId, BlockNumber>
{
fn default() -> Self {
Voting::Direct {
votes: Vec::new(),
@@ -146,31 +151,30 @@ impl<Balance: Default, AccountId, BlockNumber: Zero> Default for Voting<Balance,
}
}
impl<
Balance: Saturating + Ord + Zero + Copy,
BlockNumber: Ord + Copy + Zero,
AccountId,
> Voting<Balance, AccountId, BlockNumber> {
impl<Balance: Saturating + Ord + Zero + Copy, BlockNumber: Ord + Copy + Zero, AccountId>
Voting<Balance, AccountId, BlockNumber>
{
pub fn rejig(&mut self, now: BlockNumber) {
match self {
Voting::Direct { prior, .. } => prior,
Voting::Delegating { prior, .. } => prior,
}.rejig(now);
}
.rejig(now);
}
/// The amount of this account's balance that much currently be locked due to voting.
pub fn locked_balance(&self) -> Balance {
match self {
Voting::Direct { votes, prior, .. } => votes.iter()
.map(|i| i.1.balance())
.fold(prior.locked(), |a, i| a.max(i)),
Voting::Direct { votes, prior, .. } =>
votes.iter().map(|i| i.1.balance()).fold(prior.locked(), |a, i| a.max(i)),
Voting::Delegating { balance, .. } => *balance,
}
}
pub fn set_common(&mut self,
pub fn set_common(
&mut self,
delegations: Delegations<Balance>,
prior: PriorLock<BlockNumber, Balance>
prior: PriorLock<BlockNumber, Balance>,
) {
let (d, p) = match self {
Voting::Direct { ref mut delegations, ref mut prior, .. } => (delegations, prior),
+34 -17
View File
@@ -17,12 +17,12 @@
//! Voting thresholds.
#[cfg(feature = "std")]
use serde::{Serialize, Deserialize};
use codec::{Encode, Decode};
use sp_runtime::traits::{Zero, IntegerSquareRoot};
use sp_std::ops::{Add, Mul, Div, Rem};
use crate::Tally;
use codec::{Decode, Encode};
#[cfg(feature = "std")]
use serde::{Deserialize, Serialize};
use sp_runtime::traits::{IntegerSquareRoot, Zero};
use sp_std::ops::{Add, Div, Mul, Rem};
/// A means of determining if a vote is past pass threshold.
#[derive(Clone, Copy, PartialEq, Eq, Encode, Decode, sp_runtime::RuntimeDebug)]
@@ -43,25 +43,32 @@ pub trait Approved<Balance> {
}
/// Return `true` iff `n1 / d1 < n2 / d2`. `d1` and `d2` may not be zero.
fn compare_rationals<T: Zero + Mul<T, Output = T> + Div<T, Output = T> + Rem<T, Output = T> + Ord + Copy>(mut n1: T, mut d1: T, mut n2: T, mut d2: T) -> bool {
fn compare_rationals<
T: Zero + Mul<T, Output = T> + Div<T, Output = T> + Rem<T, Output = T> + Ord + Copy,
>(
mut n1: T,
mut d1: T,
mut n2: T,
mut d2: T,
) -> bool {
// Uses a continued fractional representation for a non-overflowing compare.
// Detailed at https://janmr.com/blog/2014/05/comparing-rational-numbers-without-overflow/.
loop {
let q1 = n1 / d1;
let q2 = n2 / d2;
if q1 < q2 {
return true;
return true
}
if q2 < q1 {
return false;
return false
}
let r1 = n1 % d1;
let r2 = n2 % d2;
if r2.is_zero() {
return false;
return false
}
if r1.is_zero() {
return true;
return true
}
n1 = d2;
n2 = d1;
@@ -71,14 +78,22 @@ fn compare_rationals<T: Zero + Mul<T, Output = T> + Div<T, Output = T> + Rem<T,
}
impl<
Balance: IntegerSquareRoot + Zero + Ord + Add<Balance, Output = Balance>
+ Mul<Balance, Output = Balance> + Div<Balance, Output = Balance>
+ Rem<Balance, Output = Balance> + Copy,
> Approved<Balance> for VoteThreshold {
Balance: IntegerSquareRoot
+ Zero
+ Ord
+ Add<Balance, Output = Balance>
+ Mul<Balance, Output = Balance>
+ Div<Balance, Output = Balance>
+ Rem<Balance, Output = Balance>
+ Copy,
> Approved<Balance> for VoteThreshold
{
fn approved(&self, tally: Tally<Balance>, electorate: Balance) -> bool {
let sqrt_voters = tally.turnout.integer_sqrt();
let sqrt_electorate = electorate.integer_sqrt();
if sqrt_voters.is_zero() { return false; }
if sqrt_voters.is_zero() {
return false
}
match *self {
VoteThreshold::SuperMajorityApprove =>
compare_rationals(tally.nays, sqrt_voters, tally.ayes, sqrt_electorate),
@@ -95,7 +110,9 @@ mod tests {
#[test]
fn should_work() {
assert!(!VoteThreshold::SuperMajorityApprove.approved(Tally{ayes: 60, nays: 50, turnout: 110}, 210));
assert!(VoteThreshold::SuperMajorityApprove.approved(Tally{ayes: 100, nays: 50, turnout: 150}, 210));
assert!(!VoteThreshold::SuperMajorityApprove
.approved(Tally { ayes: 60, nays: 50, turnout: 110 }, 210));
assert!(VoteThreshold::SuperMajorityApprove
.approved(Tally { ayes: 100, nays: 50, turnout: 150 }, 210));
}
}
+1
View File
@@ -36,6 +36,7 @@
// --template=./.maintain/frame-weight-template.hbs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]