diff --git a/justfile b/justfile index 5054a31..c5db058 100644 --- a/justfile +++ b/justfile @@ -33,6 +33,13 @@ gen-spec-file env: gen-base-spec @echo "Spec file generated at: tmp/spec/{{env}}.json" +run-benchmarks: + cargo build -r --features runtime-benchmarks + # ./target/release/torus-node benchmark pallet --pallet pallet_torus0 --chain dev --extrinsic "*" --steps 50 --repeat 20 --output pallets/torus0/src/weights.rs --template=./.maintain/frame-weight-template.hbs + ./target/release/torus-node benchmark pallet --pallet pallet_governance --chain dev --extrinsic "*" --steps 50 --repeat 20 --output pallets/governance/src/weights.rs --template=./.maintain/frame-weight-template.hbs + ./target/release/torus-node benchmark pallet --pallet pallet_emission0 --chain dev --extrinsic "*" --steps 50 --repeat 20 --output pallets/emission0/src/weights.rs --template=./.maintain/frame-weight-template.hbs + + # Github Actions run-workflows: diff --git a/pallets/emission0/src/benchmarks.rs b/pallets/emission0/src/benchmarks.rs index e22cd05..765f8f9 100644 --- a/pallets/emission0/src/benchmarks.rs +++ b/pallets/emission0/src/benchmarks.rs @@ -1,3 +1,4 @@ +use pallet_governance_api::GovernanceApi; use pallet_torus0_api::Torus0Api; use polkadot_sdk::{ frame_benchmarking::{account, benchmarks}, @@ -12,6 +13,8 @@ benchmarks! { let module_key: T::AccountId = account("ModuleKey", 0, 2); let module_key2: T::AccountId = account("ModuleKey2", 0, 3); + ::set_allocator(&module_key2); + ::force_register_agent(&module_key, vec![], vec![], vec![])?; ::force_register_agent(&module_key2, vec![], vec![], vec![])?; diff --git a/pallets/emission0/src/weights.rs b/pallets/emission0/src/weights.rs index c773984..c5d7741 100644 --- a/pallets/emission0/src/weights.rs +++ b/pallets/emission0/src/weights.rs @@ -4,17 +4,17 @@ //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 43.0.0 //! DATE: 2025-01-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `Luizs-MacBook-Pro.local`, CPU: `` +//! HOSTNAME: `MacBook-Pro-de-Joao.local`, CPU: `` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: // ./target/release/torus-node // benchmark // pallet -// --chain -// dev // --pallet // pallet_emission0 +// --chain +// dev // --extrinsic // * // --steps @@ -46,8 +46,12 @@ pub trait WeightInfo { /// Weights for `pallet_emission0` using the Substrate node and recommended hardware. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { + /// Storage: `Governance::Allocators` (r:1 w:0) + /// Proof: `Governance::Allocators` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) /// Storage: `Emission0::MaxAllowedWeights` (r:1 w:0) /// Proof: `Emission0::MaxAllowedWeights` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `Emission0::WeightControlDelegation` (r:1 w:0) + /// Proof: `Emission0::WeightControlDelegation` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) /// Storage: `Torus0::Agents` (r:2 w:0) /// Proof: `Torus0::Agents` (`max_values`: None, `max_size`: Some(849), added: 3324, mode: `MaxEncodedLen`) /// Storage: `Torus0::StakedBy` (r:1 w:0) @@ -58,11 +62,11 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Emission0::ConsensusMembers` (`max_values`: None, `max_size`: Some(4294967295), added: 2474, mode: `MaxEncodedLen`) fn set_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `277` + // Measured: `339` // Estimated: `7638` - // Minimum execution time: 18_000_000 picoseconds. - Weight::from_parts(20_000_000, 7638) - .saturating_add(T::DbWeight::get().reads(6_u64)) + // Minimum execution time: 33_000_000 picoseconds. + Weight::from_parts(34_000_000, 7638) + .saturating_add(T::DbWeight::get().reads(8_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Torus0::Agents` (r:2 w:0) @@ -73,8 +77,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `168` // Estimated: `7638` - // Minimum execution time: 12_000_000 picoseconds. - Weight::from_parts(12_000_000, 7638) + // Minimum execution time: 17_000_000 picoseconds. + Weight::from_parts(18_000_000, 7638) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -84,8 +88,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `199` // Estimated: `3529` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(8_000_000, 3529) + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(11_000_000, 3529) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -93,8 +97,12 @@ impl WeightInfo for SubstrateWeight { // For backwards compatibility and tests. impl WeightInfo for () { + /// Storage: `Governance::Allocators` (r:1 w:0) + /// Proof: `Governance::Allocators` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) /// Storage: `Emission0::MaxAllowedWeights` (r:1 w:0) /// Proof: `Emission0::MaxAllowedWeights` (`max_values`: Some(1), `max_size`: Some(2), added: 497, mode: `MaxEncodedLen`) + /// Storage: `Emission0::WeightControlDelegation` (r:1 w:0) + /// Proof: `Emission0::WeightControlDelegation` (`max_values`: None, `max_size`: Some(64), added: 2539, mode: `MaxEncodedLen`) /// Storage: `Torus0::Agents` (r:2 w:0) /// Proof: `Torus0::Agents` (`max_values`: None, `max_size`: Some(849), added: 3324, mode: `MaxEncodedLen`) /// Storage: `Torus0::StakedBy` (r:1 w:0) @@ -105,11 +113,11 @@ impl WeightInfo for () { /// Proof: `Emission0::ConsensusMembers` (`max_values`: None, `max_size`: Some(4294967295), added: 2474, mode: `MaxEncodedLen`) fn set_weights() -> Weight { // Proof Size summary in bytes: - // Measured: `277` + // Measured: `339` // Estimated: `7638` - // Minimum execution time: 18_000_000 picoseconds. - Weight::from_parts(20_000_000, 7638) - .saturating_add(RocksDbWeight::get().reads(6_u64)) + // Minimum execution time: 33_000_000 picoseconds. + Weight::from_parts(34_000_000, 7638) + .saturating_add(RocksDbWeight::get().reads(8_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Torus0::Agents` (r:2 w:0) @@ -120,8 +128,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `168` // Estimated: `7638` - // Minimum execution time: 12_000_000 picoseconds. - Weight::from_parts(12_000_000, 7638) + // Minimum execution time: 17_000_000 picoseconds. + Weight::from_parts(18_000_000, 7638) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -131,8 +139,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `199` // Estimated: `3529` - // Minimum execution time: 7_000_000 picoseconds. - Weight::from_parts(8_000_000, 3529) + // Minimum execution time: 10_000_000 picoseconds. + Weight::from_parts(11_000_000, 3529) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } diff --git a/pallets/governance/api/src/lib.rs b/pallets/governance/api/src/lib.rs index ad2b669..9d60155 100644 --- a/pallets/governance/api/src/lib.rs +++ b/pallets/governance/api/src/lib.rs @@ -10,4 +10,6 @@ pub trait GovernanceApi { fn is_whitelisted(key: &AccountId) -> bool; fn ensure_allocator(key: &AccountId) -> DispatchResult; + + fn set_allocator(key: &AccountId); } diff --git a/pallets/governance/src/benchmarks.rs b/pallets/governance/src/benchmarks.rs index fcb7275..ce2b886 100644 --- a/pallets/governance/src/benchmarks.rs +++ b/pallets/governance/src/benchmarks.rs @@ -15,7 +15,7 @@ fn create_application(module_key: &T::AccountId) { let min_data_len = T::MinApplicationDataLength::get(); let data = vec![0; min_data_len as usize]; - application::submit_application::(module_key.clone(), module_key.clone(), data) + application::submit_application::(module_key.clone(), module_key.clone(), data, false) .expect("failed to submit application"); } @@ -66,7 +66,7 @@ benchmarks! { let min_data_len = T::MinApplicationDataLength::get(); let data = vec![0; min_data_len as usize]; - }: _(RawOrigin::Signed(module_key.clone()), module_key.clone(), data) + }: _(RawOrigin::Signed(module_key.clone()), module_key.clone(), data, false) accept_application { let module_key: T::AccountId = account("ModuleKey", 0, 2); @@ -193,4 +193,14 @@ benchmarks! { disable_vote_delegation { let module_key: T::AccountId = account("ModuleKey", 0, 2); }: _(RawOrigin::Signed(module_key)) + + add_emission_proposal { + let module_key: T::AccountId = account("ModuleKey", 0, 2); + let data = vec![0]; + + let config = crate::GlobalGovernanceConfig::::get(); + let cost = config.proposal_cost; + let _ = ::Currency::deposit_creating(&module_key, cost); + + }: _(RawOrigin::Signed(module_key.clone()), Percent::from_parts(40), Percent::from_parts(40), data) } diff --git a/pallets/governance/src/lib.rs b/pallets/governance/src/lib.rs index 0e2588e..d1240a6 100644 --- a/pallets/governance/src/lib.rs +++ b/pallets/governance/src/lib.rs @@ -305,6 +305,23 @@ pub mod pallet { let delegator = ensure_signed(origin)?; voting::disable_delegation::(delegator) } + + #[pallet::call_index(17)] + #[pallet::weight((::WeightInfo::add_emission_proposal(), DispatchClass::Normal, Pays::Yes))] + pub fn add_emission_proposal( + origin: OriginFor, + recycling_percentage: Percent, + treasury_percentage: Percent, + data: Vec, + ) -> DispatchResult { + let proposer = ensure_signed(origin)?; + proposal::add_emission_proposal::( + proposer, + recycling_percentage, + treasury_percentage, + data, + ) + } } #[pallet::event] @@ -425,6 +442,8 @@ pub mod pallet { InvalidMinWeightControlFee, /// Invalid minimum staking fee in proposal InvalidMinStakingFee, + /// Invalid params given to Emission proposal + InvalidEmissionProposalData, } } @@ -444,4 +463,8 @@ impl pallet_governance_api::GovernanceApi for Pallet fn ensure_allocator(key: &T::AccountId) -> DispatchResult { crate::roles::ensure_allocator::(key) } + + fn set_allocator(key: &T::AccountId) { + crate::Allocators::::insert(key, ()); + } } diff --git a/pallets/governance/src/proposal.rs b/pallets/governance/src/proposal.rs index 5357d50..b6716da 100644 --- a/pallets/governance/src/proposal.rs +++ b/pallets/governance/src/proposal.rs @@ -12,6 +12,7 @@ use codec::{Decode, Encode, MaxEncodedLen}; use polkadot_sdk::frame_election_provider_support::Get; use polkadot_sdk::frame_support::traits::Currency; use polkadot_sdk::frame_support::traits::WithdrawReasons; +use polkadot_sdk::polkadot_sdk_frame::traits::CheckedAdd; use polkadot_sdk::sp_runtime::SaturatedConversion; use polkadot_sdk::sp_std::{collections::btree_set::BTreeSet, vec::Vec}; use polkadot_sdk::{ @@ -24,7 +25,7 @@ use substrate_fixed::types::I92F36; pub type ProposalId = u64; -#[derive(DebugNoBound, TypeInfo, Decode, Encode, MaxEncodedLen)] +#[derive(Clone, DebugNoBound, TypeInfo, Decode, Encode, MaxEncodedLen)] #[scale_info(skip_type_params(T))] pub struct Proposal { pub id: ProposalId, @@ -44,6 +45,13 @@ impl Proposal { matches!(self.status, ProposalStatus::Open { .. }) } + pub fn execution_block(&self) -> Block { + match self.data { + ProposalData::Emission { .. } => self.creation_block + 21_600, + _ => self.expiration_block, + } + } + /// Marks a proposal as accepted and overrides the storage value. pub fn accept( mut self, @@ -250,11 +258,15 @@ impl GlobalParamsData { } } -#[derive(DebugNoBound, TypeInfo, Decode, Encode, MaxEncodedLen, PartialEq, Eq)] +#[derive(Clone, DebugNoBound, TypeInfo, Decode, Encode, MaxEncodedLen, PartialEq, Eq)] #[scale_info(skip_type_params(T))] pub enum ProposalData { GlobalParams(GlobalParamsData), GlobalCustom, + Emission { + recycling_percentage: Percent, + treasury_percentage: Percent, + }, TransferDaoTreasury { account: AccountIdOf, amount: BalanceOf, @@ -265,6 +277,7 @@ impl ProposalData { #[must_use] pub fn required_stake(&self) -> Percent { match self { + Self::Emission { .. } => Percent::from_parts(10), Self::GlobalCustom | Self::TransferDaoTreasury { .. } => Percent::from_parts(50), Self::GlobalParams { .. } => Percent::from_parts(40), } @@ -312,6 +325,27 @@ pub fn add_dao_treasury_transfer_proposal( add_proposal::(proposer, data, metadata) } +pub fn add_emission_proposal( + proposer: AccountIdOf, + recycling_percentage: Percent, + treasury_percentage: Percent, + metadata: Vec, +) -> DispatchResult { + ensure!( + recycling_percentage + .checked_add(&treasury_percentage) + .is_some(), + crate::Error::::InvalidEmissionProposalData + ); + + let data = ProposalData::::Emission { + recycling_percentage, + treasury_percentage, + }; + + add_proposal::(proposer, data, metadata) +} + fn add_proposal( proposer: AccountIdOf, data: ProposalData, @@ -442,7 +476,10 @@ fn tick_proposal( *stake_for = stake_for_sum; *stake_against = stake_against_sum; } - Proposals::::set(proposal.id, Some(proposal)); + Proposals::::set(proposal.id, Some(proposal.clone())); + } + + if block_number < proposal.execution_block() { return Ok(()); } @@ -450,6 +487,27 @@ fn tick_proposal( let minimal_stake_to_execute = get_minimal_stake_to_execute_with_percentage::(proposal.data.required_stake()); + if total_stake >= minimal_stake_to_execute { + create_unrewarded_proposal::(proposal.id, block_number, votes_for, votes_against); + if stake_against_sum > stake_for_sum { + proposal.refuse(block_number, stake_for_sum, stake_against_sum) + } else { + proposal.accept(block_number, stake_for_sum, stake_against_sum) + } + } else if block_number >= proposal.expiration_block { + create_unrewarded_proposal::(proposal.id, block_number, votes_for, votes_against); + proposal.expire(block_number) + } else { + Ok(()) + } +} + +fn create_unrewarded_proposal( + proposal_id: u64, + block_number: Block, + votes_for: Vec<(AccountIdOf, BalanceOf)>, + votes_against: Vec<(AccountIdOf, BalanceOf)>, +) { let mut reward_votes_for = BoundedBTreeMap::new(); for (key, value) in votes_for { reward_votes_for @@ -469,23 +527,13 @@ fn tick_proposal( } UnrewardedProposals::::insert( - proposal.id, + proposal_id, UnrewardedProposal:: { block: block_number, votes_for: reward_votes_for, votes_against: reward_votes_against, }, ); - - if total_stake >= minimal_stake_to_execute { - if stake_against_sum > stake_for_sum { - proposal.refuse(block_number, stake_for_sum, stake_against_sum) - } else { - proposal.accept(block_number, stake_for_sum, stake_against_sum) - } - } else { - proposal.expire(block_number) - } } #[inline] diff --git a/pallets/governance/src/weights.rs b/pallets/governance/src/weights.rs index 329c7ea..fb69986 100644 --- a/pallets/governance/src/weights.rs +++ b/pallets/governance/src/weights.rs @@ -4,17 +4,17 @@ //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 43.0.0 //! DATE: 2025-01-03, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! WORST CASE MAP SIZE: `1000000` -//! HOSTNAME: `Luizs-MacBook-Pro.local`, CPU: `` +//! HOSTNAME: `MacBook-Pro-de-Joao.local`, CPU: `` //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` // Executed Command: -// target/release/torus-node +// ./target/release/torus-node // benchmark // pallet -// --chain -// dev // --pallet // pallet_governance +// --chain +// dev // --extrinsic // * // --steps @@ -55,6 +55,7 @@ pub trait WeightInfo { fn remove_vote_proposal() -> Weight; fn enable_vote_delegation() -> Weight; fn disable_vote_delegation() -> Weight; + fn add_emission_proposal() -> Weight; } /// Weights for `pallet_governance` using the Substrate node and recommended hardware. @@ -66,8 +67,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6` // Estimated: `3497` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(5_000_000, 3497) + // Minimum execution time: 6_000_000 picoseconds. + Weight::from_parts(7_000_000, 3497) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -77,8 +78,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `60` // Estimated: `3497` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(6_000_000, 3497) + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 3497) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -88,8 +89,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6` // Estimated: `3497` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(5_000_000, 3497) + // Minimum execution time: 6_000_000 picoseconds. + Weight::from_parts(7_000_000, 3497) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -99,8 +100,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `62` // Estimated: `3497` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(6_000_000, 3497) + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 3497) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -108,76 +109,78 @@ impl WeightInfo for SubstrateWeight { /// Proof: `Governance::Curators` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) /// Storage: `Governance::Whitelist` (r:1 w:1) /// Proof: `Governance::Whitelist` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) + /// Storage: `Governance::AgentApplications` (r:1 w:0) + /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(357), added: 2832, mode: `MaxEncodedLen`) fn add_to_whitelist() -> Weight { // Proof Size summary in bytes: - // Measured: `60` - // Estimated: `3497` - // Minimum execution time: 9_000_000 picoseconds. - Weight::from_parts(10_000_000, 3497) - .saturating_add(T::DbWeight::get().reads(2_u64)) + // Measured: `66` + // Estimated: `3822` + // Minimum execution time: 17_000_000 picoseconds. + Weight::from_parts(18_000_000, 3822) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Governance::Curators` (r:1 w:0) /// Proof: `Governance::Curators` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) /// Storage: `Governance::Whitelist` (r:1 w:1) /// Proof: `Governance::Whitelist` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) + /// Storage: `Governance::AgentApplications` (r:1 w:0) + /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(357), added: 2832, mode: `MaxEncodedLen`) /// Storage: `Torus0::Agents` (r:1 w:0) /// Proof: `Torus0::Agents` (`max_values`: None, `max_size`: Some(849), added: 3324, mode: `MaxEncodedLen`) fn remove_from_whitelist() -> Weight { // Proof Size summary in bytes: - // Measured: `124` + // Measured: `130` // Estimated: `4314` - // Minimum execution time: 14_000_000 picoseconds. - Weight::from_parts(14_000_000, 4314) - .saturating_add(T::DbWeight::get().reads(3_u64)) + // Minimum execution time: 23_000_000 picoseconds. + Weight::from_parts(24_000_000, 4314) + .saturating_add(T::DbWeight::get().reads(4_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } /// Storage: `Governance::Whitelist` (r:1 w:0) /// Proof: `Governance::Whitelist` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) + /// Storage: `Governance::AgentApplications` (r:1 w:1) + /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(357), added: 2832, mode: `MaxEncodedLen`) /// Storage: `Governance::GlobalGovernanceConfig` (r:1 w:0) /// Proof: `Governance::GlobalGovernanceConfig` (`max_values`: Some(1), `max_size`: Some(73), added: 568, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Governance::AgentApplicationId` (r:1 w:1) - /// Proof: `Governance::AgentApplicationId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Governance::AgentApplications` (r:0 w:1) - /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(354), added: 2829, mode: `MaxEncodedLen`) fn submit_application() -> Weight { // Proof Size summary in bytes: - // Measured: `146` - // Estimated: `3593` - // Minimum execution time: 29_000_000 picoseconds. - Weight::from_parts(30_000_000, 3593) + // Measured: `152` + // Estimated: `3822` + // Minimum execution time: 45_000_000 picoseconds. + Weight::from_parts(46_000_000, 3822) .saturating_add(T::DbWeight::get().reads(4_u64)) - .saturating_add(T::DbWeight::get().writes(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) } /// Storage: `Governance::Curators` (r:1 w:0) /// Proof: `Governance::Curators` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) /// Storage: `Governance::AgentApplications` (r:1 w:1) - /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(354), added: 2829, mode: `MaxEncodedLen`) - /// Storage: `Governance::Whitelist` (r:1 w:1) - /// Proof: `Governance::Whitelist` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) + /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(357), added: 2832, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Governance::Whitelist` (r:0 w:1) + /// Proof: `Governance::Whitelist` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) fn accept_application() -> Weight { // Proof Size summary in bytes: - // Measured: `262` - // Estimated: `3819` - // Minimum execution time: 37_000_000 picoseconds. - Weight::from_parts(38_000_000, 3819) - .saturating_add(T::DbWeight::get().reads(4_u64)) + // Measured: `241` + // Estimated: `3822` + // Minimum execution time: 46_000_000 picoseconds. + Weight::from_parts(48_000_000, 3822) + .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(3_u64)) } /// Storage: `Governance::Curators` (r:1 w:0) /// Proof: `Governance::Curators` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) /// Storage: `Governance::AgentApplications` (r:1 w:1) - /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(354), added: 2829, mode: `MaxEncodedLen`) + /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(357), added: 2832, mode: `MaxEncodedLen`) fn deny_application() -> Weight { // Proof Size summary in bytes: - // Measured: `210` - // Estimated: `3819` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(14_000_000, 3819) + // Measured: `189` + // Estimated: `3822` + // Minimum execution time: 18_000_000 picoseconds. + Weight::from_parts(19_000_000, 3822) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -189,8 +192,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `170` // Estimated: `4314` - // Minimum execution time: 10_000_000 picoseconds. - Weight::from_parts(11_000_000, 4314) + // Minimum execution time: 15_000_000 picoseconds. + Weight::from_parts(15_000_000, 4314) .saturating_add(T::DbWeight::get().reads(2_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -204,8 +207,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `152` // Estimated: `3593` - // Minimum execution time: 27_000_000 picoseconds. - Weight::from_parts(28_000_000, 3593) + // Minimum execution time: 38_000_000 picoseconds. + Weight::from_parts(40_000_000, 3593) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -219,8 +222,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `152` // Estimated: `3593` - // Minimum execution time: 27_000_000 picoseconds. - Weight::from_parts(28_000_000, 3593) + // Minimum execution time: 38_000_000 picoseconds. + Weight::from_parts(39_000_000, 3593) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -234,8 +237,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `152` // Estimated: `3593` - // Minimum execution time: 27_000_000 picoseconds. - Weight::from_parts(29_000_000, 3593) + // Minimum execution time: 38_000_000 picoseconds. + Weight::from_parts(39_000_000, 3593) .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(2_u64)) } @@ -251,8 +254,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `316` // Estimated: `6100` - // Minimum execution time: 22_000_000 picoseconds. - Weight::from_parts(23_000_000, 6100) + // Minimum execution time: 31_000_000 picoseconds. + Weight::from_parts(33_000_000, 6100) .saturating_add(T::DbWeight::get().reads(5_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -262,8 +265,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `216` // Estimated: `3464` - // Minimum execution time: 10_000_000 picoseconds. - Weight::from_parts(11_000_000, 3464) + // Minimum execution time: 15_000_000 picoseconds. + Weight::from_parts(15_000_000, 3464) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -273,8 +276,8 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6` // Estimated: `1484` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(4_000_000, 1484) + // Minimum execution time: 5_000_000 picoseconds. + Weight::from_parts(5_000_000, 1484) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } @@ -284,11 +287,26 @@ impl WeightInfo for SubstrateWeight { // Proof Size summary in bytes: // Measured: `6` // Estimated: `1484` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(4_000_000, 1484) + // Minimum execution time: 5_000_000 picoseconds. + Weight::from_parts(5_000_000, 1484) .saturating_add(T::DbWeight::get().reads(1_u64)) .saturating_add(T::DbWeight::get().writes(1_u64)) } + /// Storage: `Governance::GlobalGovernanceConfig` (r:1 w:0) + /// Proof: `Governance::GlobalGovernanceConfig` (`max_values`: Some(1), `max_size`: Some(73), added: 568, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Governance::Proposals` (r:1 w:1) + /// Proof: `Governance::Proposals` (`max_values`: None, `max_size`: Some(4294967295), added: 2474, mode: `MaxEncodedLen`) + fn add_emission_proposal() -> Weight { + // Proof Size summary in bytes: + // Measured: `152` + // Estimated: `3593` + // Minimum execution time: 37_000_000 picoseconds. + Weight::from_parts(38_000_000, 3593) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(2_u64)) + } } // For backwards compatibility and tests. @@ -299,8 +317,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6` // Estimated: `3497` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(5_000_000, 3497) + // Minimum execution time: 6_000_000 picoseconds. + Weight::from_parts(7_000_000, 3497) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -310,8 +328,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `60` // Estimated: `3497` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(6_000_000, 3497) + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 3497) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -321,8 +339,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6` // Estimated: `3497` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(5_000_000, 3497) + // Minimum execution time: 6_000_000 picoseconds. + Weight::from_parts(7_000_000, 3497) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -332,8 +350,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `62` // Estimated: `3497` - // Minimum execution time: 6_000_000 picoseconds. - Weight::from_parts(6_000_000, 3497) + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 3497) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -341,76 +359,78 @@ impl WeightInfo for () { /// Proof: `Governance::Curators` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) /// Storage: `Governance::Whitelist` (r:1 w:1) /// Proof: `Governance::Whitelist` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) + /// Storage: `Governance::AgentApplications` (r:1 w:0) + /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(357), added: 2832, mode: `MaxEncodedLen`) fn add_to_whitelist() -> Weight { // Proof Size summary in bytes: - // Measured: `60` - // Estimated: `3497` - // Minimum execution time: 9_000_000 picoseconds. - Weight::from_parts(10_000_000, 3497) - .saturating_add(RocksDbWeight::get().reads(2_u64)) + // Measured: `66` + // Estimated: `3822` + // Minimum execution time: 17_000_000 picoseconds. + Weight::from_parts(18_000_000, 3822) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Governance::Curators` (r:1 w:0) /// Proof: `Governance::Curators` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) /// Storage: `Governance::Whitelist` (r:1 w:1) /// Proof: `Governance::Whitelist` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) + /// Storage: `Governance::AgentApplications` (r:1 w:0) + /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(357), added: 2832, mode: `MaxEncodedLen`) /// Storage: `Torus0::Agents` (r:1 w:0) /// Proof: `Torus0::Agents` (`max_values`: None, `max_size`: Some(849), added: 3324, mode: `MaxEncodedLen`) fn remove_from_whitelist() -> Weight { // Proof Size summary in bytes: - // Measured: `124` + // Measured: `130` // Estimated: `4314` - // Minimum execution time: 14_000_000 picoseconds. - Weight::from_parts(14_000_000, 4314) - .saturating_add(RocksDbWeight::get().reads(3_u64)) + // Minimum execution time: 23_000_000 picoseconds. + Weight::from_parts(24_000_000, 4314) + .saturating_add(RocksDbWeight::get().reads(4_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } /// Storage: `Governance::Whitelist` (r:1 w:0) /// Proof: `Governance::Whitelist` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) + /// Storage: `Governance::AgentApplications` (r:1 w:1) + /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(357), added: 2832, mode: `MaxEncodedLen`) /// Storage: `Governance::GlobalGovernanceConfig` (r:1 w:0) /// Proof: `Governance::GlobalGovernanceConfig` (`max_values`: Some(1), `max_size`: Some(73), added: 568, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) - /// Storage: `Governance::AgentApplicationId` (r:1 w:1) - /// Proof: `Governance::AgentApplicationId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) - /// Storage: `Governance::AgentApplications` (r:0 w:1) - /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(354), added: 2829, mode: `MaxEncodedLen`) fn submit_application() -> Weight { // Proof Size summary in bytes: - // Measured: `146` - // Estimated: `3593` - // Minimum execution time: 29_000_000 picoseconds. - Weight::from_parts(30_000_000, 3593) + // Measured: `152` + // Estimated: `3822` + // Minimum execution time: 45_000_000 picoseconds. + Weight::from_parts(46_000_000, 3822) .saturating_add(RocksDbWeight::get().reads(4_u64)) - .saturating_add(RocksDbWeight::get().writes(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) } /// Storage: `Governance::Curators` (r:1 w:0) /// Proof: `Governance::Curators` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) /// Storage: `Governance::AgentApplications` (r:1 w:1) - /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(354), added: 2829, mode: `MaxEncodedLen`) - /// Storage: `Governance::Whitelist` (r:1 w:1) - /// Proof: `Governance::Whitelist` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) + /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(357), added: 2832, mode: `MaxEncodedLen`) /// Storage: `System::Account` (r:1 w:1) /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Governance::Whitelist` (r:0 w:1) + /// Proof: `Governance::Whitelist` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) fn accept_application() -> Weight { // Proof Size summary in bytes: - // Measured: `262` - // Estimated: `3819` - // Minimum execution time: 37_000_000 picoseconds. - Weight::from_parts(38_000_000, 3819) - .saturating_add(RocksDbWeight::get().reads(4_u64)) + // Measured: `241` + // Estimated: `3822` + // Minimum execution time: 46_000_000 picoseconds. + Weight::from_parts(48_000_000, 3822) + .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(3_u64)) } /// Storage: `Governance::Curators` (r:1 w:0) /// Proof: `Governance::Curators` (`max_values`: None, `max_size`: Some(32), added: 2507, mode: `MaxEncodedLen`) /// Storage: `Governance::AgentApplications` (r:1 w:1) - /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(354), added: 2829, mode: `MaxEncodedLen`) + /// Proof: `Governance::AgentApplications` (`max_values`: None, `max_size`: Some(357), added: 2832, mode: `MaxEncodedLen`) fn deny_application() -> Weight { // Proof Size summary in bytes: - // Measured: `210` - // Estimated: `3819` - // Minimum execution time: 13_000_000 picoseconds. - Weight::from_parts(14_000_000, 3819) + // Measured: `189` + // Estimated: `3822` + // Minimum execution time: 18_000_000 picoseconds. + Weight::from_parts(19_000_000, 3822) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -422,8 +442,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `170` // Estimated: `4314` - // Minimum execution time: 10_000_000 picoseconds. - Weight::from_parts(11_000_000, 4314) + // Minimum execution time: 15_000_000 picoseconds. + Weight::from_parts(15_000_000, 4314) .saturating_add(RocksDbWeight::get().reads(2_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -437,8 +457,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `152` // Estimated: `3593` - // Minimum execution time: 27_000_000 picoseconds. - Weight::from_parts(28_000_000, 3593) + // Minimum execution time: 38_000_000 picoseconds. + Weight::from_parts(40_000_000, 3593) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -452,8 +472,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `152` // Estimated: `3593` - // Minimum execution time: 27_000_000 picoseconds. - Weight::from_parts(28_000_000, 3593) + // Minimum execution time: 38_000_000 picoseconds. + Weight::from_parts(39_000_000, 3593) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -467,8 +487,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `152` // Estimated: `3593` - // Minimum execution time: 27_000_000 picoseconds. - Weight::from_parts(29_000_000, 3593) + // Minimum execution time: 38_000_000 picoseconds. + Weight::from_parts(39_000_000, 3593) .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(2_u64)) } @@ -484,8 +504,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `316` // Estimated: `6100` - // Minimum execution time: 22_000_000 picoseconds. - Weight::from_parts(23_000_000, 6100) + // Minimum execution time: 31_000_000 picoseconds. + Weight::from_parts(33_000_000, 6100) .saturating_add(RocksDbWeight::get().reads(5_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -495,8 +515,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `216` // Estimated: `3464` - // Minimum execution time: 10_000_000 picoseconds. - Weight::from_parts(11_000_000, 3464) + // Minimum execution time: 15_000_000 picoseconds. + Weight::from_parts(15_000_000, 3464) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -506,8 +526,8 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6` // Estimated: `1484` - // Minimum execution time: 3_000_000 picoseconds. - Weight::from_parts(4_000_000, 1484) + // Minimum execution time: 5_000_000 picoseconds. + Weight::from_parts(5_000_000, 1484) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } @@ -517,9 +537,24 @@ impl WeightInfo for () { // Proof Size summary in bytes: // Measured: `6` // Estimated: `1484` - // Minimum execution time: 4_000_000 picoseconds. - Weight::from_parts(4_000_000, 1484) + // Minimum execution time: 5_000_000 picoseconds. + Weight::from_parts(5_000_000, 1484) .saturating_add(RocksDbWeight::get().reads(1_u64)) .saturating_add(RocksDbWeight::get().writes(1_u64)) } + /// Storage: `Governance::GlobalGovernanceConfig` (r:1 w:0) + /// Proof: `Governance::GlobalGovernanceConfig` (`max_values`: Some(1), `max_size`: Some(73), added: 568, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `Governance::Proposals` (r:1 w:1) + /// Proof: `Governance::Proposals` (`max_values`: None, `max_size`: Some(4294967295), added: 2474, mode: `MaxEncodedLen`) + fn add_emission_proposal() -> Weight { + // Proof Size summary in bytes: + // Measured: `152` + // Estimated: `3593` + // Minimum execution time: 37_000_000 picoseconds. + Weight::from_parts(38_000_000, 3593) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(2_u64)) + } } diff --git a/pallets/governance/tests/voting.rs b/pallets/governance/tests/voting.rs index 8a08525..171846d 100644 --- a/pallets/governance/tests/voting.rs +++ b/pallets/governance/tests/voting.rs @@ -3,7 +3,8 @@ use pallet_governance::{ proposal::{GlobalParamsData, ProposalStatus}, DaoTreasuryAddress, Error, GlobalGovernanceConfig, Proposals, }; -use polkadot_sdk::frame_support::assert_err; +use polkadot_sdk::frame_support::traits::Get; +use polkadot_sdk::{frame_support::assert_err, sp_runtime::BoundedBTreeSet}; use polkadot_sdk::{frame_support::assert_ok, sp_runtime::Percent}; use test_utils::{ add_balance, get_balance, get_origin, new_test_ext, step_block, to_nano, zero_min_burn, @@ -349,6 +350,163 @@ fn creates_treasury_transfer_proposal_and_transfers() { }); } +#[test] +fn creates_emission_proposal_and_it_runs_after_2_days() { + new_test_ext().execute_with(|| { + zero_min_burn(); + + let default_proposal_expiration: u64 = + ::DefaultProposalExpiration::get(); + + config(1, default_proposal_expiration); + + let origin = get_origin(0); + add_balance(0, to_nano(2)); + register(0, 0, 0, to_nano(1)); + pallet_torus0::TotalStake::::set(to_nano(10)); + + assert_ok!(pallet_governance::Pallet::::add_emission_proposal( + origin.clone(), + Percent::from_parts(20), + Percent::from_parts(20), + vec![b'0'; 64], + )); + + vote(0, 0, true); + + step_block(21_600); + + assert_eq!( + Proposals::::get(0).unwrap().status, + ProposalStatus::Accepted { + block: 21_600, + stake_for: to_nano(1), + stake_against: 0 + } + ); + }); +} + +#[test] +fn creates_emission_proposal_and_it_runs_before_expiration() { + new_test_ext().execute_with(|| { + zero_min_burn(); + + let default_proposal_expiration: u64 = + ::DefaultProposalExpiration::get(); + + let min_stake: u128 = ::DefaultMinAllowedStake::get(); + + config(1, default_proposal_expiration); + + let origin = get_origin(0); + add_balance(0, to_nano(2)); + register(0, 0, 0, to_nano(1) - min_stake); + pallet_torus0::TotalStake::::set(to_nano(10)); + + assert_ok!(pallet_governance::Pallet::::add_emission_proposal( + origin.clone(), + Percent::from_parts(20), + Percent::from_parts(20), + vec![b'0'; 64], + )); + + vote(0, 0, true); + + step_block(21_600); + + let mut votes_for = BoundedBTreeSet::new(); + votes_for.try_insert(0).unwrap(); + + assert_eq!( + Proposals::::get(0).unwrap().status, + ProposalStatus::Open { + votes_for, + votes_against: BoundedBTreeSet::new(), + stake_for: to_nano(1) - min_stake, + stake_against: 0 + } + ); + + stake(0, 0, min_stake); + pallet_torus0::TotalStake::::set(to_nano(10)); + + step_block(100); + + assert_eq!( + Proposals::::get(0).unwrap().status, + ProposalStatus::Accepted { + block: 21_700, + stake_for: to_nano(1), + stake_against: 0 + } + ); + }); +} + +#[test] +fn creates_emission_proposal_and_it_expires() { + new_test_ext().execute_with(|| { + zero_min_burn(); + + let default_proposal_expiration: u64 = + ::DefaultProposalExpiration::get(); + + let min_stake: u128 = ::DefaultMinAllowedStake::get(); + + config(1, default_proposal_expiration); + + let origin = get_origin(0); + add_balance(0, to_nano(2)); + register(0, 0, 0, to_nano(1) - min_stake); + pallet_torus0::TotalStake::::set(to_nano(10)); + + assert_ok!(pallet_governance::Pallet::::add_emission_proposal( + origin.clone(), + Percent::from_parts(20), + Percent::from_parts(20), + vec![b'0'; 64], + )); + + vote(0, 0, true); + + step_block(default_proposal_expiration); + + assert_eq!( + Proposals::::get(0).unwrap().status, + ProposalStatus::Expired + ); + }); +} + +#[test] +fn creates_emission_proposal_with_invalid_params_and_it_fails() { + new_test_ext().execute_with(|| { + zero_min_burn(); + + let default_proposal_expiration: u64 = + ::DefaultProposalExpiration::get(); + + let min_stake: u128 = ::DefaultMinAllowedStake::get(); + + config(1, default_proposal_expiration); + + let origin = get_origin(0); + add_balance(0, to_nano(2)); + register(0, 0, 0, to_nano(1) - min_stake); + + assert_err!( + pallet_governance::Pallet::::add_emission_proposal( + origin.clone(), + Percent::from_parts(51), + Percent::from_parts(50), + vec![b'0'; 64], + ), + Error::::InvalidEmissionProposalData + ); + }); +} + #[test] fn rewards_wont_exceed_treasury() { new_test_ext().execute_with(|| { diff --git a/test-utils/src/lib.rs b/test-utils/src/lib.rs index 8a47c5c..227f411 100644 --- a/test-utils/src/lib.rs +++ b/test-utils/src/lib.rs @@ -101,6 +101,10 @@ impl pallet_governance_api::GovernanceApi for Test { fn ensure_allocator(key: &AccountId) -> DispatchResult { pallet_governance::roles::ensure_allocator::(key) } + + fn set_allocator(key: &AccountId) { + pallet_governance::Allocators::::insert(key, ()); + } } impl pallet_torus0::Config for Test {