add instantiable support for treasury pallet (#7058)

* add instantiable support for treasury pallet

* update treasury pallet benchmarking code to support multi-instance

* use benchmark_intance! macro; fix hard coded treasury identity string; fix over characters line width limitation error

* fix line return style
This commit is contained in:
Kerwin Zhu
2020-09-14 16:59:01 +08:00
committed by GitHub
parent 2348f03f0f
commit f9441b3ea5
3 changed files with 141 additions and 121 deletions
+42 -40
View File
@@ -22,7 +22,7 @@
use super::*; use super::*;
use frame_system::RawOrigin; use frame_system::RawOrigin;
use frame_benchmarking::{benchmarks, account, whitelisted_caller}; use frame_benchmarking::{benchmarks_instance, account, whitelisted_caller};
use frame_support::traits::OnInitialize; use frame_support::traits::OnInitialize;
use crate::Module as Treasury; use crate::Module as Treasury;
@@ -30,13 +30,13 @@ use crate::Module as Treasury;
const SEED: u32 = 0; const SEED: u32 = 0;
// Create the pre-requisite information needed to create a treasury `propose_spend`. // Create the pre-requisite information needed to create a treasury `propose_spend`.
fn setup_proposal<T: Trait>(u: u32) -> ( fn setup_proposal<T: Trait<I>, I: Instance>(u: u32) -> (
T::AccountId, T::AccountId,
BalanceOf<T>, BalanceOf<T, I>,
<T::Lookup as StaticLookup>::Source, <T::Lookup as StaticLookup>::Source,
) { ) {
let caller = account("caller", u, SEED); let caller = account("caller", u, SEED);
let value: BalanceOf<T> = T::ProposalBondMinimum::get().saturating_mul(100.into()); let value: BalanceOf<T, I> = T::ProposalBondMinimum::get().saturating_mul(100.into());
let _ = T::Currency::make_free_balance_be(&caller, value); let _ = T::Currency::make_free_balance_be(&caller, value);
let beneficiary = account("beneficiary", u, SEED); let beneficiary = account("beneficiary", u, SEED);
let beneficiary_lookup = T::Lookup::unlookup(beneficiary); let beneficiary_lookup = T::Lookup::unlookup(beneficiary);
@@ -44,7 +44,7 @@ fn setup_proposal<T: Trait>(u: u32) -> (
} }
// Create the pre-requisite information needed to create a `report_awesome`. // Create the pre-requisite information needed to create a `report_awesome`.
fn setup_awesome<T: Trait>(length: u32) -> (T::AccountId, Vec<u8>, T::AccountId) { fn setup_awesome<T: Trait<I>, I: Instance>(length: u32) -> (T::AccountId, Vec<u8>, T::AccountId) {
let caller = whitelisted_caller(); let caller = whitelisted_caller();
let value = T::TipReportDepositBase::get() let value = T::TipReportDepositBase::get()
+ T::TipReportDepositPerByte::get() * length.into() + T::TipReportDepositPerByte::get() * length.into()
@@ -56,8 +56,8 @@ fn setup_awesome<T: Trait>(length: u32) -> (T::AccountId, Vec<u8>, T::AccountId)
} }
// Create the pre-requisite information needed to call `tip_new`. // Create the pre-requisite information needed to call `tip_new`.
fn setup_tip<T: Trait>(r: u32, t: u32) -> fn setup_tip<T: Trait<I>, I: Instance>(r: u32, t: u32) ->
Result<(T::AccountId, Vec<u8>, T::AccountId, BalanceOf<T>), &'static str> Result<(T::AccountId, Vec<u8>, T::AccountId, BalanceOf<T, I>), &'static str>
{ {
let tippers_count = T::Tippers::count(); let tippers_count = T::Tippers::count();
@@ -77,13 +77,15 @@ fn setup_tip<T: Trait>(r: u32, t: u32) ->
// Create `t` new tips for the tip proposal with `hash`. // Create `t` new tips for the tip proposal with `hash`.
// This function automatically makes the tip able to close. // This function automatically makes the tip able to close.
fn create_tips<T: Trait>(t: u32, hash: T::Hash, value: BalanceOf<T>) -> Result<(), &'static str> { fn create_tips<T: Trait<I>, I: Instance>(t: u32, hash: T::Hash, value: BalanceOf<T, I>) ->
Result<(), &'static str>
{
for i in 0 .. t { for i in 0 .. t {
let caller = account("member", i, SEED); let caller = account("member", i, SEED);
ensure!(T::Tippers::contains(&caller), "caller is not a tipper"); ensure!(T::Tippers::contains(&caller), "caller is not a tipper");
Treasury::<T>::tip(RawOrigin::Signed(caller).into(), hash, value)?; Treasury::<T, I>::tip(RawOrigin::Signed(caller).into(), hash, value)?;
} }
Tips::<T>::mutate(hash, |maybe_tip| { Tips::<T, I>::mutate(hash, |maybe_tip| {
if let Some(open_tip) = maybe_tip { if let Some(open_tip) = maybe_tip {
open_tip.closes = Some(T::BlockNumber::zero()); open_tip.closes = Some(T::BlockNumber::zero());
} }
@@ -92,30 +94,30 @@ fn create_tips<T: Trait>(t: u32, hash: T::Hash, value: BalanceOf<T>) -> Result<(
} }
// Create proposals that are approved for use in `on_initialize`. // Create proposals that are approved for use in `on_initialize`.
fn create_approved_proposals<T: Trait>(n: u32) -> Result<(), &'static str> { fn create_approved_proposals<T: Trait<I>, I: Instance>(n: u32) -> Result<(), &'static str> {
for i in 0 .. n { for i in 0 .. n {
let (caller, value, lookup) = setup_proposal::<T>(i); let (caller, value, lookup) = setup_proposal::<T, I>(i);
Treasury::<T>::propose_spend( Treasury::<T, I>::propose_spend(
RawOrigin::Signed(caller).into(), RawOrigin::Signed(caller).into(),
value, value,
lookup lookup
)?; )?;
let proposal_id = ProposalCount::get() - 1; let proposal_id = <ProposalCount<I>>::get() - 1;
Treasury::<T>::approve_proposal(RawOrigin::Root.into(), proposal_id)?; Treasury::<T, I>::approve_proposal(RawOrigin::Root.into(), proposal_id)?;
} }
ensure!(Approvals::get().len() == n as usize, "Not all approved"); ensure!(<Approvals<I>>::get().len() == n as usize, "Not all approved");
Ok(()) Ok(())
} }
const MAX_BYTES: u32 = 16384; const MAX_BYTES: u32 = 16384;
const MAX_TIPPERS: u32 = 100; const MAX_TIPPERS: u32 = 100;
benchmarks! { benchmarks_instance! {
_ { } _ { }
propose_spend { propose_spend {
let u in 0 .. 1000; let u in 0 .. 1000;
let (caller, value, beneficiary_lookup) = setup_proposal::<T>(u); let (caller, value, beneficiary_lookup) = setup_proposal::<T, _>(u);
// Whitelist caller account from further DB operations. // Whitelist caller account from further DB operations.
let caller_key = frame_system::Account::<T>::hashed_key_for(&caller); let caller_key = frame_system::Account::<T>::hashed_key_for(&caller);
frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into());
@@ -123,29 +125,29 @@ benchmarks! {
reject_proposal { reject_proposal {
let u in 0 .. 1000; let u in 0 .. 1000;
let (caller, value, beneficiary_lookup) = setup_proposal::<T>(u); let (caller, value, beneficiary_lookup) = setup_proposal::<T, _>(u);
Treasury::<T>::propose_spend( Treasury::<T, _>::propose_spend(
RawOrigin::Signed(caller).into(), RawOrigin::Signed(caller).into(),
value, value,
beneficiary_lookup beneficiary_lookup
)?; )?;
let proposal_id = ProposalCount::get() - 1; let proposal_id = Treasury::<T, _>::proposal_count() - 1;
}: _(RawOrigin::Root, proposal_id) }: _(RawOrigin::Root, proposal_id)
approve_proposal { approve_proposal {
let u in 0 .. 1000; let u in 0 .. 1000;
let (caller, value, beneficiary_lookup) = setup_proposal::<T>(u); let (caller, value, beneficiary_lookup) = setup_proposal::<T, _>(u);
Treasury::<T>::propose_spend( Treasury::<T, _>::propose_spend(
RawOrigin::Signed(caller).into(), RawOrigin::Signed(caller).into(),
value, value,
beneficiary_lookup beneficiary_lookup
)?; )?;
let proposal_id = ProposalCount::get() - 1; let proposal_id = Treasury::<T, _>::proposal_count() - 1;
}: _(RawOrigin::Root, proposal_id) }: _(RawOrigin::Root, proposal_id)
report_awesome { report_awesome {
let r in 0 .. MAX_BYTES; let r in 0 .. MAX_BYTES;
let (caller, reason, awesome_person) = setup_awesome::<T>(r); let (caller, reason, awesome_person) = setup_awesome::<T, _>(r);
// Whitelist caller account from further DB operations. // Whitelist caller account from further DB operations.
let caller_key = frame_system::Account::<T>::hashed_key_for(&caller); let caller_key = frame_system::Account::<T>::hashed_key_for(&caller);
frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into());
@@ -153,8 +155,8 @@ benchmarks! {
retract_tip { retract_tip {
let r in 0 .. MAX_BYTES; let r in 0 .. MAX_BYTES;
let (caller, reason, awesome_person) = setup_awesome::<T>(r); let (caller, reason, awesome_person) = setup_awesome::<T, _>(r);
Treasury::<T>::report_awesome( Treasury::<T, _>::report_awesome(
RawOrigin::Signed(caller.clone()).into(), RawOrigin::Signed(caller.clone()).into(),
reason.clone(), reason.clone(),
awesome_person.clone() awesome_person.clone()
@@ -170,7 +172,7 @@ benchmarks! {
let r in 0 .. MAX_BYTES; let r in 0 .. MAX_BYTES;
let t in 1 .. MAX_TIPPERS; let t in 1 .. MAX_TIPPERS;
let (caller, reason, beneficiary, value) = setup_tip::<T>(r, t)?; let (caller, reason, beneficiary, value) = setup_tip::<T, _>(r, t)?;
// Whitelist caller account from further DB operations. // Whitelist caller account from further DB operations.
let caller_key = frame_system::Account::<T>::hashed_key_for(&caller); let caller_key = frame_system::Account::<T>::hashed_key_for(&caller);
frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into()); frame_benchmarking::benchmarking::add_to_whitelist(caller_key.into());
@@ -178,9 +180,9 @@ benchmarks! {
tip { tip {
let t in 1 .. MAX_TIPPERS; let t in 1 .. MAX_TIPPERS;
let (member, reason, beneficiary, value) = setup_tip::<T>(0, t)?; let (member, reason, beneficiary, value) = setup_tip::<T, _>(0, t)?;
let value = T::Currency::minimum_balance().saturating_mul(100.into()); let value = T::Currency::minimum_balance().saturating_mul(100.into());
Treasury::<T>::tip_new( Treasury::<T, _>::tip_new(
RawOrigin::Signed(member).into(), RawOrigin::Signed(member).into(),
reason.clone(), reason.clone(),
beneficiary.clone(), beneficiary.clone(),
@@ -188,8 +190,8 @@ benchmarks! {
)?; )?;
let reason_hash = T::Hashing::hash(&reason[..]); let reason_hash = T::Hashing::hash(&reason[..]);
let hash = T::Hashing::hash_of(&(&reason_hash, &beneficiary)); let hash = T::Hashing::hash_of(&(&reason_hash, &beneficiary));
ensure!(Tips::<T>::contains_key(hash), "tip does not exist"); ensure!(Tips::<T, _>::contains_key(hash), "tip does not exist");
create_tips::<T>(t - 1, hash.clone(), value)?; create_tips::<T, _>(t - 1, hash.clone(), value)?;
let caller = account("member", t - 1, SEED); let caller = account("member", t - 1, SEED);
// Whitelist caller account from further DB operations. // Whitelist caller account from further DB operations.
let caller_key = frame_system::Account::<T>::hashed_key_for(&caller); let caller_key = frame_system::Account::<T>::hashed_key_for(&caller);
@@ -200,14 +202,14 @@ benchmarks! {
let t in 1 .. MAX_TIPPERS; let t in 1 .. MAX_TIPPERS;
// Make sure pot is funded // Make sure pot is funded
let pot_account = Treasury::<T>::account_id(); let pot_account = Treasury::<T, _>::account_id();
let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000.into()); let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000.into());
let _ = T::Currency::make_free_balance_be(&pot_account, value); let _ = T::Currency::make_free_balance_be(&pot_account, value);
// Set up a new tip proposal // Set up a new tip proposal
let (member, reason, beneficiary, value) = setup_tip::<T>(0, t)?; let (member, reason, beneficiary, value) = setup_tip::<T, _>(0, t)?;
let value = T::Currency::minimum_balance().saturating_mul(100.into()); let value = T::Currency::minimum_balance().saturating_mul(100.into());
Treasury::<T>::tip_new( Treasury::<T, _>::tip_new(
RawOrigin::Signed(member).into(), RawOrigin::Signed(member).into(),
reason.clone(), reason.clone(),
beneficiary.clone(), beneficiary.clone(),
@@ -217,8 +219,8 @@ benchmarks! {
// Create a bunch of tips // Create a bunch of tips
let reason_hash = T::Hashing::hash(&reason[..]); let reason_hash = T::Hashing::hash(&reason[..]);
let hash = T::Hashing::hash_of(&(&reason_hash, &beneficiary)); let hash = T::Hashing::hash_of(&(&reason_hash, &beneficiary));
ensure!(Tips::<T>::contains_key(hash), "tip does not exist"); ensure!(Tips::<T, _>::contains_key(hash), "tip does not exist");
create_tips::<T>(t, hash.clone(), value)?; create_tips::<T, _>(t, hash.clone(), value)?;
let caller = account("caller", t, SEED); let caller = account("caller", t, SEED);
// Whitelist caller account from further DB operations. // Whitelist caller account from further DB operations.
@@ -228,12 +230,12 @@ benchmarks! {
on_initialize { on_initialize {
let p in 0 .. 100; let p in 0 .. 100;
let pot_account = Treasury::<T>::account_id(); let pot_account = Treasury::<T, _>::account_id();
let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000.into()); let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000.into());
let _ = T::Currency::make_free_balance_be(&pot_account, value); let _ = T::Currency::make_free_balance_be(&pot_account, value);
create_approved_proposals::<T>(p)?; create_approved_proposals::<T, _>(p)?;
}: { }: {
Treasury::<T>::on_initialize(T::BlockNumber::zero()); Treasury::<T, _>::on_initialize(T::BlockNumber::zero());
} }
} }
+72 -66
View File
@@ -107,9 +107,12 @@ use frame_system::{self as system, ensure_signed};
mod tests; mod tests;
mod benchmarking; mod benchmarking;
type BalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance; type BalanceOf<T, I> =
type PositiveImbalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::PositiveImbalance; <<T as Trait<I>>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::Balance;
type NegativeImbalanceOf<T> = <<T as Trait>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::NegativeImbalance; type PositiveImbalanceOf<T, I> =
<<T as Trait<I>>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::PositiveImbalance;
type NegativeImbalanceOf<T, I> =
<<T as Trait<I>>::Currency as Currency<<T as frame_system::Trait>::AccountId>>::NegativeImbalance;
pub trait WeightInfo { pub trait WeightInfo {
fn propose_spend(u: u32, ) -> Weight; fn propose_spend(u: u32, ) -> Weight;
@@ -135,7 +138,7 @@ impl WeightInfo for () {
fn on_initialize(_p: u32, ) -> Weight { 1_000_000_000 } fn on_initialize(_p: u32, ) -> Weight { 1_000_000_000 }
} }
pub trait Trait: frame_system::Trait { pub trait Trait<I=DefaultInstance>: frame_system::Trait {
/// The treasury's module id, used for deriving its sovereign account ID. /// The treasury's module id, used for deriving its sovereign account ID.
type ModuleId: Get<ModuleId>; type ModuleId: Get<ModuleId>;
@@ -160,23 +163,23 @@ pub trait Trait: frame_system::Trait {
type TipFindersFee: Get<Percent>; type TipFindersFee: Get<Percent>;
/// The amount held on deposit for placing a tip report. /// The amount held on deposit for placing a tip report.
type TipReportDepositBase: Get<BalanceOf<Self>>; type TipReportDepositBase: Get<BalanceOf<Self, I>>;
/// The amount held on deposit per byte within the tip report reason. /// The amount held on deposit per byte within the tip report reason.
type TipReportDepositPerByte: Get<BalanceOf<Self>>; type TipReportDepositPerByte: Get<BalanceOf<Self, I>>;
/// The overarching event type. /// The overarching event type.
type Event: From<Event<Self>> + Into<<Self as frame_system::Trait>::Event>; type Event: From<Event<Self, I>> + Into<<Self as frame_system::Trait>::Event>;
/// Handler for the unbalanced decrease when slashing for a rejected proposal. /// Handler for the unbalanced decrease when slashing for a rejected proposal.
type ProposalRejection: OnUnbalanced<NegativeImbalanceOf<Self>>; type ProposalRejection: OnUnbalanced<NegativeImbalanceOf<Self, I>>;
/// Fraction of a proposal's value that should be bonded in order to place the proposal. /// Fraction of a proposal's value that should be bonded in order to place the proposal.
/// An accepted proposal gets these back. A rejected proposal does not. /// An accepted proposal gets these back. A rejected proposal does not.
type ProposalBond: Get<Permill>; type ProposalBond: Get<Permill>;
/// Minimum amount of funds that should be placed in a deposit for making a proposal. /// Minimum amount of funds that should be placed in a deposit for making a proposal.
type ProposalBondMinimum: Get<BalanceOf<Self>>; type ProposalBondMinimum: Get<BalanceOf<Self, I>>;
/// Period between successive spends. /// Period between successive spends.
type SpendPeriod: Get<Self::BlockNumber>; type SpendPeriod: Get<Self::BlockNumber>;
@@ -185,7 +188,7 @@ pub trait Trait: frame_system::Trait {
type Burn: Get<Permill>; type Burn: Get<Permill>;
/// Handler for the unbalanced decrease when treasury funds are burned. /// Handler for the unbalanced decrease when treasury funds are burned.
type BurnDestination: OnUnbalanced<NegativeImbalanceOf<Self>>; type BurnDestination: OnUnbalanced<NegativeImbalanceOf<Self, I>>;
/// Weight information for extrinsics in this pallet. /// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo; type WeightInfo: WeightInfo;
@@ -236,14 +239,14 @@ pub struct OpenTip<
} }
decl_storage! { decl_storage! {
trait Store for Module<T: Trait> as Treasury { trait Store for Module<T: Trait<I>, I: Instance=DefaultInstance> as Treasury {
/// Number of proposals that have been made. /// Number of proposals that have been made.
ProposalCount get(fn proposal_count): ProposalIndex; ProposalCount get(fn proposal_count): ProposalIndex;
/// Proposals that have been made. /// Proposals that have been made.
Proposals get(fn proposals): Proposals get(fn proposals):
map hasher(twox_64_concat) ProposalIndex map hasher(twox_64_concat) ProposalIndex
=> Option<Proposal<T::AccountId, BalanceOf<T>>>; => Option<Proposal<T::AccountId, BalanceOf<T, I>>>;
/// Proposal indices that have been approved but not yet awarded. /// Proposal indices that have been approved but not yet awarded.
Approvals get(fn approvals): Vec<ProposalIndex>; Approvals get(fn approvals): Vec<ProposalIndex>;
@@ -253,7 +256,7 @@ decl_storage! {
/// guaranteed to be a secure hash. /// guaranteed to be a secure hash.
pub Tips get(fn tips): pub Tips get(fn tips):
map hasher(twox_64_concat) T::Hash map hasher(twox_64_concat) T::Hash
=> Option<OpenTip<T::AccountId, BalanceOf<T>, T::BlockNumber, T::Hash>>; => Option<OpenTip<T::AccountId, BalanceOf<T, I>, T::BlockNumber, T::Hash>>;
/// Simple preimage lookup from the reason's hash to the original data. Again, has an /// Simple preimage lookup from the reason's hash to the original data. Again, has an
/// insecure enumerable hash since the key is guaranteed to be the result of a secure hash. /// insecure enumerable hash since the key is guaranteed to be the result of a secure hash.
@@ -263,7 +266,7 @@ decl_storage! {
build(|_config| { build(|_config| {
// Create Treasury account // Create Treasury account
let _ = T::Currency::make_free_balance_be( let _ = T::Currency::make_free_balance_be(
&<Module<T>>::account_id(), &<Module<T, I>>::account_id(),
T::Currency::minimum_balance(), T::Currency::minimum_balance(),
); );
}); });
@@ -271,9 +274,9 @@ decl_storage! {
} }
decl_event!( decl_event!(
pub enum Event<T> pub enum Event<T, I=DefaultInstance>
where where
Balance = BalanceOf<T>, Balance = BalanceOf<T, I>,
<T as frame_system::Trait>::AccountId, <T as frame_system::Trait>::AccountId,
<T as frame_system::Trait>::Hash, <T as frame_system::Trait>::Hash,
{ {
@@ -305,7 +308,7 @@ decl_event!(
decl_error! { decl_error! {
/// Error for the treasury module. /// Error for the treasury module.
pub enum Error for Module<T: Trait> { pub enum Error for Module<T: Trait<I>, I: Instance> {
/// Proposer's balance is too low. /// Proposer's balance is too low.
InsufficientProposersBalance, InsufficientProposersBalance,
/// No proposal at that index. /// No proposal at that index.
@@ -326,13 +329,16 @@ decl_error! {
} }
decl_module! { decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin { pub struct Module<T: Trait<I>, I: Instance=DefaultInstance>
for enum Call
where origin: T::Origin
{
/// Fraction of a proposal's value that should be bonded in order to place the proposal. /// Fraction of a proposal's value that should be bonded in order to place the proposal.
/// An accepted proposal gets these back. A rejected proposal does not. /// An accepted proposal gets these back. A rejected proposal does not.
const ProposalBond: Permill = T::ProposalBond::get(); const ProposalBond: Permill = T::ProposalBond::get();
/// Minimum amount of funds that should be placed in a deposit for making a proposal. /// Minimum amount of funds that should be placed in a deposit for making a proposal.
const ProposalBondMinimum: BalanceOf<T> = T::ProposalBondMinimum::get(); const ProposalBondMinimum: BalanceOf<T, I> = T::ProposalBondMinimum::get();
/// Period between successive spends. /// Period between successive spends.
const SpendPeriod: T::BlockNumber = T::SpendPeriod::get(); const SpendPeriod: T::BlockNumber = T::SpendPeriod::get();
@@ -347,15 +353,15 @@ decl_module! {
const TipFindersFee: Percent = T::TipFindersFee::get(); const TipFindersFee: Percent = T::TipFindersFee::get();
/// The amount held on deposit for placing a tip report. /// The amount held on deposit for placing a tip report.
const TipReportDepositBase: BalanceOf<T> = T::TipReportDepositBase::get(); const TipReportDepositBase: BalanceOf<T, I> = T::TipReportDepositBase::get();
/// The amount held on deposit per byte within the tip report reason. /// The amount held on deposit per byte within the tip report reason.
const TipReportDepositPerByte: BalanceOf<T> = T::TipReportDepositPerByte::get(); const TipReportDepositPerByte: BalanceOf<T, I> = T::TipReportDepositPerByte::get();
/// The treasury's module id, used for deriving its sovereign account ID. /// The treasury's module id, used for deriving its sovereign account ID.
const ModuleId: ModuleId = T::ModuleId::get(); const ModuleId: ModuleId = T::ModuleId::get();
type Error = Error<T>; type Error = Error<T, I>;
fn deposit_event() = default; fn deposit_event() = default;
@@ -371,7 +377,7 @@ decl_module! {
#[weight = 120_000_000 + T::DbWeight::get().reads_writes(1, 2)] #[weight = 120_000_000 + T::DbWeight::get().reads_writes(1, 2)]
fn propose_spend( fn propose_spend(
origin, origin,
#[compact] value: BalanceOf<T>, #[compact] value: BalanceOf<T, I>,
beneficiary: <T::Lookup as StaticLookup>::Source beneficiary: <T::Lookup as StaticLookup>::Source
) { ) {
let proposer = ensure_signed(origin)?; let proposer = ensure_signed(origin)?;
@@ -379,11 +385,11 @@ decl_module! {
let bond = Self::calculate_bond(value); let bond = Self::calculate_bond(value);
T::Currency::reserve(&proposer, bond) T::Currency::reserve(&proposer, bond)
.map_err(|_| Error::<T>::InsufficientProposersBalance)?; .map_err(|_| Error::<T, I>::InsufficientProposersBalance)?;
let c = Self::proposal_count(); let c = Self::proposal_count();
ProposalCount::put(c + 1); <ProposalCount<I>>::put(c + 1);
<Proposals<T>>::insert(c, Proposal { proposer, value, beneficiary, bond }); <Proposals<T, I>>::insert(c, Proposal { proposer, value, beneficiary, bond });
Self::deposit_event(RawEvent::Proposed(c)); Self::deposit_event(RawEvent::Proposed(c));
} }
@@ -401,12 +407,12 @@ decl_module! {
fn reject_proposal(origin, #[compact] proposal_id: ProposalIndex) { fn reject_proposal(origin, #[compact] proposal_id: ProposalIndex) {
T::RejectOrigin::ensure_origin(origin)?; T::RejectOrigin::ensure_origin(origin)?;
let proposal = <Proposals<T>>::take(&proposal_id).ok_or(Error::<T>::InvalidProposalIndex)?; let proposal = <Proposals<T, I>>::take(&proposal_id).ok_or(Error::<T, I>::InvalidProposalIndex)?;
let value = proposal.bond; let value = proposal.bond;
let imbalance = T::Currency::slash_reserved(&proposal.proposer, value).0; let imbalance = T::Currency::slash_reserved(&proposal.proposer, value).0;
T::ProposalRejection::on_unbalanced(imbalance); T::ProposalRejection::on_unbalanced(imbalance);
Self::deposit_event(Event::<T>::Rejected(proposal_id, value)); Self::deposit_event(Event::<T, I>::Rejected(proposal_id, value));
} }
/// Approve a proposal. At a later time, the proposal will be allocated to the beneficiary /// Approve a proposal. At a later time, the proposal will be allocated to the beneficiary
@@ -423,8 +429,8 @@ decl_module! {
fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) { fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) {
T::ApproveOrigin::ensure_origin(origin)?; T::ApproveOrigin::ensure_origin(origin)?;
ensure!(<Proposals<T>>::contains_key(proposal_id), Error::<T>::InvalidProposalIndex); ensure!(<Proposals<T, I>>::contains_key(proposal_id), Error::<T, I>::InvalidProposalIndex);
Approvals::mutate(|v| v.push(proposal_id)); <Approvals<I>>::mutate(|v| v.push(proposal_id));
} }
/// Report something `reason` that deserves a tip and claim any eventual the finder's fee. /// Report something `reason` that deserves a tip and claim any eventual the finder's fee.
@@ -451,18 +457,18 @@ decl_module! {
let finder = ensure_signed(origin)?; let finder = ensure_signed(origin)?;
const MAX_SENSIBLE_REASON_LENGTH: usize = 16384; const MAX_SENSIBLE_REASON_LENGTH: usize = 16384;
ensure!(reason.len() <= MAX_SENSIBLE_REASON_LENGTH, Error::<T>::ReasonTooBig); ensure!(reason.len() <= MAX_SENSIBLE_REASON_LENGTH, Error::<T, I>::ReasonTooBig);
let reason_hash = T::Hashing::hash(&reason[..]); let reason_hash = T::Hashing::hash(&reason[..]);
ensure!(!Reasons::<T>::contains_key(&reason_hash), Error::<T>::AlreadyKnown); ensure!(!Reasons::<T, I>::contains_key(&reason_hash), Error::<T, I>::AlreadyKnown);
let hash = T::Hashing::hash_of(&(&reason_hash, &who)); let hash = T::Hashing::hash_of(&(&reason_hash, &who));
ensure!(!Tips::<T>::contains_key(&hash), Error::<T>::AlreadyKnown); ensure!(!Tips::<T, I>::contains_key(&hash), Error::<T, I>::AlreadyKnown);
let deposit = T::TipReportDepositBase::get() let deposit = T::TipReportDepositBase::get()
+ T::TipReportDepositPerByte::get() * (reason.len() as u32).into(); + T::TipReportDepositPerByte::get() * (reason.len() as u32).into();
T::Currency::reserve(&finder, deposit)?; T::Currency::reserve(&finder, deposit)?;
Reasons::<T>::insert(&reason_hash, &reason); Reasons::<T, I>::insert(&reason_hash, &reason);
let tip = OpenTip { let tip = OpenTip {
reason: reason_hash, reason: reason_hash,
who, who,
@@ -472,7 +478,7 @@ decl_module! {
tips: vec![], tips: vec![],
finders_fee: true finders_fee: true
}; };
Tips::<T>::insert(&hash, tip); Tips::<T, I>::insert(&hash, tip);
Self::deposit_event(RawEvent::NewTip(hash)); Self::deposit_event(RawEvent::NewTip(hash));
} }
@@ -498,11 +504,11 @@ decl_module! {
#[weight = 120_000_000 + T::DbWeight::get().reads_writes(1, 2)] #[weight = 120_000_000 + T::DbWeight::get().reads_writes(1, 2)]
fn retract_tip(origin, hash: T::Hash) { fn retract_tip(origin, hash: T::Hash) {
let who = ensure_signed(origin)?; let who = ensure_signed(origin)?;
let tip = Tips::<T>::get(&hash).ok_or(Error::<T>::UnknownTip)?; let tip = Tips::<T, I>::get(&hash).ok_or(Error::<T, I>::UnknownTip)?;
ensure!(tip.finder == who, Error::<T>::NotFinder); ensure!(tip.finder == who, Error::<T, I>::NotFinder);
Reasons::<T>::remove(&tip.reason); Reasons::<T, I>::remove(&tip.reason);
Tips::<T>::remove(&hash); Tips::<T, I>::remove(&hash);
if !tip.deposit.is_zero() { if !tip.deposit.is_zero() {
let _ = T::Currency::unreserve(&who, tip.deposit); let _ = T::Currency::unreserve(&who, tip.deposit);
} }
@@ -535,14 +541,14 @@ decl_module! {
+ 4_000 * reason.len() as Weight + 4_000 * reason.len() as Weight
+ 480_000 * T::Tippers::max_len() as Weight + 480_000 * T::Tippers::max_len() as Weight
+ T::DbWeight::get().reads_writes(2, 2)] + T::DbWeight::get().reads_writes(2, 2)]
fn tip_new(origin, reason: Vec<u8>, who: T::AccountId, tip_value: BalanceOf<T>) { fn tip_new(origin, reason: Vec<u8>, who: T::AccountId, tip_value: BalanceOf<T, I>) {
let tipper = ensure_signed(origin)?; let tipper = ensure_signed(origin)?;
ensure!(T::Tippers::contains(&tipper), BadOrigin); ensure!(T::Tippers::contains(&tipper), BadOrigin);
let reason_hash = T::Hashing::hash(&reason[..]); let reason_hash = T::Hashing::hash(&reason[..]);
ensure!(!Reasons::<T>::contains_key(&reason_hash), Error::<T>::AlreadyKnown); ensure!(!Reasons::<T, I>::contains_key(&reason_hash), Error::<T, I>::AlreadyKnown);
let hash = T::Hashing::hash_of(&(&reason_hash, &who)); let hash = T::Hashing::hash_of(&(&reason_hash, &who));
Reasons::<T>::insert(&reason_hash, &reason); Reasons::<T, I>::insert(&reason_hash, &reason);
Self::deposit_event(RawEvent::NewTip(hash.clone())); Self::deposit_event(RawEvent::NewTip(hash.clone()));
let tips = vec![(tipper.clone(), tip_value)]; let tips = vec![(tipper.clone(), tip_value)];
let tip = OpenTip { let tip = OpenTip {
@@ -554,7 +560,7 @@ decl_module! {
tips, tips,
finders_fee: false, finders_fee: false,
}; };
Tips::<T>::insert(&hash, tip); Tips::<T, I>::insert(&hash, tip);
} }
/// Declare a tip value for an already-open tip. /// Declare a tip value for an already-open tip.
@@ -584,15 +590,15 @@ decl_module! {
/// # </weight> /// # </weight>
#[weight = 68_000_000 + 2_000_000 * T::Tippers::max_len() as Weight #[weight = 68_000_000 + 2_000_000 * T::Tippers::max_len() as Weight
+ T::DbWeight::get().reads_writes(2, 1)] + T::DbWeight::get().reads_writes(2, 1)]
fn tip(origin, hash: T::Hash, tip_value: BalanceOf<T>) { fn tip(origin, hash: T::Hash, tip_value: BalanceOf<T, I>) {
let tipper = ensure_signed(origin)?; let tipper = ensure_signed(origin)?;
ensure!(T::Tippers::contains(&tipper), BadOrigin); ensure!(T::Tippers::contains(&tipper), BadOrigin);
let mut tip = Tips::<T>::get(hash).ok_or(Error::<T>::UnknownTip)?; let mut tip = Tips::<T, I>::get(hash).ok_or(Error::<T, I>::UnknownTip)?;
if Self::insert_tip_and_check_closing(&mut tip, tipper, tip_value) { if Self::insert_tip_and_check_closing(&mut tip, tipper, tip_value) {
Self::deposit_event(RawEvent::TipClosing(hash.clone())); Self::deposit_event(RawEvent::TipClosing(hash.clone()));
} }
Tips::<T>::insert(&hash, tip); Tips::<T, I>::insert(&hash, tip);
} }
/// Close and payout a tip. /// Close and payout a tip.
@@ -617,12 +623,12 @@ decl_module! {
fn close_tip(origin, hash: T::Hash) { fn close_tip(origin, hash: T::Hash) {
ensure_signed(origin)?; ensure_signed(origin)?;
let tip = Tips::<T>::get(hash).ok_or(Error::<T>::UnknownTip)?; let tip = Tips::<T, I>::get(hash).ok_or(Error::<T, I>::UnknownTip)?;
let n = tip.closes.as_ref().ok_or(Error::<T>::StillOpen)?; let n = tip.closes.as_ref().ok_or(Error::<T, I>::StillOpen)?;
ensure!(system::Module::<T>::block_number() >= *n, Error::<T>::Premature); ensure!(system::Module::<T>::block_number() >= *n, Error::<T, I>::Premature);
// closed. // closed.
Reasons::<T>::remove(&tip.reason); Reasons::<T, I>::remove(&tip.reason);
Tips::<T>::remove(hash); Tips::<T, I>::remove(hash);
Self::payout_tip(hash, tip); Self::payout_tip(hash, tip);
} }
@@ -647,7 +653,7 @@ decl_module! {
} }
} }
impl<T: Trait> Module<T> { impl<T: Trait<I>, I: Instance> Module<T, I> {
// Add public immutables and private mutables. // Add public immutables and private mutables.
/// The account ID of the treasury pot. /// The account ID of the treasury pot.
@@ -659,7 +665,7 @@ impl<T: Trait> Module<T> {
} }
/// The needed bond for a proposal whose spend is `value`. /// The needed bond for a proposal whose spend is `value`.
fn calculate_bond(value: BalanceOf<T>) -> BalanceOf<T> { fn calculate_bond(value: BalanceOf<T, I>) -> BalanceOf<T, I> {
T::ProposalBondMinimum::get().max(T::ProposalBond::get() * value) T::ProposalBondMinimum::get().max(T::ProposalBond::get() * value)
} }
@@ -668,9 +674,9 @@ impl<T: Trait> Module<T> {
/// ///
/// `O(T)` and one storage access. /// `O(T)` and one storage access.
fn insert_tip_and_check_closing( fn insert_tip_and_check_closing(
tip: &mut OpenTip<T::AccountId, BalanceOf<T>, T::BlockNumber, T::Hash>, tip: &mut OpenTip<T::AccountId, BalanceOf<T, I>, T::BlockNumber, T::Hash>,
tipper: T::AccountId, tipper: T::AccountId,
tip_value: BalanceOf<T>, tip_value: BalanceOf<T, I>,
) -> bool { ) -> bool {
match tip.tips.binary_search_by_key(&&tipper, |x| &x.0) { match tip.tips.binary_search_by_key(&&tipper, |x| &x.0) {
Ok(pos) => tip.tips[pos] = (tipper, tip_value), Ok(pos) => tip.tips[pos] = (tipper, tip_value),
@@ -687,7 +693,7 @@ impl<T: Trait> Module<T> {
} }
/// Remove any non-members of `Tippers` from a `tips` vector. `O(T)`. /// Remove any non-members of `Tippers` from a `tips` vector. `O(T)`.
fn retain_active_tips(tips: &mut Vec<(T::AccountId, BalanceOf<T>)>) { fn retain_active_tips(tips: &mut Vec<(T::AccountId, BalanceOf<T, I>)>) {
let members = T::Tippers::sorted_members(); let members = T::Tippers::sorted_members();
let mut members_iter = members.iter(); let mut members_iter = members.iter();
let mut member = members_iter.next(); let mut member = members_iter.next();
@@ -711,7 +717,7 @@ impl<T: Trait> Module<T> {
/// ///
/// Up to three balance operations. /// Up to three balance operations.
/// Plus `O(T)` (`T` is Tippers length). /// Plus `O(T)` (`T` is Tippers length).
fn payout_tip(hash: T::Hash, tip: OpenTip<T::AccountId, BalanceOf<T>, T::BlockNumber, T::Hash>) { fn payout_tip(hash: T::Hash, tip: OpenTip<T::AccountId, BalanceOf<T, I>, T::BlockNumber, T::Hash>) {
let mut tips = tip.tips; let mut tips = tip.tips;
Self::retain_active_tips(&mut tips); Self::retain_active_tips(&mut tips);
tips.sort_by_key(|i| i.1); tips.sort_by_key(|i| i.1);
@@ -742,15 +748,15 @@ impl<T: Trait> Module<T> {
Self::deposit_event(RawEvent::Spending(budget_remaining)); Self::deposit_event(RawEvent::Spending(budget_remaining));
let mut missed_any = false; let mut missed_any = false;
let mut imbalance = <PositiveImbalanceOf<T>>::zero(); let mut imbalance = <PositiveImbalanceOf<T, I>>::zero();
let prior_approvals_len = Approvals::mutate(|v| { let prior_approvals_len = <Approvals<I>>::mutate(|v| {
let prior_approvals_len = v.len() as u64; let prior_approvals_len = v.len() as u64;
v.retain(|&index| { v.retain(|&index| {
// Should always be true, but shouldn't panic if false or we're screwed. // Should always be true, but shouldn't panic if false or we're screwed.
if let Some(p) = Self::proposals(index) { if let Some(p) = Self::proposals(index) {
if p.value <= budget_remaining { if p.value <= budget_remaining {
budget_remaining -= p.value; budget_remaining -= p.value;
<Proposals<T>>::remove(index); <Proposals<T, I>>::remove(index);
// return their deposit. // return their deposit.
let _ = T::Currency::unreserve(&p.proposer, p.bond); let _ = T::Currency::unreserve(&p.proposer, p.bond);
@@ -804,7 +810,7 @@ impl<T: Trait> Module<T> {
/// Return the amount of money in the pot. /// Return the amount of money in the pot.
// The existential deposit is not part of the pot so treasury account never gets deleted. // The existential deposit is not part of the pot so treasury account never gets deleted.
fn pot() -> BalanceOf<T> { fn pot() -> BalanceOf<T, I> {
T::Currency::free_balance(&Self::account_id()) T::Currency::free_balance(&Self::account_id())
// Must never be less than 0 but better be safe. // Must never be less than 0 but better be safe.
.saturating_sub(T::Currency::minimum_balance()) .saturating_sub(T::Currency::minimum_balance())
@@ -838,9 +844,9 @@ impl<T: Trait> Module<T> {
for (hash, old_tip) in StorageKeyIterator::< for (hash, old_tip) in StorageKeyIterator::<
T::Hash, T::Hash,
OldOpenTip<T::AccountId, BalanceOf<T>, T::BlockNumber, T::Hash>, OldOpenTip<T::AccountId, BalanceOf<T, I>, T::BlockNumber, T::Hash>,
Twox64Concat, Twox64Concat,
>::new(b"Treasury", b"Tips").drain() >::new(I::PREFIX.as_bytes(), b"Tips").drain()
{ {
let (finder, deposit, finders_fee) = match old_tip.finder { let (finder, deposit, finders_fee) = match old_tip.finder {
Some((finder, deposit)) => (finder, deposit, true), Some((finder, deposit)) => (finder, deposit, true),
@@ -855,13 +861,13 @@ impl<T: Trait> Module<T> {
tips: old_tip.tips, tips: old_tip.tips,
finders_fee finders_fee
}; };
Tips::<T>::insert(hash, new_tip) Tips::<T, I>::insert(hash, new_tip)
} }
} }
} }
impl<T: Trait> OnUnbalanced<NegativeImbalanceOf<T>> for Module<T> { impl<T: Trait<I>, I: Instance> OnUnbalanced<NegativeImbalanceOf<T, I>> for Module<T, I> {
fn on_nonzero_unbalanced(amount: NegativeImbalanceOf<T>) { fn on_nonzero_unbalanced(amount: NegativeImbalanceOf<T, I>) {
let numeric_amount = amount.peek(); let numeric_amount = amount.peek();
// Must resolve into existing but better to be safe. // Must resolve into existing but better to be safe.
+27 -15
View File
@@ -162,7 +162,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
// Total issuance will be 200 with treasury account initialized at ED. // Total issuance will be 200 with treasury account initialized at ED.
balances: vec![(0, 100), (1, 98), (2, 1)], balances: vec![(0, 100), (1, 98), (2, 1)],
}.assimilate_storage(&mut t).unwrap(); }.assimilate_storage(&mut t).unwrap();
GenesisConfig::default().assimilate_storage::<Test>(&mut t).unwrap(); GenesisConfig::default().assimilate_storage::<Test, _>(&mut t).unwrap();
t.into() t.into()
} }
@@ -185,7 +185,7 @@ fn tip_new_cannot_be_used_twice() {
assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10)); assert_ok!(Treasury::tip_new(Origin::signed(10), b"awesome.dot".to_vec(), 3, 10));
assert_noop!( assert_noop!(
Treasury::tip_new(Origin::signed(11), b"awesome.dot".to_vec(), 3, 10), Treasury::tip_new(Origin::signed(11), b"awesome.dot".to_vec(), 3, 10),
Error::<Test>::AlreadyKnown Error::<Test, _>::AlreadyKnown
); );
}); });
} }
@@ -201,7 +201,7 @@ fn report_awesome_and_tip_works() {
// other reports don't count. // other reports don't count.
assert_noop!( assert_noop!(
Treasury::report_awesome(Origin::signed(1), b"awesome.dot".to_vec(), 3), Treasury::report_awesome(Origin::signed(1), b"awesome.dot".to_vec(), 3),
Error::<Test>::AlreadyKnown Error::<Test, _>::AlreadyKnown
); );
let h = tip_hash(); let h = tip_hash();
@@ -259,7 +259,7 @@ fn close_tip_works() {
assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10));
assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::<Test>::StillOpen); assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::<Test, _>::StillOpen);
assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10));
@@ -273,7 +273,7 @@ fn close_tip_works() {
RawEvent::TipClosing(h), RawEvent::TipClosing(h),
); );
assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::<Test>::Premature); assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::<Test, _>::Premature);
System::set_block_number(2); System::set_block_number(2);
assert_noop!(Treasury::close_tip(Origin::none(), h.into()), BadOrigin); assert_noop!(Treasury::close_tip(Origin::none(), h.into()), BadOrigin);
@@ -290,7 +290,7 @@ fn close_tip_works() {
RawEvent::TipClosed(h, 3, 10), RawEvent::TipClosed(h, 3, 10),
); );
assert_noop!(Treasury::close_tip(Origin::signed(100), h.into()), Error::<Test>::UnknownTip); assert_noop!(Treasury::close_tip(Origin::signed(100), h.into()), Error::<Test, _>::UnknownTip);
}); });
} }
@@ -304,10 +304,10 @@ fn retract_tip_works() {
assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10)); assert_ok!(Treasury::tip(Origin::signed(10), h.clone(), 10));
assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10));
assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10));
assert_noop!(Treasury::retract_tip(Origin::signed(10), h.clone()), Error::<Test>::NotFinder); assert_noop!(Treasury::retract_tip(Origin::signed(10), h.clone()), Error::<Test, _>::NotFinder);
assert_ok!(Treasury::retract_tip(Origin::signed(0), h.clone())); assert_ok!(Treasury::retract_tip(Origin::signed(0), h.clone()));
System::set_block_number(2); System::set_block_number(2);
assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::<Test>::UnknownTip); assert_noop!(Treasury::close_tip(Origin::signed(0), h.into()), Error::<Test, _>::UnknownTip);
// with tip new // with tip new
Balances::make_free_balance_be(&Treasury::account_id(), 101); Balances::make_free_balance_be(&Treasury::account_id(), 101);
@@ -315,10 +315,10 @@ fn retract_tip_works() {
let h = tip_hash(); let h = tip_hash();
assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10)); assert_ok!(Treasury::tip(Origin::signed(11), h.clone(), 10));
assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10)); assert_ok!(Treasury::tip(Origin::signed(12), h.clone(), 10));
assert_noop!(Treasury::retract_tip(Origin::signed(0), h.clone()), Error::<Test>::NotFinder); assert_noop!(Treasury::retract_tip(Origin::signed(0), h.clone()), Error::<Test, _>::NotFinder);
assert_ok!(Treasury::retract_tip(Origin::signed(10), h.clone())); assert_ok!(Treasury::retract_tip(Origin::signed(10), h.clone()));
System::set_block_number(2); System::set_block_number(2);
assert_noop!(Treasury::close_tip(Origin::signed(10), h.into()), Error::<Test>::UnknownTip); assert_noop!(Treasury::close_tip(Origin::signed(10), h.into()), Error::<Test, _>::UnknownTip);
}); });
} }
@@ -387,7 +387,7 @@ fn spend_proposal_fails_when_proposer_poor() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_noop!( assert_noop!(
Treasury::propose_spend(Origin::signed(2), 100, 3), Treasury::propose_spend(Origin::signed(2), 100, 3),
Error::<Test>::InsufficientProposersBalance, Error::<Test, _>::InsufficientProposersBalance,
); );
}); });
} }
@@ -440,21 +440,30 @@ fn reject_already_rejected_spend_proposal_fails() {
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3));
assert_ok!(Treasury::reject_proposal(Origin::root(), 0)); assert_ok!(Treasury::reject_proposal(Origin::root(), 0));
assert_noop!(Treasury::reject_proposal(Origin::root(), 0), Error::<Test>::InvalidProposalIndex); assert_noop!(
Treasury::reject_proposal(Origin::root(), 0),
Error::<Test, _>::InvalidProposalIndex,
);
}); });
} }
#[test] #[test]
fn reject_non_existent_spend_proposal_fails() { fn reject_non_existent_spend_proposal_fails() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_noop!(Treasury::reject_proposal(Origin::root(), 0), Error::<Test>::InvalidProposalIndex); assert_noop!(
Treasury::reject_proposal(Origin::root(), 0),
Error::<Test, _>::InvalidProposalIndex,
);
}); });
} }
#[test] #[test]
fn accept_non_existent_spend_proposal_fails() { fn accept_non_existent_spend_proposal_fails() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_noop!(Treasury::approve_proposal(Origin::root(), 0), Error::<Test>::InvalidProposalIndex); assert_noop!(
Treasury::approve_proposal(Origin::root(), 0),
Error::<Test, _>::InvalidProposalIndex,
);
}); });
} }
@@ -465,7 +474,10 @@ fn accept_already_rejected_spend_proposal_fails() {
assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3)); assert_ok!(Treasury::propose_spend(Origin::signed(0), 100, 3));
assert_ok!(Treasury::reject_proposal(Origin::root(), 0)); assert_ok!(Treasury::reject_proposal(Origin::root(), 0));
assert_noop!(Treasury::approve_proposal(Origin::root(), 0), Error::<Test>::InvalidProposalIndex); assert_noop!(
Treasury::approve_proposal(Origin::root(), 0),
Error::<Test, _>::InvalidProposalIndex,
);
}); });
} }