diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index 5f20c502e4953..c210fb5d02a7f 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -363,7 +363,7 @@ fn full_native_block_import_works() { }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::pallet_treasury(pallet_treasury::RawEvent::Deposit(fees * 8 / 10)), + event: Event::pallet_treasury(pallet_treasury::Event::Deposit(fees * 8 / 10)), topics: vec![], }, EventRecord { @@ -417,7 +417,7 @@ fn full_native_block_import_works() { }, EventRecord { phase: Phase::ApplyExtrinsic(1), - event: Event::pallet_treasury(pallet_treasury::RawEvent::Deposit(fees * 8 / 10)), + event: Event::pallet_treasury(pallet_treasury::Event::Deposit(fees * 8 / 10)), topics: vec![], }, EventRecord { @@ -440,7 +440,7 @@ fn full_native_block_import_works() { }, EventRecord { phase: Phase::ApplyExtrinsic(2), - event: Event::pallet_treasury(pallet_treasury::RawEvent::Deposit(fees * 8 / 10)), + event: Event::pallet_treasury(pallet_treasury::Event::Deposit(fees * 8 / 10)), topics: vec![], }, EventRecord { diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 46f80cc56afd9..b786e9b20acfe 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1097,7 +1097,7 @@ construct_runtime!( Elections: pallet_elections_phragmen::{Pallet, Call, Storage, Event, Config}, TechnicalMembership: pallet_membership::::{Pallet, Call, Storage, Event, Config}, Grandpa: pallet_grandpa::{Pallet, Call, Storage, Config, Event, ValidateUnsigned}, - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, + Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, Contracts: pallet_contracts::{Pallet, Call, Config, Storage, Event}, Sudo: pallet_sudo::{Pallet, Call, Config, Storage, Event}, ImOnline: pallet_im_online::{Pallet, Call, Storage, Event, ValidateUnsigned, Config}, diff --git a/frame/bounties/src/benchmarking.rs b/frame/bounties/src/benchmarking.rs index cb7933079763a..77988b125977b 100644 --- a/frame/bounties/src/benchmarking.rs +++ b/frame/bounties/src/benchmarking.rs @@ -27,7 +27,7 @@ use frame_benchmarking::{benchmarks, account, whitelisted_caller, impl_benchmark use frame_support::traits::OnInitialize; use crate::Module as Bounties; -use pallet_treasury::Module as Treasury; +use pallet_treasury::Pallet as Treasury; const SEED: u32 = 0; diff --git a/frame/bounties/src/tests.rs b/frame/bounties/src/tests.rs index 617f186975269..973ce721d00be 100644 --- a/frame/bounties/src/tests.rs +++ b/frame/bounties/src/tests.rs @@ -46,7 +46,7 @@ frame_support::construct_runtime!( System: frame_system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, Bounties: pallet_bounties::{Pallet, Call, Storage, Event}, - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, + Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, } ); @@ -140,7 +140,7 @@ impl Config for Test { type WeightInfo = (); } -type TreasuryError = pallet_treasury::Error::; +type TreasuryError = pallet_treasury::Error::; pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); @@ -148,7 +148,10 @@ pub fn new_test_ext() -> sp_io::TestExternalities { // Total issuance will be 200 with treasury account initialized at ED. balances: vec![(0, 100), (1, 98), (2, 1)], }.assimilate_storage(&mut t).unwrap(); - pallet_treasury::GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); + + pallet_treasury::GenesisConfig::::default() + .assimilate_storage(&mut t).unwrap(); + t.into() } @@ -262,7 +265,7 @@ fn reject_already_rejected_spend_proposal_fails() { fn reject_non_existent_spend_proposal_fails() { new_test_ext().execute_with(|| { assert_noop!(Treasury::reject_proposal(Origin::root(), 0), - pallet_treasury::Error::::InvalidIndex); + pallet_treasury::Error::::InvalidIndex); }); } @@ -890,7 +893,10 @@ fn genesis_funding_works() { // Total issuance will be 200 with treasury account initialized with 100. balances: vec![(0, 100), (Treasury::account_id(), initial_funding)], }.assimilate_storage(&mut t).unwrap(); - pallet_treasury::GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); + + pallet_treasury::GenesisConfig::::default() + .assimilate_storage(&mut t).unwrap(); + let mut t: sp_io::TestExternalities = t.into(); t.execute_with(|| { diff --git a/frame/tips/src/lib.rs b/frame/tips/src/lib.rs index 6d85df33f10c9..68db714b0da9e 100644 --- a/frame/tips/src/lib.rs +++ b/frame/tips/src/lib.rs @@ -502,7 +502,7 @@ impl Module { tips.sort_by_key(|i| i.1); let treasury = Self::account_id(); - let max_payout = pallet_treasury::Module::::pot(); + let max_payout = pallet_treasury::Pallet::::pot(); let mut payout = tips[tips.len() / 2].1.min(max_payout); if !tip.deposit.is_zero() { diff --git a/frame/tips/src/tests.rs b/frame/tips/src/tests.rs index ef30962fc846f..a5a1605ddf3fe 100644 --- a/frame/tips/src/tests.rs +++ b/frame/tips/src/tests.rs @@ -42,7 +42,7 @@ frame_support::construct_runtime!( { System: frame_system::{Pallet, Call, Config, Storage, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, + Treasury: pallet_treasury::{Pallet, Call, Storage, Config, Event}, TipsModTestInst: tips::{Pallet, Call, Storage, Event}, } ); @@ -160,7 +160,10 @@ pub fn new_test_ext() -> sp_io::TestExternalities { // Total issuance will be 200 with treasury account initialized at ED. balances: vec![(0, 100), (1, 98), (2, 1)], }.assimilate_storage(&mut t).unwrap(); - pallet_treasury::GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); + + pallet_treasury::GenesisConfig::::default() + .assimilate_storage(&mut t).unwrap(); + t.into() } @@ -476,7 +479,10 @@ fn genesis_funding_works() { // Total issuance will be 200 with treasury account initialized with 100. balances: vec![(0, 100), (Treasury::account_id(), initial_funding)], }.assimilate_storage(&mut t).unwrap(); - pallet_treasury::GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); + + pallet_treasury::GenesisConfig::::default() + .assimilate_storage(&mut t).unwrap(); + let mut t: sp_io::TestExternalities = t.into(); t.execute_with(|| { diff --git a/frame/treasury/src/benchmarking.rs b/frame/treasury/src/benchmarking.rs index 119516fe2741a..d29a12f32f18c 100644 --- a/frame/treasury/src/benchmarking.rs +++ b/frame/treasury/src/benchmarking.rs @@ -22,15 +22,17 @@ use super::*; use frame_system::RawOrigin; -use frame_benchmarking::{benchmarks_instance, account, impl_benchmark_test_suite}; -use frame_support::traits::OnInitialize; - -use crate::Module as Treasury; +use frame_benchmarking::{benchmarks_instance_pallet, account, impl_benchmark_test_suite}; +use frame_support::{ + ensure, + traits::{OnInitialize}, +}; +use crate::Pallet as Treasury; const SEED: u32 = 0; // Create the pre-requisite information needed to create a treasury `propose_spend`. -fn setup_proposal, I: Instance>(u: u32) -> ( +fn setup_proposal, I: 'static>(u: u32) -> ( T::AccountId, BalanceOf, ::Source, @@ -44,7 +46,7 @@ fn setup_proposal, I: Instance>(u: u32) -> ( } // Create proposals that are approved for use in `on_initialize`. -fn create_approved_proposals, I: Instance>(n: u32) -> Result<(), &'static str> { +fn create_approved_proposals, I: 'static>(n: u32) -> Result<(), &'static str> { for i in 0 .. n { let (caller, value, lookup) = setup_proposal::(i); Treasury::::propose_spend( @@ -52,20 +54,20 @@ fn create_approved_proposals, I: Instance>(n: u32) -> Result<(), &' value, lookup )?; - let proposal_id = >::get() - 1; + let proposal_id = >::get() - 1; Treasury::::approve_proposal(RawOrigin::Root.into(), proposal_id)?; } - ensure!(>::get().len() == n as usize, "Not all approved"); + ensure!(>::get().len() == n as usize, "Not all approved"); Ok(()) } -fn setup_pot_account, I: Instance>() { +fn setup_pot_account, I: 'static>() { let pot_account = Treasury::::account_id(); let value = T::Currency::minimum_balance().saturating_mul(1_000_000_000u32.into()); let _ = T::Currency::make_free_balance_be(&pot_account, value); } -benchmarks_instance! { +benchmarks_instance_pallet! { propose_spend { let (caller, value, beneficiary_lookup) = setup_proposal::(SEED); diff --git a/frame/treasury/src/lib.rs b/frame/treasury/src/lib.rs index cef50706b5173..dd77520d94781 100644 --- a/frame/treasury/src/lib.rs +++ b/frame/treasury/src/lib.rs @@ -61,74 +61,44 @@ mod tests; mod benchmarking; -pub mod weights; +use sp_std::prelude::*; #[cfg(feature = "std")] use serde::{Serialize, Deserialize}; -use sp_std::prelude::*; -use frame_support::{decl_module, decl_storage, decl_event, ensure, print, decl_error}; -use frame_support::traits::{ - Currency, Get, Imbalance, OnUnbalanced, ExistenceRequirement::{KeepAlive}, - ReservableCurrency, WithdrawReasons +use frame_support::{ + print, + traits::{ + Currency, Get, Imbalance, OnUnbalanced, ExistenceRequirement::{KeepAlive}, + ReservableCurrency, WithdrawReasons, + }, + weights::{Weight}, +}; +use sp_runtime::{ + Permill, ModuleId, RuntimeDebug, + traits::{ + Zero, StaticLookup, AccountIdConversion, Saturating + }, }; -use sp_runtime::{Permill, ModuleId, RuntimeDebug, traits::{ - Zero, StaticLookup, AccountIdConversion, Saturating -}}; -use frame_support::weights::{Weight, DispatchClass}; -use frame_support::traits::{EnsureOrigin}; +#[cfg(feature = "std")] +use frame_support::traits::GenesisBuild; + use codec::{Encode, Decode}; -use frame_system::{ensure_signed}; + +pub mod weights; pub use weights::WeightInfo; -pub type BalanceOf = +pub use pallet::*; + +/// An index of a proposal. Just a `u32`. +pub type ProposalIndex = u32; + +pub type BalanceOf = <>::Currency as Currency<::AccountId>>::Balance; -pub type PositiveImbalanceOf = +pub type PositiveImbalanceOf = <>::Currency as Currency<::AccountId>>::PositiveImbalance; -pub type NegativeImbalanceOf = +pub type NegativeImbalanceOf = <>::Currency as Currency<::AccountId>>::NegativeImbalance; -pub trait Config: frame_system::Config { - /// The treasury's module id, used for deriving its sovereign account ID. - type ModuleId: Get; - - /// The staking balance. - type Currency: Currency + ReservableCurrency; - - /// Origin from which approvals must come. - type ApproveOrigin: EnsureOrigin; - - /// Origin from which rejections must come. - type RejectOrigin: EnsureOrigin; - - /// The overarching event type. - type Event: From> + Into<::Event>; - - /// Handler for the unbalanced decrease when slashing for a rejected proposal or bounty. - type OnSlash: OnUnbalanced>; - - /// 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. - type ProposalBond: Get; - - /// Minimum amount of funds that should be placed in a deposit for making a proposal. - type ProposalBondMinimum: Get>; - - /// Period between successive spends. - type SpendPeriod: Get; - - /// Percentage of spare funds (if any) that are burnt per spend period. - type Burn: Get; - - /// Handler for the unbalanced decrease when treasury funds are burned. - type BurnDestination: OnUnbalanced>; - - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; - - /// Runtime hooks to external pallet using treasury to compute spend funds. - type SpendFunds: SpendFunds; -} - /// A trait to allow the Treasury Pallet to spend it's funds for other purposes. /// There is an expectation that the implementer of this trait will correctly manage /// the mutable variables passed to it: @@ -142,7 +112,7 @@ pub trait Config: frame_system::Config { /// not enough funds, mark this value as `true`. This will prevent the treasury /// from burning the excess funds. #[impl_trait_for_tuples::impl_for_tuples(30)] -pub trait SpendFunds, I=DefaultInstance> { +pub trait SpendFunds, I: 'static = ()> { fn spend_funds( budget_remaining: &mut BalanceOf, imbalance: &mut PositiveImbalanceOf, @@ -151,9 +121,6 @@ pub trait SpendFunds, I=DefaultInstance> { ); } -/// An index of a proposal. Just a `u32`. -pub type ProposalIndex = u32; - /// A spending proposal. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))] #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug)] @@ -168,108 +135,90 @@ pub struct Proposal { bond: Balance, } -decl_storage! { - trait Store for Module, I: Instance=DefaultInstance> as Treasury { - /// Number of proposals that have been made. - ProposalCount get(fn proposal_count): ProposalIndex; +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use super::*; - /// Proposals that have been made. - pub Proposals get(fn proposals): - map hasher(twox_64_concat) ProposalIndex - => Option>>; + #[pallet::config] + pub trait Config: frame_system::Config { - /// Proposal indices that have been approved but not yet awarded. - pub Approvals get(fn approvals): Vec; - } - add_extra_genesis { - build(|_config| { - // Create Treasury account - let account_id = >::account_id(); - let min = T::Currency::minimum_balance(); - if T::Currency::free_balance(&account_id) < min { - let _ = T::Currency::make_free_balance_be( - &account_id, - min, - ); - } - }); - } -} + /// The treasury's module id, used for deriving its sovereign account ID. + #[pallet::constant] + type ModuleId: Get; -decl_event!( - pub enum Event - where - Balance = BalanceOf, - ::AccountId, - { - /// New proposal. \[proposal_index\] - Proposed(ProposalIndex), - /// We have ended a spend period and will now allocate funds. \[budget_remaining\] - Spending(Balance), - /// Some funds have been allocated. \[proposal_index, award, beneficiary\] - Awarded(ProposalIndex, Balance, AccountId), - /// A proposal was rejected; funds were slashed. \[proposal_index, slashed\] - Rejected(ProposalIndex, Balance), - /// Some of our funds have been burnt. \[burn\] - Burnt(Balance), - /// Spending has finished; this is the amount that rolls over until next spend. - /// \[budget_remaining\] - Rollover(Balance), - /// Some funds have been deposited. \[deposit\] - Deposit(Balance), - } -); + /// The staking balance. + type Currency: Currency + ReservableCurrency; -decl_error! { - /// Error for the treasury module. - pub enum Error for Module, I: Instance> { - /// Proposer's balance is too low. - InsufficientProposersBalance, - /// No proposal or bounty at that index. - InvalidIndex, - } -} + /// Origin from which approvals must come. + type ApproveOrigin: EnsureOrigin; + + /// Origin from which rejections must come. + type RejectOrigin: EnsureOrigin; + + /// The overarching event type. + type Event: From> + IsType<::Event>; + + /// Handler for the unbalanced decrease when slashing for a rejected proposal or bounty. + type OnSlash: OnUnbalanced>; -decl_module! { - pub struct Module, 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. /// An accepted proposal gets these back. A rejected proposal does not. - const ProposalBond: Permill = T::ProposalBond::get(); + #[pallet::constant] + type ProposalBond: Get; /// Minimum amount of funds that should be placed in a deposit for making a proposal. - const ProposalBondMinimum: BalanceOf = T::ProposalBondMinimum::get(); + #[pallet::constant] + type ProposalBondMinimum: Get>; /// Period between successive spends. - const SpendPeriod: T::BlockNumber = T::SpendPeriod::get(); + #[pallet::constant] + type SpendPeriod: Get; /// Percentage of spare funds (if any) that are burnt per spend period. - const Burn: Permill = T::Burn::get(); + #[pallet::constant] + type Burn: Get; - /// The treasury's module id, used for deriving its sovereign account ID. - const ModuleId: ModuleId = T::ModuleId::get(); + /// Handler for the unbalanced decrease when treasury funds are burned. + type BurnDestination: OnUnbalanced>; - type Error = Error; + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; - fn deposit_event() = default; + /// Runtime hooks to external pallet using treasury to compute spend funds. + type SpendFunds: SpendFunds; + } + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(PhantomData<(T, I)>); + + #[pallet::hooks] + impl, I: 'static> Hooks> for Pallet { + /// `on_initialize` to return the weight used in `spend_funds`. + fn on_initialize(now: T::BlockNumber) -> Weight { + // Check to see if we should spend some funds! + if (now % T::SpendPeriod::get()).is_zero() { + Self::spend_funds() + } else { + 0 + } + } + } + + #[pallet::call] + impl, I: 'static> Pallet { /// Put forward a suggestion for spending. A deposit proportional to the value /// is reserved and slashed if the proposal is rejected. It is returned once the /// proposal is awarded. - /// - /// # - /// - Complexity: O(1) - /// - DbReads: `ProposalCount`, `origin account` - /// - DbWrites: `ProposalCount`, `Proposals`, `origin account` - /// # - #[weight = T::WeightInfo::propose_spend()] + #[pallet::weight(T::WeightInfo::propose_spend())] pub fn propose_spend( - origin, - #[compact] value: BalanceOf, + origin: OriginFor, + #[pallet::compact] value: BalanceOf, beneficiary: ::Source - ) { + ) -> DispatchResultWithPostInfo { let proposer = ensure_signed(origin)?; let beneficiary = T::Lookup::lookup(beneficiary)?; @@ -278,23 +227,32 @@ decl_module! { .map_err(|_| Error::::InsufficientProposersBalance)?; let c = Self::proposal_count(); - >::put(c + 1); - >::insert(c, Proposal { proposer, value, beneficiary, bond }); - - Self::deposit_event(RawEvent::Proposed(c)); + >::put(c + 1); + >::insert( + c, + Proposal::> { + proposer, + value, + beneficiary, + bond, + }, + ); + Self::deposit_event(Event::Proposed(c)); + Ok(().into()) } - /// Reject a proposed spend. The original deposit will be slashed. /// /// May only be called from `T::RejectOrigin`. - /// - /// # - /// - Complexity: O(1) - /// - DbReads: `Proposals`, `rejected proposer account` - /// - DbWrites: `Proposals`, `rejected proposer account` - /// # - #[weight = (T::WeightInfo::reject_proposal(), DispatchClass::Operational)] - pub fn reject_proposal(origin, #[compact] proposal_id: ProposalIndex) { + #[pallet::weight( + ( + T::WeightInfo::reject_proposal(), + DispatchClass::Operational, + ) + )] + pub fn reject_proposal( + origin: OriginFor, + #[pallet::compact] proposal_id: ProposalIndex, + ) -> DispatchResultWithPostInfo { T::RejectOrigin::ensure_origin(origin)?; let proposal = >::take(&proposal_id).ok_or(Error::::InvalidIndex)?; @@ -303,46 +261,136 @@ decl_module! { T::OnSlash::on_unbalanced(imbalance); Self::deposit_event(Event::::Rejected(proposal_id, value)); + Ok(().into()) } - /// Approve a proposal. At a later time, the proposal will be allocated to the beneficiary /// and the original deposit will be returned. /// /// May only be called from `T::ApproveOrigin`. - /// - /// # - /// - Complexity: O(1). - /// - DbReads: `Proposals`, `Approvals` - /// - DbWrite: `Approvals` - /// # - #[weight = (T::WeightInfo::approve_proposal(), DispatchClass::Operational)] - pub fn approve_proposal(origin, #[compact] proposal_id: ProposalIndex) { + #[pallet::weight( + ( + T::WeightInfo::approve_proposal(), + DispatchClass::Operational + ) + )] + pub fn approve_proposal( + origin: OriginFor, + #[pallet::compact] proposal_id: ProposalIndex, + ) -> DispatchResultWithPostInfo { T::ApproveOrigin::ensure_origin(origin)?; ensure!(>::contains_key(proposal_id), Error::::InvalidIndex); - Approvals::::append(proposal_id); + >::append(proposal_id); + Ok(().into()) } + } - /// # - /// - Complexity: `O(A)` where `A` is the number of approvals - /// - Db reads and writes: `Approvals`, `pot account data` - /// - Db reads and writes per approval: - /// `Proposals`, `proposer account data`, `beneficiary account data` - /// - The weight is overestimated if some approvals got missed. - /// # - fn on_initialize(n: T::BlockNumber) -> Weight { - // Check to see if we should spend some funds! - if (n % T::SpendPeriod::get()).is_zero() { - Self::spend_funds() - } else { - 0 + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + #[pallet::metadata(T::AccountId = "AccountId", BalanceOf = "Balance")] + pub enum Event, I: 'static = ()> { + /// New proposal. \[proposal_index\] + Proposed(ProposalIndex), + /// We have ended a spend period and will now allocate funds. \[budget_remaining\] + Spending(BalanceOf), + /// Some funds have been allocated. \[proposal_index, award, beneficiary\] + Awarded(ProposalIndex, BalanceOf, T::AccountId), + /// A proposal was rejected; funds were slashed. \[proposal_index, slashed\] + Rejected(ProposalIndex, BalanceOf), + /// Some of our funds have been burnt. \[burn\] + Burnt(BalanceOf), + /// Spending has finished; this is the amount that rolls over until next spend. + /// \[budget_remaining\] + Rollover(BalanceOf), + /// Some funds have been deposited. \[deposit\] + Deposit(BalanceOf), + } + + /// Old name generated by `decl_event`. + #[deprecated(note = "use `Event` instead")] + pub type RawEvent = Event; + + #[pallet::error] + pub enum Error { + /// Proposer's balance is too low. + InsufficientProposersBalance, + /// No proposal or bounty at that index. + InvalidIndex, + } + + /// Number of proposals that have been made. + #[pallet::storage] + #[pallet::getter(fn proposal_count)] + pub type ProposalCount, I: 'static = ()> = StorageValue<_, ProposalIndex, ValueQuery>; + + /// Proposals that have been made. + #[pallet::storage] + #[pallet::getter(fn proposals)] + pub type Proposals, I: 'static = ()> = StorageMap< + _, + Twox64Concat, + ProposalIndex, + Proposal>, + OptionQuery, + >; + + /// Proposal indices that have been approved but not yet awarded. + #[pallet::storage] + #[pallet::getter(fn approvals)] + pub type Approvals, I: 'static = ()> = + StorageValue<_, Vec, ValueQuery>; + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()>{ + pub phantom: sp_std::marker::PhantomData<(T, I)>, + } + + #[cfg(feature = "std")] + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + Self { + phantom: Default::default(), } } } + + #[pallet::genesis_build] + impl, I: 'static> GenesisBuild for GenesisConfig { + fn build(&self) { + // Create Treasury account + let account_id = >::account_id(); + let min = T::Currency::minimum_balance(); + if T::Currency::free_balance(&account_id) < min { + let _ = T::Currency::make_free_balance_be( + &account_id, + min, + ); + } + } + } +} + +#[cfg(feature = "std")] +impl, I: 'static> GenesisConfig { + /// Direct implementation of `GenesisBuild::build_storage`. + /// + /// Kept in order not to break dependency. + pub fn build_storage(&self) -> Result { + >::build_storage(self) + } + + /// Direct implementation of `GenesisBuild::assimilate_storage`. + /// + /// Kept in order not to break dependency. + pub fn assimilate_storage( + &self, + storage: &mut sp_runtime::Storage + ) -> Result<(), String> { + >::assimilate_storage(self, storage) + } } -impl, I: Instance> Module { - // Add public immutables and private mutables. +impl, I: 'static> Pallet { /// The account ID of the treasury pot. /// @@ -362,12 +410,12 @@ impl, I: Instance> Module { let mut total_weight: Weight = Zero::zero(); let mut budget_remaining = Self::pot(); - Self::deposit_event(RawEvent::Spending(budget_remaining)); + Self::deposit_event(Event::Spending(budget_remaining)); let account_id = Self::account_id(); let mut missed_any = false; let mut imbalance = >::zero(); - let proposals_len = Approvals::::mutate(|v| { + let proposals_len = Approvals::::mutate(|v| { let proposals_approvals_len = v.len() as u32; v.retain(|&index| { // Should always be true, but shouldn't panic if false or we're screwed. @@ -383,7 +431,7 @@ impl, I: Instance> Module { // provide the allocation. imbalance.subsume(T::Currency::deposit_creating(&p.beneficiary, p.value)); - Self::deposit_event(RawEvent::Awarded(index, p.value, p.beneficiary)); + Self::deposit_event(Event::Awarded(index, p.value, p.beneficiary)); false } else { missed_any = true; @@ -409,7 +457,7 @@ impl, I: Instance> Module { let (debit, credit) = T::Currency::pair(burn); imbalance.subsume(debit); T::BurnDestination::on_unbalanced(credit); - Self::deposit_event(RawEvent::Burnt(burn)) + Self::deposit_event(Event::Burnt(burn)) } // Must never be an error, but better to be safe. @@ -427,7 +475,7 @@ impl, I: Instance> Module { drop(problem); } - Self::deposit_event(RawEvent::Rollover(budget_remaining)); + Self::deposit_event(Event::Rollover(budget_remaining)); total_weight } @@ -442,13 +490,13 @@ impl, I: Instance> Module { } -impl, I: Instance> OnUnbalanced> for Module { +impl, I: 'static> OnUnbalanced> for Pallet { fn on_nonzero_unbalanced(amount: NegativeImbalanceOf) { let numeric_amount = amount.peek(); // Must resolve into existing but better to be safe. let _ = T::Currency::resolve_creating(&Self::account_id(), amount); - Self::deposit_event(RawEvent::Deposit(numeric_amount)); + Self::deposit_event(Event::Deposit(numeric_amount)); } } diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 45fc3e629fb0b..3668b5b81071f 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -15,12 +15,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! Treasury pallet tests. +//! Treasury test utilities #![cfg(test)] -use crate as treasury; -use super::*; +use crate::*; +use sp_std::{prelude::*}; + use std::cell::RefCell; use frame_support::{ assert_noop, assert_ok, parameter_types, @@ -29,11 +30,16 @@ use frame_support::{ use sp_core::H256; use sp_runtime::{ - ModuleId, + Permill, ModuleId, testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; +use crate::{ + self as treasury, + Config, +}; + type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -43,9 +49,9 @@ frame_support::construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic, { - System: frame_system::{Pallet, Call, Config, Storage, Event}, + System: frame_system::{Pallet, Call, Storage, Config, Event}, Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Treasury: treasury::{Pallet, Call, Storage, Config, Event}, + Treasury: treasury::{Pallet, Call, Storage, Config, Event}, } ); @@ -121,12 +127,19 @@ impl Config for Test { pub fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - pallet_balances::GenesisConfig::{ - // Total issuance will be 200 with treasury account initialized at ED. + + // Total issuance will be 200 with treasury account initialized at ED. + pallet_balances::GenesisConfig:: { balances: vec![(0, 100), (1, 98), (2, 1)], }.assimilate_storage(&mut t).unwrap(); - treasury::GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); - t.into() + + treasury::GenesisConfig::::default() + .assimilate_storage(&mut t).unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + + ext } #[test] @@ -351,7 +364,7 @@ fn genesis_funding_works() { // Total issuance will be 200 with treasury account initialized with 100. balances: vec![(0, 100), (Treasury::account_id(), initial_funding)], }.assimilate_storage(&mut t).unwrap(); - treasury::GenesisConfig::default().assimilate_storage::(&mut t).unwrap(); + treasury::GenesisConfig::::default().assimilate_storage(&mut t).unwrap(); let mut t: sp_io::TestExternalities = t.into(); t.execute_with(|| {