From ba9e583c7125a7c3faa9e81b616b276ef18e9368 Mon Sep 17 00:00:00 2001 From: f-gate Date: Wed, 14 Jun 2023 11:02:24 +0100 Subject: [PATCH 1/6] reversable storage hasher, errors more semantic, increase coverage --- pallets/crowdfunding/Cargo.toml | 7 +++++-- pallets/crowdfunding/src/lib.rs | 31 ++++++++++++++++++------------- pallets/crowdfunding/src/tests.rs | 21 +++++++++++++++++++++ 3 files changed, 44 insertions(+), 15 deletions(-) diff --git a/pallets/crowdfunding/Cargo.toml b/pallets/crowdfunding/Cargo.toml index e69ae289..4ecaa1fe 100644 --- a/pallets/crowdfunding/Cargo.toml +++ b/pallets/crowdfunding/Cargo.toml @@ -27,6 +27,7 @@ pallet-identity = { git = "https://github.com/paritytech/substrate", branch = "p orml-traits = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.39", default-features = false } common-types = { path = "../../libs/common-types", default-features = false } +common-runtime = { path = "../../runtime/common", default-features = false} pallet-proposals = { path= "../proposals", default-features = false} pallet-deposits = {path= "../deposits", default-features = false } @@ -36,6 +37,7 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkad sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.39"} pallet-proposals = { path= "../proposals"} common-types = { path = "../../libs/common-types"} +common-runtime = { path = "../../runtime/common"} sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.39"} pallet-identity = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.39"} orml-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", branch = "polkadot-v0.9.39" } @@ -57,8 +59,9 @@ std = [ "pallet-proposals/std", "sp-core/std", "pallet-identity/std", - "pallet-xcm/std" + "pallet-xcm/std", + "common-runtime/std", ] -runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks", "pallet-xcm/runtime-benchmarks"] +runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "common-runtime/runtime-benchmarks"] try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/crowdfunding/src/lib.rs b/pallets/crowdfunding/src/lib.rs index 291aa45b..49f01edf 100644 --- a/pallets/crowdfunding/src/lib.rs +++ b/pallets/crowdfunding/src/lib.rs @@ -79,13 +79,13 @@ pub mod pallet { /// Stores a list of crowdfunds. #[pallet::storage] - pub type CrowdFunds = StorageMap<_, Blake2_128, CrowdFundKey, CrowdFund, OptionQuery>; + pub type CrowdFunds = StorageMap<_, Blake2_128Concat, CrowdFundKey, CrowdFund, OptionQuery>; /// Stores the crowdfund keys that are expiring on a given block. /// Handled in the hooks, #[pallet::storage] pub type RoundsExpiring = - StorageMap<_, Blake2_128, BlockNumberFor, BoundedKeysPerRound, ValueQuery>; + StorageMap<_, Blake2_128Concat, BlockNumberFor, BoundedKeysPerRound, ValueQuery>; /// Tracks wether CrowdFunds are in a given round type. /// Key 1 : CrowdFundID @@ -94,15 +94,17 @@ pub mod pallet { #[pallet::storage] pub type CrowdFundsInRound = StorageDoubleMap< _, - Blake2_128, + Blake2_128Concat, CrowdFundKey, - Blake2_128, + Blake2_128Concat, RoundType, BlockNumberFor, ValueQuery, >; /// Tracks the whitelists of a given crowdfund. + /// MIGRATION FROM PROPOSALS REFACTOR? + /// PALLET PREFIX HAS CHANGED #[pallet::storage] #[pallet::getter(fn whitelist_spots)] pub type WhitelistSpots = @@ -173,6 +175,10 @@ pub mod pallet { CrowdFundCancelled, /// The conversion to a Project has failed. CrowdFundConversionFailedGeneric, + /// You are trying to add too many whitelist spots. + WhiteListSpotLimitReached, + /// There are too many rounds inserted this block, please wait for the next on (6s) + TooManyRoundsInBlock, } #[pallet::call] @@ -259,16 +265,15 @@ pub mod pallet { let who = ensure_signed(origin)?; Self::ensure_initiator(who, crowdfund_key)?; let crowdfund_whitelist_spots = WhitelistSpots::::get(crowdfund_key).unwrap_or( - BTreeMap::new() - .try_into() - .expect("Empty BTree is always smaller than bound; qed"), + BoundedBTreeMap::new() ); let mut unbounded = crowdfund_whitelist_spots.into_inner(); unbounded.extend(new_whitelist_spots); let bounded: BoundedWhitelistSpots = - unbounded.try_into().map_err(|_| Error::::Overflow)?; + unbounded.try_into().map_err(|_| Error::::WhiteListSpotLimitReached)?; + >::insert(crowdfund_key, bounded); let now = >::block_number(); Self::deposit_event(Event::WhitelistAdded(crowdfund_key, now)); @@ -459,7 +464,7 @@ pub mod pallet { .saturating_add(::RoundExpiry::get()); RoundsExpiring::::try_mutate(expiry_block, |list| -> DispatchResult { list.try_push(crowdfund_key) - .map_err(|_| Error::::Overflow)?; + .map_err(|_| Error::::TooManyRoundsInBlock)?; Ok(()) })?; CrowdFundsInRound::::insert( @@ -552,8 +557,7 @@ pub mod pallet { crowdfund.initiator, crowdfund.milestones.into_inner(), FundingType::Proposal, - ) - .map_err(|_| Error::::CrowdFundConversionFailedGeneric)?; + )?; CrowdFunds::::mutate(crowdfund_key, |crowdfund| { if let Some(cf) = crowdfund { @@ -561,10 +565,12 @@ pub mod pallet { } Ok::<(), DispatchError>(()) })?; + Self::deposit_event(Event::CrowdFundApproved(crowdfund_key)); Ok(().into()) } + /// Actually calls storage. Could be improved. pub fn ensure_initiator( who: T::AccountId, crowdfund_key: CrowdFundKey, @@ -577,6 +583,7 @@ pub mod pallet { } } + /// Ensure the identity of an account is either Reasonable or KnownGood. fn ensure_identity_is_decent(who: &T::AccountId) -> Result<(), Error> { let identity = pallet_identity::Pallet::::identity(who).ok_or(Error::::IdentityNeeded)?; @@ -607,8 +614,6 @@ pub mod pallet { pub created_on: BlockNumberFor, pub is_converted: bool, } - - // Called to ensure that an account is is a contributor to a crowdfund. } // Warning: This will allow the withdrawal of funds, approve is a governance action so should not be a problem. diff --git a/pallets/crowdfunding/src/tests.rs b/pallets/crowdfunding/src/tests.rs index 8a5828a2..5d9d91c3 100644 --- a/pallets/crowdfunding/src/tests.rs +++ b/pallets/crowdfunding/src/tests.rs @@ -455,3 +455,24 @@ fn on_initialize_removes_contribution_round() { assert!(!RoundsExpiring::::contains_key(expiry_block)); }); } + +#[test] +fn contribute_too_many_contributions() { + new_test_ext().execute_with(|| { + assert!(false) + }); +} + +#[test] +fn approve_fails_as_funding_threshold_wasnt_met() { + new_test_ext().execute_with(|| { + assert!(false) + }); +} + +#[test] +fn too_many_rounds_in_the_block() { + new_test_ext().execute_with(|| { + assert!(false) + }); +} From 79882708e50bcaff7702280e1c0fbc57aa0b79ab Mon Sep 17 00:00:00 2001 From: f-gate Date: Wed, 14 Jun 2023 11:54:18 +0100 Subject: [PATCH 2/6] comments, new tests --- pallets/crowdfunding/src/lib.rs | 13 ++++++++---- pallets/crowdfunding/src/mock.rs | 2 +- pallets/crowdfunding/src/tests.rs | 34 ++++++++++++++++++++++--------- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/pallets/crowdfunding/src/lib.rs b/pallets/crowdfunding/src/lib.rs index 49f01edf..d42235d9 100644 --- a/pallets/crowdfunding/src/lib.rs +++ b/pallets/crowdfunding/src/lib.rs @@ -62,13 +62,21 @@ pub mod pallet { pub trait Config: frame_system::Config + pallet_identity::Config { type RuntimeEvent: From> + IsType<::RuntimeEvent>; type MultiCurrency: MultiReservableCurrency, CurrencyId = CurrencyId>; + /// The length of a round in the system. type RoundExpiry: Get>; + /// The maximum number of crowdfund keys in a given round. type MaxKeysPerRound: Get; + /// The maximum number of contributors possible in a crowdfund. type MaxContributionsPerCrowdFund: Get; + /// The maximum number of milestones that is possible in a crowdfund. type MaxMilestonesPerCrowdFund: Get; + /// The maximum number of whitelist spots in a crowdfund. type MaxWhitelistPerCrowdFund: Get; + /// Define wether a decent identity is required when creating a crowdfund. type IsIdentityRequired: Get; + /// The authority responisble for governance actions. type AuthorityOrigin: EnsureOrigin; + /// The type that converts a crowdfund into a project and allows milestone submission. type IntoProposals: IntoProposal, BalanceOf, BlockNumberFor>; type WeightInfo: WeightInfo; } @@ -223,10 +231,7 @@ pub mod pallet { agreement_hash: Option, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - if ::IsIdentityRequired::get() { - Self::ensure_identity_is_decent(&who)?; - } - + let crowdfund = CrowdFunds::::get(crowdfund_key).ok_or(Error::::CrowdFundDoesNotExist)?; ensure!(crowdfund.initiator == who, Error::::UserIsNotInitiator); diff --git a/pallets/crowdfunding/src/mock.rs b/pallets/crowdfunding/src/mock.rs index 410180bc..634ace4b 100644 --- a/pallets/crowdfunding/src/mock.rs +++ b/pallets/crowdfunding/src/mock.rs @@ -67,7 +67,7 @@ impl frame_system::Config for Test { parameter_types! { pub RoundExpiry: BlockNumber = 100; pub MaxKeysPerRound: u32 = 50; - pub MaxContributionsPerCrowdFund: u32 = 1000; + pub MaxContributionsPerCrowdFund: u32 = 127; pub MaxMilestonesPerCrowdFund: u32 = 50; pub MaxWhitelistPerCrowdFund: u32 = 50; pub MinimumRequiredFunds: Balance = 2000; diff --git a/pallets/crowdfunding/src/tests.rs b/pallets/crowdfunding/src/tests.rs index 5d9d91c3..be5031fb 100644 --- a/pallets/crowdfunding/src/tests.rs +++ b/pallets/crowdfunding/src/tests.rs @@ -5,11 +5,12 @@ use crate::{ }; use common_types::CurrencyId; use frame_support::{assert_noop, assert_ok, traits::Hooks}; -use orml_traits::MultiReservableCurrency; +use orml_traits::{MultiReservableCurrency, MultiCurrency}; use pallet_proposals::ProposedMilestone; use sp_arithmetic::per_things::Percent; use sp_core::H256; use sp_runtime::DispatchError::BadOrigin; +use sp_core::sr25519::{Public}; use test_utils::*; pub(crate) mod test_utils { @@ -459,20 +460,33 @@ fn on_initialize_removes_contribution_round() { #[test] fn contribute_too_many_contributions() { new_test_ext().execute_with(|| { - assert!(false) - }); -} - -#[test] -fn approve_fails_as_funding_threshold_wasnt_met() { - new_test_ext().execute_with(|| { - assert!(false) + let key = create_cf_default(*ALICE, 1_000_000u64); + let max_contributions = ::MaxContributionsPerCrowdFund::get(); + let _ = + CrowdFunding::open_contributions(RuntimeOrigin::root(), key).expect("should be fine."); + (0..max_contributions + 10).for_each(move |i| { + let acc = Public::from_raw([i as u8; 32]); + let _ = ::MultiCurrency::deposit(CurrencyId::Native, &acc, 100_000); + if i < max_contributions { + assert_ok!(CrowdFunding::contribute(RuntimeOrigin::signed(acc), key, 10_000)); + } else { + assert_noop!(CrowdFunding::contribute(RuntimeOrigin::signed(acc), key, 10_000), Error::::TooManyContributions); + } + }); }); } #[test] fn too_many_rounds_in_the_block() { new_test_ext().execute_with(|| { - assert!(false) + let max = ::MaxKeysPerRound::get(); + (0..max + 10).for_each(move |i| { + let key = create_cf_default(*ALICE, 1_000_000u64); + if i < max { + assert_ok!(CrowdFunding::open_contributions(RuntimeOrigin::root(), key)); + } else { + assert_noop!(CrowdFunding::open_contributions(RuntimeOrigin::root(), key), Error::::TooManyRoundsInBlock); + } + }); }); } From dd36626a30be9a19870d757beb4273ddf5f9e6e6 Mon Sep 17 00:00:00 2001 From: f-gate Date: Wed, 14 Jun 2023 14:22:20 +0100 Subject: [PATCH 3/6] crowdfunding storage deposits, add to runtime --- Cargo.lock | 2 ++ pallets/crowdfunding/src/benchmarking.rs | 2 +- pallets/crowdfunding/src/lib.rs | 33 +++++++++++++----------- pallets/crowdfunding/src/mock.rs | 3 +++ pallets/crowdfunding/src/tests.rs | 2 +- runtime/imbue-kusama/Cargo.toml | 3 +++ runtime/imbue-kusama/src/lib.rs | 33 +++++++++++++++++++++++- 7 files changed, 60 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 558fa8b6..a4f46d4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3946,6 +3946,7 @@ dependencies = [ "pallet-briefs", "pallet-collator-selection", "pallet-collective", + "pallet-crowdfunding", "pallet-democracy", "pallet-deposits", "pallet-grants", @@ -6384,6 +6385,7 @@ dependencies = [ name = "pallet-crowdfunding" version = "0.1.0" dependencies = [ + "common-runtime", "common-types", "frame-benchmarking", "frame-support", diff --git a/pallets/crowdfunding/src/benchmarking.rs b/pallets/crowdfunding/src/benchmarking.rs index d70dcb0c..df142c21 100644 --- a/pallets/crowdfunding/src/benchmarking.rs +++ b/pallets/crowdfunding/src/benchmarking.rs @@ -13,7 +13,7 @@ use orml_traits::MultiCurrency; use pallet_proposals::ProposedMilestone; use sp_arithmetic::per_things::Percent; use sp_core::{Get, H256}; -use sp_std::collections::btree_map::BTreeMap; +use sp_std::{vec::Vec, collections::btree_map::BTreeMap}; benchmarks! { where_clause { diff --git a/pallets/crowdfunding/src/lib.rs b/pallets/crowdfunding/src/lib.rs index d42235d9..4843911a 100644 --- a/pallets/crowdfunding/src/lib.rs +++ b/pallets/crowdfunding/src/lib.rs @@ -1,7 +1,7 @@ #![cfg_attr(not(feature = "std"), no_std)] pub use pallet::*; -mod weights; +pub mod weights; #[cfg(test)] mod mock; @@ -26,6 +26,7 @@ pub mod pallet { use sp_arithmetic::per_things::Percent; use sp_core::H256; use sp_std::collections::btree_map::BTreeMap; + use pallet_deposits::traits::DepositHandler; pub type AccountIdOf = ::AccountId; pub type BalanceOf = @@ -46,6 +47,9 @@ pub mod pallet { pub type BoundedProposedMilestones = BoundedVec::MaxMilestonesPerCrowdFund>; + type StorageItemOf = <::DepositHandler as DepositHandler, AccountIdOf>>::StorageItem; + type DepositIdOf = <::DepositHandler as DepositHandler, AccountIdOf>>::DepositId; + pub type CrowdFundKey = u32; pub type MilestoneKey = u32; @@ -78,6 +82,10 @@ pub mod pallet { type AuthorityOrigin: EnsureOrigin; /// The type that converts a crowdfund into a project and allows milestone submission. type IntoProposals: IntoProposal, BalanceOf, BlockNumberFor>; + /// The type reponsible for handling storage deposits. + type DepositHandler: DepositHandler, AccountIdOf>; + /// The type that the deposit fee will be calculated from. + type CrowdFundStorageItem: Get>; type WeightInfo: WeightInfo; } @@ -177,8 +185,6 @@ pub mod pallet { IdentityNeeded, /// Below the minimum required funds. BelowMinimumRequiredFunds, - /// The crowdfund as already been converted to milestones. - CrowdFundAlreadyConverted, /// The crowdfund has already been cancelled. CrowdFundCancelled, /// The conversion to a Project has failed. @@ -235,10 +241,6 @@ pub mod pallet { let crowdfund = CrowdFunds::::get(crowdfund_key).ok_or(Error::::CrowdFundDoesNotExist)?; ensure!(crowdfund.initiator == who, Error::::UserIsNotInitiator); - ensure!( - !crowdfund.is_converted, - Error::::CrowdFundAlreadyConverted - ); ensure!( !crowdfund.approved_for_funding, Error::::CrowdFundAlreadyApproved @@ -395,6 +397,11 @@ pub mod pallet { let crowdfund_key = CrowdFundCount::::get(); // Todo: Take storage deposit> + let deposit_id = ::DepositHandler::take_deposit( + who.clone(), + ::CrowdFundStorageItem::get(), + CurrencyId::Native, + )?; // For now we keep them as proposed milestones until the project is able to submit. let crowdfund = CrowdFund { @@ -410,7 +417,7 @@ pub mod pallet { created_on: >::block_number(), approved_for_funding: false, cancelled: false, - is_converted: false, + deposit_id }; // Add crowdfund to list @@ -564,12 +571,8 @@ pub mod pallet { FundingType::Proposal, )?; - CrowdFunds::::mutate(crowdfund_key, |crowdfund| { - if let Some(cf) = crowdfund { - cf.is_converted = true - } - Ok::<(), DispatchError>(()) - })?; + ::DepositHandler::return_deposit(crowdfund.deposit_id)?; + CrowdFunds::::remove(crowdfund_key); Self::deposit_event(Event::CrowdFundApproved(crowdfund_key)); Ok(().into()) @@ -617,7 +620,7 @@ pub mod pallet { pub agreement_hash: H256, pub initiator: AccountIdOf, pub created_on: BlockNumberFor, - pub is_converted: bool, + pub deposit_id: DepositIdOf, } } diff --git a/pallets/crowdfunding/src/mock.rs b/pallets/crowdfunding/src/mock.rs index 634ace4b..9a15380c 100644 --- a/pallets/crowdfunding/src/mock.rs +++ b/pallets/crowdfunding/src/mock.rs @@ -72,6 +72,7 @@ parameter_types! { pub MaxWhitelistPerCrowdFund: u32 = 50; pub MinimumRequiredFunds: Balance = 2000; pub MinimumContribution: Balance = 5; + pub CrowdFundStorageItem: StorageItem = StorageItem::CrowdFund; } impl pallet_crowdfunding::Config for Test { @@ -85,6 +86,8 @@ impl pallet_crowdfunding::Config for Test { type IsIdentityRequired = IsIdentityRequired; type AuthorityOrigin = EnsureRoot; type IntoProposals = pallet_proposals::Pallet; + type CrowdFundStorageItem = CrowdFundStorageItem; + type DepositHandler = MockDepositHandler; type WeightInfo = (); } diff --git a/pallets/crowdfunding/src/tests.rs b/pallets/crowdfunding/src/tests.rs index be5031fb..bb90b948 100644 --- a/pallets/crowdfunding/src/tests.rs +++ b/pallets/crowdfunding/src/tests.rs @@ -149,7 +149,7 @@ fn update_crowdfund_already_converted() { None, None, ), - Error::::CrowdFundAlreadyConverted + Error::::CrowdFundDoesNotExist ); }); } diff --git a/runtime/imbue-kusama/Cargo.toml b/runtime/imbue-kusama/Cargo.toml index f0c9ee84..45e6a326 100644 --- a/runtime/imbue-kusama/Cargo.toml +++ b/runtime/imbue-kusama/Cargo.toml @@ -103,6 +103,7 @@ pallet-proposals = { path = '../../pallets/proposals', default-features = false pallet-briefs = {path = '../../pallets/briefs', default-features = false } pallet-grants = {path = '../../pallets/grants', default-features = false } pallet-deposits = {path = '../../pallets/deposits', default-features = false } +pallet-crowdfunding = {path = '../../pallets/crowdfunding', default-features = false } common-traits = { path = "../../libs/common-traits", default-features = false } common-types = { path = "../../libs/common-types", default-features = false } @@ -178,6 +179,7 @@ std = [ 'pallet-proposals/std', 'pallet-briefs/std', 'pallet-grants/std', + 'pallet-crowdfunding/std', ] runtime-benchmarks = [ @@ -197,6 +199,7 @@ runtime-benchmarks = [ 'pallet-proposals/runtime-benchmarks', 'pallet-briefs/runtime-benchmarks', 'pallet-grants/runtime-benchmarks', + 'pallet-crowdfunding/runtime-benchmarks', ] # A feature that should be enabled when the runtime should be build for on-chain diff --git a/runtime/imbue-kusama/src/lib.rs b/runtime/imbue-kusama/src/lib.rs index 36796d2c..b182edf9 100644 --- a/runtime/imbue-kusama/src/lib.rs +++ b/runtime/imbue-kusama/src/lib.rs @@ -761,7 +761,6 @@ parameter_types! { pub const PercentRequiredForVoteToPass: Percent = Percent::from_percent(75u8); pub const MaximumContributorsPerProject: u32 = 5000; pub const RefundsPerBlock: u8 = 20; - pub const IsIdentityRequired: bool = false; pub const MilestoneVotingWindow: BlockNumber = 100800; pub const ImbueFee: Percent = Percent::from_percent(5_u8); pub const ExpiringProjectRoundsPerBlock: u32 = 50; @@ -834,6 +833,7 @@ impl DepositCalculator for ImbueDepositCalculator { u: Self::StorageItem, currency: CurrencyId, ) -> Result { + // A safe guard as Imbue only takes deposits in the $IMBU if currency != CurrencyId::Native { return Err(pallet_deposits::pallet::Error::::UnsupportedCurrencyType.into()); } @@ -845,6 +845,7 @@ impl DepositCalculator for ImbueDepositCalculator { }) } } + impl pallet_deposits::Config for Runtime { type RuntimeEvent = RuntimeEvent; type MultiCurrency = Currencies; @@ -854,6 +855,34 @@ impl pallet_deposits::Config for Runtime { type DepositSlashAccount = TreasuryAccount; } +parameter_types! { + // SAFETY: This is iterated in the hooks of linear complexity (O(n) + 1)r/w. + pub MaxKeysPerRound: u32 = 100; + // (?) + pub MaxContributionsPerCrowdFund: u32 = 300; + // (?) + pub MaxWhitelistPerCrowdFund: u32 = 300; + pub IsIdentityRequired: bool = false; + pub TwoWeeks: BlockNumber = DAYS * 14; + pub CrowdFundStorageItem: StorageDepositItems = StorageDepositItems::CrowdFund; +} + +impl pallet_crowdfunding::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type MultiCurrency = Currencies; + type RoundExpiry = TwoWeeks; + type MaxKeysPerRound = MaxKeysPerRound; + type MaxMilestonesPerCrowdFund = MaxMilestonesPerProject; + type MaxWhitelistPerCrowdFund = MaxWhitelistPerCrowdFund; + type MaxContributionsPerCrowdFund = MaxContributionsPerCrowdFund; + type IsIdentityRequired = IsIdentityRequired; + type AuthorityOrigin = EnsureRoot; + type IntoProposals = pallet_proposals::Pallet; + type DepositHandler = Deposits; + type CrowdFundStorageItem = CrowdFundStorageItem; + type WeightInfo = pallet_crowdfunding::weights::SubstrateWeight; +} + construct_runtime! { pub enum Runtime where Block = Block, @@ -911,6 +940,7 @@ construct_runtime! { ImbueBriefs: pallet_briefs::{Pallet, Call, Storage, Event} = 101, ImbueGrants: pallet_grants::{Pallet, Call, Storage, Event} = 102, Deposits: pallet_deposits::{Pallet, Storage, Event} = 103, + ImbueCrowdfunding: pallet_crowdfunding::{Pallet, Call, Storage, Event} = 104, } } @@ -956,6 +986,7 @@ mod benches { [pallet_proposals, ImbueProposals] [pallet_briefs, ImbueBriefs] [pallet_grants, ImbueGrants] + [pallet_crowdfunding, ImbueCrowdfunding] ); } From 27cebb09f3662bfbcf589a7ec0a7e433587a10e2 Mon Sep 17 00:00:00 2001 From: f-gate Date: Wed, 14 Jun 2023 19:07:17 +0100 Subject: [PATCH 4/6] fix --- pallets/crowdfunding/src/benchmarking.rs | 47 +++++++++++------------- pallets/crowdfunding/src/mock.rs | 2 +- pallets/proposals/Cargo.toml | 2 +- 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/pallets/crowdfunding/src/benchmarking.rs b/pallets/crowdfunding/src/benchmarking.rs index df142c21..54c90f86 100644 --- a/pallets/crowdfunding/src/benchmarking.rs +++ b/pallets/crowdfunding/src/benchmarking.rs @@ -1,13 +1,10 @@ //! Benchmarking setup for pallet-template use super::*; - -#[allow(unused)] -use crate::Pallet as Template; use crate::Pallet as CrowdFunding; use common_types::CurrencyId; -use frame_benchmarking::v1::{account, benchmarks, impl_benchmark_test_suite, whitelisted_caller}; -use frame_support::assert_ok; +use frame_benchmarking::{account, benchmarks, impl_benchmark_test_suite, whitelisted_caller}; +use frame_support::{assert_ok, sp_runtime::SaturatedConversion}; use frame_system::{EventRecord, RawOrigin}; use orml_traits::MultiCurrency; use pallet_proposals::ProposedMilestone; @@ -21,14 +18,14 @@ benchmarks! { } create_crowdfund { - let caller: T::AccountId = whitelisted_caller(); + let caller: T::AccountId = create_funded_user::("initiator", 1, 100_000_000_000_000_000u128); let milestones = get_max_milestones::(); let required_funds = u32::MAX; let currency_id = CurrencyId::Native; let agg_hash = H256::from([10u8; 32]); let crowdfund_key = 0; // (Origin, agg_hash, ProposedMilestones, RequiredFunds, CurrencyId) - }: _(RawOrigin::Signed(whitelisted_caller()), agg_hash, milestones, required_funds.into(), CurrencyId::Native) + }: _(RawOrigin::Signed(caller.clone()), agg_hash, milestones, required_funds.into(), CurrencyId::Native) verify { assert_last_event::(Event::::CrowdFundCreated(caller, agg_hash, crowdfund_key, required_funds.into(), CurrencyId::Native).into()); } @@ -87,7 +84,7 @@ benchmarks! { contribute { let required_funds = u32::MAX; create_crowdfund_common::(required_funds); - let alice: T::AccountId = create_funded_user::("candidate", 1, 100_000); + let alice: T::AccountId = create_funded_user::("candidate", 1, 100_000_000_000_000_000u128); let caller: T::AccountId = whitelisted_caller(); let _ = CrowdFunding::::open_contributions(RawOrigin::Root.into(), 0); @@ -98,11 +95,11 @@ benchmarks! { } approve_crowdfund_for_milestone_submission { - let required_funds: u32 = 100_000u32; + let required_funds: u32 = u32::MAX; create_crowdfund_common::(required_funds); - let alice: T::AccountId = create_funded_user::("candidate", 1, required_funds.into()); - let _ = CrowdFunding::::open_contributions(RawOrigin::Root.into(), 0); - let _ = CrowdFunding::::contribute(RawOrigin::Signed(alice.clone()).into(), 0u32, required_funds.into()); + let alice: T::AccountId = create_funded_user::("candidate", 1, 100_000_000_000_000_000u128); + assert_ok!(CrowdFunding::::open_contributions(RawOrigin::Root.into(), 0)); + assert_ok!(CrowdFunding::::contribute(RawOrigin::Signed(alice.clone()).into(), 0u32, required_funds.into())); //(Origin, CrowdFundKey) }: _(RawOrigin::Root, 0) @@ -111,25 +108,23 @@ benchmarks! { } } -impl_benchmark_test_suite!(CrowdFunding, crate::mock::new_test_ext(), crate::mock::Test); - -fn create_funded_user( - string: &'static str, +pub fn create_funded_user( + seed: &'static str, n: u32, - balance_factor: u32, + balance_factor: u128, ) -> T::AccountId { - let user = account(string, n, 99); - let balance: BalanceOf = balance_factor.into(); - let _ = ::AccountId>>::deposit( - CurrencyId::Native, - &user, - balance, - ); + let user = account(seed, n, 0); + assert_ok!(::AccountId, + >>::deposit( + CurrencyId::Native, &user, balance_factor.saturated_into() + )); user } + fn create_crowdfund_common(required_funds: u32) -> T::AccountId { - let bob: T::AccountId = create_funded_user::("initiator", 1, 100_000_000); + let bob: T::AccountId = create_funded_user::("initiator", 1, 100_000_000_000_000_000u128); let milestones = get_max_milestones::(); let agg_hash = H256::from([20; 32]); @@ -176,3 +171,5 @@ where let EventRecord { event, .. } = &events[events.len() - 1]; assert_eq!(event, &system_event); } + +impl_benchmark_test_suite!(CrowdFunding, crate::mock::new_test_ext(), crate::mock::Test); diff --git a/pallets/crowdfunding/src/mock.rs b/pallets/crowdfunding/src/mock.rs index 9a15380c..ba7221e3 100644 --- a/pallets/crowdfunding/src/mock.rs +++ b/pallets/crowdfunding/src/mock.rs @@ -238,7 +238,7 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { let mut ext = sp_io::TestExternalities::new(t); ext.execute_with(|| { - let initial_balance = 10_000_000u64; + let initial_balance = 100_000_000_000_000u64; System::set_block_number(1); let _ = Tokens::deposit(CurrencyId::Native, &ALICE, initial_balance); let _ = Tokens::deposit(CurrencyId::Native, &BOB, initial_balance); diff --git a/pallets/proposals/Cargo.toml b/pallets/proposals/Cargo.toml index 0f69a3a2..72eb9d23 100644 --- a/pallets/proposals/Cargo.toml +++ b/pallets/proposals/Cargo.toml @@ -61,7 +61,7 @@ common-runtime = { path = "../../runtime/common"} [features] default = ['std'] -runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks", "pallet-xcm/runtime-benchmarks"] +runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks", "pallet-xcm/runtime-benchmarks", "common-runtime/runtime-benchmarks"] std = [ "codec/std", "serde/std", From c63f992b6aa1e7e06830c066db208e082023d8dc Mon Sep 17 00:00:00 2001 From: cuteolaf Date: Wed, 12 Jul 2023 15:34:32 +0200 Subject: [PATCH 5/6] minor fixes --- pallets/crowdfunding/src/benchmarking.rs | 2 +- pallets/deposits/src/benchmarking.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/pallets/crowdfunding/src/benchmarking.rs b/pallets/crowdfunding/src/benchmarking.rs index 54c90f86..d95f9151 100644 --- a/pallets/crowdfunding/src/benchmarking.rs +++ b/pallets/crowdfunding/src/benchmarking.rs @@ -1,4 +1,4 @@ -//! Benchmarking setup for pallet-template +//! Benchmarking setup for pallet-crowdfunding use super::*; use crate::Pallet as CrowdFunding; diff --git a/pallets/deposits/src/benchmarking.rs b/pallets/deposits/src/benchmarking.rs index 7fc5aa56..04eec0ad 100644 --- a/pallets/deposits/src/benchmarking.rs +++ b/pallets/deposits/src/benchmarking.rs @@ -1,3 +1,2 @@ #[allow(unused)] -//use crate::Pallet as Template; use frame_benchmarking::v1::{benchmarks, whitelisted_caller}; From 0bdf6609a30831eb0dc97116518765d1870e86d8 Mon Sep 17 00:00:00 2001 From: cuteolaf Date: Wed, 12 Jul 2023 15:42:02 +0200 Subject: [PATCH 6/6] fix: typos --- pallets/crowdfunding/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/crowdfunding/src/lib.rs b/pallets/crowdfunding/src/lib.rs index 4843911a..816ef856 100644 --- a/pallets/crowdfunding/src/lib.rs +++ b/pallets/crowdfunding/src/lib.rs @@ -76,13 +76,13 @@ pub mod pallet { type MaxMilestonesPerCrowdFund: Get; /// The maximum number of whitelist spots in a crowdfund. type MaxWhitelistPerCrowdFund: Get; - /// Define wether a decent identity is required when creating a crowdfund. + /// Define whether a decent identity is required when creating a crowdfund. type IsIdentityRequired: Get; - /// The authority responisble for governance actions. + /// The authority responsible for governance actions. type AuthorityOrigin: EnsureOrigin; /// The type that converts a crowdfund into a project and allows milestone submission. type IntoProposals: IntoProposal, BalanceOf, BlockNumberFor>; - /// The type reponsible for handling storage deposits. + /// The type responsible for handling storage deposits. type DepositHandler: DepositHandler, AccountIdOf>; /// The type that the deposit fee will be calculated from. type CrowdFundStorageItem: Get>;