From 15935b3ba134b4cb3b2cbe288129c69bc1998bc8 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 27 Nov 2021 22:59:31 +0100 Subject: [PATCH 01/17] Allow asset accounts to exist by deposit --- frame/assets/src/extra_mutator.rs | 20 +--- frame/assets/src/functions.rs | 168 ++++++++++++++++++++-------- frame/assets/src/impl_stored_map.rs | 8 +- frame/assets/src/lib.rs | 76 +++++++++++-- frame/assets/src/mock.rs | 33 ++---- frame/assets/src/tests.rs | 6 +- frame/assets/src/types.rs | 39 ++++++- frame/support/src/traits.rs | 7 +- frame/support/src/traits/misc.rs | 35 ++++-- 9 files changed, 271 insertions(+), 121 deletions(-) diff --git a/frame/assets/src/extra_mutator.rs b/frame/assets/src/extra_mutator.rs index 8c601b746346c..af263113b45c3 100644 --- a/frame/assets/src/extra_mutator.rs +++ b/frame/assets/src/extra_mutator.rs @@ -62,11 +62,11 @@ impl, I: 'static> ExtraMutator { id: T::AssetId, who: impl sp_std::borrow::Borrow, ) -> Option> { - if Account::::contains_key(id, who.borrow()) { + if let Some(a) = Account::::get(id, who.borrow()) { Some(ExtraMutator:: { id, who: who.borrow().clone(), - original: Account::::get(id, who.borrow()).extra, + original: a.extra, pending: None, }) } else { @@ -77,13 +77,8 @@ impl, I: 'static> ExtraMutator { /// Commit any changes to storage. pub fn commit(&mut self) -> Result<(), ()> { if let Some(extra) = self.pending.take() { - Account::::try_mutate_exists(self.id, self.who.borrow(), |maybe_account| { - if let Some(ref mut account) = maybe_account { - account.extra = extra; - Ok(()) - } else { - Err(()) - } + Account::::try_mutate(self.id, self.who.borrow(), |maybe_account| { + maybe_account.as_mut().ok_or(()).map(|account| account.extra = extra) }) } else { Ok(()) @@ -94,12 +89,7 @@ impl, I: 'static> ExtraMutator { pub fn revert(mut self) -> Result<(), ()> { self.pending = None; Account::::try_mutate_exists(self.id, self.who.borrow(), |maybe_account| { - if let Some(ref mut account) = maybe_account { - account.extra = self.original.clone(); - Ok(()) - } else { - Err(()) - } + maybe_account.as_mut().ok_or(()).map(|account| account.extra = self.original.clone()) }) } } diff --git a/frame/assets/src/functions.rs b/frame/assets/src/functions.rs index f01954cb970ee..46e984830783c 100644 --- a/frame/assets/src/functions.rs +++ b/frame/assets/src/functions.rs @@ -20,6 +20,14 @@ use super::*; use frame_support::{traits::Get, BoundedVec}; +#[must_use] +pub(super)enum DeadConsequence { + Remove, + Keep, +} + +use DeadConsequence::*; + // The main implementation block for the module. impl, I: 'static> Pallet { // Public immutables @@ -34,7 +42,7 @@ impl, I: 'static> Pallet { /// Get the asset `id` balance of `who`. pub fn balance(id: T::AssetId, who: impl sp_std::borrow::Borrow) -> T::Balance { - Account::::get(id, who.borrow()).balance + Account::::get(id, who.borrow()).map(|a| a.balance).unwrap_or_default() } /// Get the total supply of an asset `id`. @@ -45,34 +53,38 @@ impl, I: 'static> Pallet { pub(super) fn new_account( who: &T::AccountId, d: &mut AssetDetails>, - ) -> Result { + ) -> Result>, DispatchError> { let accounts = d.accounts.checked_add(1).ok_or(ArithmeticError::Overflow)?; - let is_sufficient = if d.is_sufficient { + let reason = if d.is_sufficient { frame_system::Pallet::::inc_sufficients(who); d.sufficients += 1; - true + ExistenceReason::Sufficient } else { frame_system::Pallet::::inc_consumers(who).map_err(|_| Error::::NoProvider)?; - false + ExistenceReason::Consumer }; d.accounts = accounts; - Ok(is_sufficient) + Ok(reason) } pub(super) fn dead_account( what: T::AssetId, who: &T::AccountId, d: &mut AssetDetails>, - sufficient: bool, - ) { - if sufficient { - d.sufficients = d.sufficients.saturating_sub(1); - frame_system::Pallet::::dec_sufficients(who); - } else { - frame_system::Pallet::::dec_consumers(who); + reason: &ExistenceReason>, + ) -> DeadConsequence { + match *reason { + ExistenceReason::Consumer => frame_system::Pallet::::dec_consumers(who), + ExistenceReason::Sufficient => { + d.sufficients = d.sufficients.saturating_sub(1); + frame_system::Pallet::::dec_sufficients(who); + }, + ExistenceReason::DepositHeld(_) => { return Keep } + ExistenceReason::DepositRefunded => {} } d.accounts = d.accounts.saturating_sub(1); - T::Freezer::died(what, who) + T::Freezer::died(what, who); + Remove } pub(super) fn can_increase( @@ -87,11 +99,11 @@ impl, I: 'static> Pallet { if details.supply.checked_add(&amount).is_none() { return DepositConsequence::Overflow } - let account = Account::::get(id, who); - if account.balance.checked_add(&amount).is_none() { + let balance = Self::balance(id, who); + if balance.checked_add(&amount).is_none() { return DepositConsequence::Overflow } - if account.balance.is_zero() { + if balance.is_zero() { if amount < details.min_balance { return DepositConsequence::BelowMinimum } @@ -124,7 +136,13 @@ impl, I: 'static> Pallet { if details.is_frozen { return Frozen } - let account = Account::::get(id, who); + if amount.is_zero() { + return Success + } + let account = match Account::::get(id, who) { + Some(a) => a, + None => return NoFunds, + }; if account.is_frozen { return Frozen } @@ -165,7 +183,7 @@ impl, I: 'static> Pallet { let details = Asset::::get(id).ok_or_else(|| Error::::Unknown)?; ensure!(!details.is_frozen, Error::::Frozen); - let account = Account::::get(id, who); + let account = Account::::get(id, who).ok_or(Error::::NoAccount)?; ensure!(!account.is_frozen, Error::::Frozen); let amount = if let Some(frozen) = T::Freezer::frozen_balance(id, who) { @@ -253,6 +271,48 @@ impl, I: 'static> Pallet { Ok((credit, maybe_burn)) } + /// Creates a account for `who` to hold asset `id` with a zero balance and takes a deposit. + pub(super) fn do_touch( + id: T::AssetId, + who: T::AccountId, + ) -> DispatchResult { + ensure!(!Account::::contains_key(id, &who), Error::::AlreadyExists); + let deposit = T::AssetAccountDeposit::get(); + T::Currency::reserve(&who, deposit)?; + Account::::insert(id, &who, AssetAccountOf:: { + balance: Zero::zero(), + is_frozen: false, + reason: ExistenceReason::DepositHeld(deposit), + extra: T::Extra::default(), + }); + Ok(()) + } + + /// Returns a deposit, destroying an asset-account unless sufficient. + pub(super) fn do_refund( + id: T::AssetId, + who: T::AccountId, + allow_burn: bool, + ) -> DispatchResult { + let mut account = Account::::get(id, &who).ok_or(Error::::NoDeposit)?; + let deposit = account.reason.take_deposit().ok_or(Error::::NoDeposit)?; + let mut details = Asset::::get(&id).ok_or(Error::::Unknown)?; + + ensure!(account.balance.is_zero() || allow_burn, Error::::WouldBurn); + ensure!(!details.is_frozen, Error::::Frozen); + ensure!(!account.is_frozen, Error::::Frozen); + + T::Currency::unreserve(&who, deposit); + + if let Remove = Self::dead_account(id, &who, &mut details, &account.reason) { + Account::::remove(id, &who); + } else { + debug_assert!(false, "refund did not result in dead account?!"); + } + Asset::::insert(&id, details); + Ok(()) + } + /// Increases the asset `id` balance of `beneficiary` by `amount`. /// /// This alters the registered supply of the asset and emits an event. @@ -307,13 +367,21 @@ impl, I: 'static> Pallet { check(details)?; - Account::::try_mutate(id, beneficiary, |t| -> DispatchResult { - let new_balance = t.balance.saturating_add(amount); - ensure!(new_balance >= details.min_balance, TokenError::BelowMinimum); - if t.balance.is_zero() { - t.sufficient = Self::new_account(beneficiary, details)?; + Account::::try_mutate(id, beneficiary, |maybe_account| -> DispatchResult { + match maybe_account { + Some(ref mut account) => { + account.balance.saturating_accrue(amount); + } + maybe_account @ None => { + ensure!(amount >= details.min_balance, TokenError::BelowMinimum); + *maybe_account = Some(AssetAccountOf:: { + balance: amount, + reason: Self::new_account(beneficiary, details)?, + is_frozen: false, + extra: T::Extra::default(), + }); + } } - t.balance = new_balance; Ok(()) })?; Ok(()) @@ -375,23 +443,23 @@ impl, I: 'static> Pallet { let actual = Self::prep_debit(id, target, amount, f)?; Asset::::try_mutate(id, |maybe_details| -> DispatchResult { - let details = maybe_details.as_mut().ok_or(Error::::Unknown)?; + let mut details = maybe_details.as_mut().ok_or(Error::::Unknown)?; check(actual, details)?; - Account::::try_mutate_exists(id, target, |maybe_account| -> DispatchResult { - let mut account = maybe_account.take().unwrap_or_default(); + Account::::try_mutate(id, target, |maybe_account| -> DispatchResult { + let mut account = maybe_account.take().ok_or(Error::::NoAccount)?; debug_assert!(account.balance >= actual, "checked in prep; qed"); // Make the debit. account.balance = account.balance.saturating_sub(actual); - *maybe_account = if account.balance < details.min_balance { + if account.balance < details.min_balance { debug_assert!(account.balance.is_zero(), "checked in prep; qed"); - Self::dead_account(id, target, details, account.sufficient); - None - } else { - Some(account) + if let Remove = Self::dead_account(id, target, &mut details, &account.reason) { + return Ok(()) + } }; + *maybe_account = Some(account); Ok(()) })?; @@ -432,7 +500,7 @@ impl, I: 'static> Pallet { let debit = Self::prep_debit(id, &source, amount, f.into())?; let (credit, maybe_burn) = Self::prep_credit(id, &dest, amount, debit, f.burn_dust)?; - let mut source_account = Account::::get(id, &source); + let mut source_account = Account::::get(id, &source).ok_or(Error::::NoAccount)?; Asset::::try_mutate(id, |maybe_details| -> DispatchResult { let details = maybe_details.as_mut().ok_or(Error::::Unknown)?; @@ -459,25 +527,31 @@ impl, I: 'static> Pallet { debug_assert!(source_account.balance >= debit, "checked in prep; qed"); source_account.balance = source_account.balance.saturating_sub(debit); - Account::::try_mutate(id, &dest, |a| -> DispatchResult { - // Calculate new balance; this will not saturate since it's already checked in prep. - debug_assert!(a.balance.checked_add(&credit).is_some(), "checked in prep; qed"); - let new_balance = a.balance.saturating_add(credit); - - // Create a new account if there wasn't one already. - if a.balance.is_zero() { - a.sufficient = Self::new_account(&dest, details)?; + Account::::try_mutate(id, &dest, |maybe_account| -> DispatchResult { + match maybe_account { + Some(ref mut account) => { + // Calculate new balance; this will not saturate since it's already checked in prep. + debug_assert!(account.balance.checked_add(&credit).is_some(), "checked in prep; qed"); + account.balance.saturating_accrue(credit); + } + maybe_account @ None => { + *maybe_account = Some(AssetAccountOf:: { + balance: credit, + is_frozen: false, + reason: Self::new_account(&dest, details)?, + extra: T::Extra::default(), + }); + } } - - a.balance = new_balance; Ok(()) })?; // Remove source account if it's now dead. if source_account.balance < details.min_balance { debug_assert!(source_account.balance.is_zero(), "checked in prep; qed"); - Self::dead_account(id, &source, details, source_account.sufficient); - Account::::remove(id, &source); + if let Remove = Self::dead_account(id, &source, details, &source_account.reason) { + Account::::remove(id, &source); + } } else { Account::::insert(id, &source, &source_account) } @@ -554,7 +628,7 @@ impl, I: 'static> Pallet { ensure!(details.approvals <= witness.approvals, Error::::BadWitness); for (who, v) in Account::::drain_prefix(id) { - Self::dead_account(id, &who, &mut details, v.sufficient); + let _ = Self::dead_account(id, &who, &mut details, &v.reason); } debug_assert_eq!(details.accounts, 0); debug_assert_eq!(details.sufficients, 0); diff --git a/frame/assets/src/impl_stored_map.rs b/frame/assets/src/impl_stored_map.rs index 4c1ff1a0c6027..c72a19fadcfae 100644 --- a/frame/assets/src/impl_stored_map.rs +++ b/frame/assets/src/impl_stored_map.rs @@ -22,11 +22,7 @@ use super::*; impl, I: 'static> StoredMap<(T::AssetId, T::AccountId), T::Extra> for Pallet { fn get(id_who: &(T::AssetId, T::AccountId)) -> T::Extra { let &(id, ref who) = id_who; - if Account::::contains_key(id, who) { - Account::::get(id, who).extra - } else { - Default::default() - } + Account::::get(id, who).map(|a| a.extra).unwrap_or_default() } fn try_mutate_exists>( @@ -34,7 +30,7 @@ impl, I: 'static> StoredMap<(T::AssetId, T::AccountId), T::Extra> f f: impl FnOnce(&mut Option) -> Result, ) -> Result { let &(id, ref who) = id_who; - let mut maybe_extra = Some(Account::::get(id, who).extra); + let mut maybe_extra = Account::::get(id, who).map(|a| a.extra); let r = f(&mut maybe_extra)?; // They want to write some value or delete it. // If the account existed and they want to write a value, then we write. diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 940120954f968..caba67a56427c 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -212,6 +212,11 @@ pub mod pallet { #[pallet::constant] type AssetDeposit: Get>; + /// The amount of funds that must be reserved for a non-provider asset account to be + /// maintained. + #[pallet::constant] + type AssetAccountDeposit: Get>; + /// The basic amount of funds that must be reserved when adding metadata to your asset. #[pallet::constant] type MetadataDepositBase: Get>; @@ -229,6 +234,11 @@ pub mod pallet { #[pallet::constant] type StringLimit: Get; + /// The number of non-provider asset accounts which may exist per account without a deposit + /// being paid. + #[pallet::constant] + type FreeAssetAccounts: Get; + /// A hook to allow a per-asset, per-account minimum balance to be enforced. This must be /// respected in all permissionless operations. type Freezer: FrozenBalance; @@ -250,15 +260,15 @@ pub mod pallet { >; #[pallet::storage] - /// The number of units of assets held by any given account. + /// The holdings of a specific account for a specific asset. pub(super) type Account, I: 'static = ()> = StorageDoubleMap< _, Blake2_128Concat, T::AssetId, Blake2_128Concat, T::AccountId, - AssetBalance, - ValueQuery, + AssetAccountOf, + OptionQuery, GetDefault, ConstU32<300_000>, >; @@ -448,8 +458,8 @@ pub mod pallet { pub enum Error { /// Account balance must be greater than or equal to the transfer amount. BalanceLow, - /// Balance should be non-zero. - BalanceZero, + /// The account to alter does not exist. + NoAccount, /// The signing account has no permission to do the operation. NoPermission, /// The given asset ID is unknown. @@ -471,6 +481,12 @@ pub mod pallet { Unapproved, /// The source account would not survive the transfer and it needs to stay alive. WouldDie, + /// The asset-account already exists. + AlreadyExists, + /// The asset-account doesn't have an associated deposit. + NoDeposit, + /// The operation would result in funds being burned. + WouldBurn, } #[pallet::call] @@ -633,7 +649,7 @@ pub mod pallet { /// /// Origin must be Signed and the sender should be the Manager of the asset `id`. /// - /// Bails with `BalanceZero` if the `who` is already dead. + /// Bails with `NoAccount` if the `who` is already dead. /// /// - `id`: The identifier of the asset to have some amount burned. /// - `who`: The account to be debited from. @@ -659,6 +675,42 @@ pub mod pallet { Ok(()) } + /// Create an asset account for non-provider assets. + /// + /// A deposit will be taken from the signer account. + /// + /// - `origin`: Must be Signed; the signer account must have sufficient funds for a + /// deposit to be taken. + /// - `id`: The identifier of the asset for the account to be created. + /// + /// Emits `Touched` event when successful. + #[pallet::weight(T::WeightInfo::mint())] + pub fn touch( + origin: OriginFor, + #[pallet::compact] id: T::AssetId, + ) -> DispatchResult { + Self::do_touch(id, ensure_signed(origin)?) + } + + /// Return the deposit (if any) of an asset account. + /// + /// The origin must be Signed. + /// + /// - `id`: The identifier of the asset for the account to be created. + /// - `allow_burn`: If `true` then assets may be destroyed in order to complete the refund. + /// This will be needed unless the asset is a provider and the balance is greater than the + /// asset's minimum balance. + /// + /// Emits `Refunded` event when successful. + #[pallet::weight(T::WeightInfo::mint())] + pub fn refund( + origin: OriginFor, + #[pallet::compact] id: T::AssetId, + allow_burn: bool, + ) -> DispatchResult { + Self::do_refund(id, ensure_signed(origin)?, allow_burn) + } + /// Move some assets from the sender account to another. /// /// Origin must be Signed. @@ -779,9 +831,11 @@ pub mod pallet { let d = Asset::::get(id).ok_or(Error::::Unknown)?; ensure!(&origin == &d.freezer, Error::::NoPermission); let who = T::Lookup::lookup(who)?; - ensure!(Account::::contains_key(id, &who), Error::::BalanceZero); - Account::::mutate(id, &who, |a| a.is_frozen = true); + Account::::try_mutate(id, &who, |maybe_account| -> DispatchResult { + maybe_account.as_mut().ok_or(Error::::NoAccount)?.is_frozen = true; + Ok(()) + })?; Self::deposit_event(Event::::Frozen { asset_id: id, who }); Ok(()) @@ -808,9 +862,11 @@ pub mod pallet { let details = Asset::::get(id).ok_or(Error::::Unknown)?; ensure!(&origin == &details.admin, Error::::NoPermission); let who = T::Lookup::lookup(who)?; - ensure!(Account::::contains_key(id, &who), Error::::BalanceZero); - Account::::mutate(id, &who, |a| a.is_frozen = false); + Account::::try_mutate(id, &who, |maybe_account| -> DispatchResult { + maybe_account.as_mut().ok_or(Error::::NoAccount)?.is_frozen = false; + Ok(()) + })?; Self::deposit_event(Event::::Thawed { asset_id: id, who }); Ok(()) diff --git a/frame/assets/src/mock.rs b/frame/assets/src/mock.rs index aedf437ee8439..7b85eb8a6f929 100644 --- a/frame/assets/src/mock.rs +++ b/frame/assets/src/mock.rs @@ -20,7 +20,7 @@ use super::*; use crate as pallet_assets; -use frame_support::{construct_runtime, parameter_types, traits::GenesisBuild}; +use frame_support::{construct_runtime, traits::{ConstU32, ConstU64, GenesisBuild}}; use sp_core::H256; use sp_runtime::{ testing::Header, @@ -42,9 +42,6 @@ construct_runtime!( } ); -parameter_types! { - pub const BlockHashCount: u64 = 250; -} impl frame_system::Config for Test { type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); @@ -59,7 +56,7 @@ impl frame_system::Config for Test { type Lookup = IdentityLookup; type Header = Header; type Event = Event; - type BlockHashCount = BlockHashCount; + type BlockHashCount = ConstU64<250>; type DbWeight = (); type Version = (); type PalletInfo = PalletInfo; @@ -71,15 +68,11 @@ impl frame_system::Config for Test { type OnSetCode = (); } -parameter_types! { - pub const ExistentialDeposit: u64 = 1; -} - impl pallet_balances::Config for Test { type Balance = u64; type DustRemoval = (); type Event = Event; - type ExistentialDeposit = ExistentialDeposit; + type ExistentialDeposit = ConstU64<1>; type AccountStore = System; type WeightInfo = (); type MaxLocks = (); @@ -87,25 +80,19 @@ impl pallet_balances::Config for Test { type ReserveIdentifier = [u8; 8]; } -parameter_types! { - pub const AssetDeposit: u64 = 1; - pub const ApprovalDeposit: u64 = 1; - pub const StringLimit: u32 = 50; - pub const MetadataDepositBase: u64 = 1; - pub const MetadataDepositPerByte: u64 = 1; -} - impl Config for Test { type Event = Event; type Balance = u64; type AssetId = u32; type Currency = Balances; type ForceOrigin = frame_system::EnsureRoot; - type AssetDeposit = AssetDeposit; - type MetadataDepositBase = MetadataDepositBase; - type MetadataDepositPerByte = MetadataDepositPerByte; - type ApprovalDeposit = ApprovalDeposit; - type StringLimit = StringLimit; + type AssetDeposit = ConstU64<1>; + type AssetAccountDeposit = ConstU64<10>; + type MetadataDepositBase = ConstU64<1>; + type MetadataDepositPerByte = ConstU64<1>; + type ApprovalDeposit = ConstU64<1>; + type FreeAssetAccounts = ConstU32<2>; + type StringLimit = ConstU32<50>; type Freezer = TestFreezer; type WeightInfo = (); type Extra = (); diff --git a/frame/assets/src/tests.rs b/frame/assets/src/tests.rs index e24a1d45215da..b2a26ccd0fd0a 100644 --- a/frame/assets/src/tests.rs +++ b/frame/assets/src/tests.rs @@ -488,7 +488,7 @@ fn transferring_amount_more_than_available_balance_should_not_work() { assert_eq!(Assets::balance(0, 2), 50); assert_ok!(Assets::burn(Origin::signed(1), 0, 1, u64::MAX)); assert_eq!(Assets::balance(0, 1), 0); - assert_noop!(Assets::transfer(Origin::signed(1), 0, 1, 50), Error::::BalanceLow); + assert_noop!(Assets::transfer(Origin::signed(1), 0, 1, 50), Error::::NoAccount); assert_noop!(Assets::transfer(Origin::signed(2), 0, 1, 51), Error::::BalanceLow); }); } @@ -536,7 +536,7 @@ fn burning_asset_balance_with_zero_balance_does_nothing() { assert_ok!(Assets::force_create(Origin::root(), 0, 1, true, 1)); assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); assert_eq!(Assets::balance(0, 2), 0); - assert_ok!(Assets::burn(Origin::signed(1), 0, 2, u64::MAX)); + assert_noop!(Assets::burn(Origin::signed(1), 0, 2, u64::MAX), Error::::NoAccount); assert_eq!(Assets::balance(0, 2), 0); assert_eq!(Assets::total_supply(0), 100); }); @@ -688,7 +688,7 @@ fn force_metadata_should_work() { ); // string length limit check - let limit = StringLimit::get() as usize; + let limit = 50usize; assert_noop!( Assets::force_set_metadata( Origin::root(), diff --git a/frame/assets/src/types.rs b/frame/assets/src/types.rs index 879e9d5cdcb96..fd329865132c1 100644 --- a/frame/assets/src/types.rs +++ b/frame/assets/src/types.rs @@ -26,6 +26,8 @@ use sp_runtime::{traits::Convert, FixedPointNumber, FixedPointOperand, FixedU128 pub(super) type DepositBalanceOf = <>::Currency as Currency<::AccountId>>::Balance; +pub(super) type AssetAccountOf = + AssetAccount::<>::Balance, DepositBalanceOf, >::Extra>; #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub struct AssetDetails { @@ -76,14 +78,45 @@ pub struct Approval { pub(super) deposit: DepositBalance, } -#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, Default, MaxEncodedLen, TypeInfo)] -pub struct AssetBalance { +#[test] +fn ensure_bool_decodes_to_consumer_or_sufficient() { + assert_eq!(false.encode(), ExistenceReason::<()>::Consumer.encode()); + assert_eq!(true.encode(), ExistenceReason::<()>::Sufficient.encode()); +} + +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)] +pub enum ExistenceReason { + #[codec(index = 0)] + Consumer, + #[codec(index = 1)] + Sufficient, + #[codec(index = 2)] + DepositHeld(Balance), + #[codec(index = 3)] + DepositRefunded, +} + +impl ExistenceReason { + pub(crate) fn take_deposit(&mut self) -> Option { + if !matches!(self, ExistenceReason::DepositHeld(_)) { + return None + } + if let ExistenceReason::DepositHeld(deposit) = sp_std::mem::replace(self, ExistenceReason::DepositRefunded) { + return Some(deposit) + } else { + return None + } + } +} + +#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)] +pub struct AssetAccount { /// The balance. pub(super) balance: Balance, /// Whether the account is frozen. pub(super) is_frozen: bool, /// `true` if this balance gave the account a self-sufficient reference. - pub(super) sufficient: bool, + pub(super) reason: ExistenceReason, /// Additional "sidecar" data, in case some other pallet wants to use this storage item. pub(super) extra: Extra, } diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index bb990e25646db..27c7ad8b2323a 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -50,9 +50,10 @@ pub use filter::{ClearFilterGuard, FilterStack, FilterStackGuard, InstanceFilter mod misc; pub use misc::{ - Backing, ConstU32, EnsureInherentsAreFirst, EqualPrivilegeOnly, EstimateCallFee, ExecuteBlock, - ExtrinsicCall, Get, GetBacking, GetDefault, HandleLifetime, IsSubType, IsType, Len, - OffchainWorker, OnKilledAccount, OnNewAccount, PrivilegeCmp, SameOrOther, Time, TryDrop, + Backing, ConstBool, ConstU8, ConstU16, ConstU32, ConstU64, ConstU128, ConstI8, ConstI16, + ConstI32, ConstI64, ConstI128, EnsureInherentsAreFirst, EqualPrivilegeOnly, EstimateCallFee, + ExecuteBlock, ExtrinsicCall, Get, GetBacking, GetDefault, HandleLifetime, IsSubType, IsType, + Len, OffchainWorker, OnKilledAccount, OnNewAccount, PrivilegeCmp, SameOrOther, Time, TryDrop, UnixTime, WrapperKeepOpaque, WrapperOpaque, }; diff --git a/frame/support/src/traits/misc.rs b/frame/support/src/traits/misc.rs index 153c3804bd599..b346886b720bf 100644 --- a/frame/support/src/traits/misc.rs +++ b/frame/support/src/traits/misc.rs @@ -60,20 +60,33 @@ impl Get for GetDefault { } } -/// Implement `Get` and `Get>` using the given const. -pub struct ConstU32; - -impl Get for ConstU32 { - fn get() -> u32 { - T +macro_rules! impl_const_get { + ($name:ident, $t:ty) => { + pub struct $name; + impl Get<$t> for $name { + fn get() -> $t { + T + } + } + impl Get> for $name { + fn get() -> Option<$t> { + Some(T) + } + } } } -impl Get> for ConstU32 { - fn get() -> Option { - Some(T) - } -} +impl_const_get!(ConstBool, bool); +impl_const_get!(ConstU8, u8); +impl_const_get!(ConstU16, u16); +impl_const_get!(ConstU32, u32); +impl_const_get!(ConstU64, u64); +impl_const_get!(ConstU128, u128); +impl_const_get!(ConstI8, i8); +impl_const_get!(ConstI16, i16); +impl_const_get!(ConstI32, i32); +impl_const_get!(ConstI64, i64); +impl_const_get!(ConstI128, i128); /// A type for which some values make sense to be able to drop without further consideration. pub trait TryDrop: Sized { From eb65b083e52c8f2a09f759cf0c1b2753f511ce66 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 27 Nov 2021 17:32:20 -0500 Subject: [PATCH 02/17] Place limit on consumers (and therefore freebie asset accounts) --- bin/node-template/pallets/template/src/mock.rs | 1 + bin/node-template/runtime/src/lib.rs | 1 + bin/node/runtime/src/lib.rs | 1 + frame/assets/src/functions.rs | 14 ++++++++++---- frame/assets/src/lib.rs | 12 ++++++++++++ frame/assets/src/mock.rs | 1 + frame/atomic-swap/src/tests.rs | 1 + frame/aura/src/mock.rs | 1 + frame/authority-discovery/src/lib.rs | 1 + frame/authorship/src/lib.rs | 1 + frame/babe/src/mock.rs | 1 + frame/bags-list/src/mock.rs | 1 + frame/balances/src/tests_composite.rs | 1 + frame/balances/src/tests_local.rs | 1 + frame/balances/src/tests_reentrancy.rs | 1 + frame/beefy-mmr/src/mock.rs | 1 + frame/beefy/src/mock.rs | 1 + frame/benchmarking/src/baseline.rs | 1 + frame/benchmarking/src/tests.rs | 1 + frame/benchmarking/src/tests_instance.rs | 1 + frame/bounties/src/tests.rs | 1 + frame/collective/src/tests.rs | 1 + frame/contracts/src/tests.rs | 1 + frame/democracy/src/tests.rs | 1 + frame/election-provider-multi-phase/src/mock.rs | 1 + frame/election-provider-support/src/onchain.rs | 1 + frame/elections-phragmen/src/lib.rs | 1 + frame/elections/src/mock.rs | 1 + frame/examples/basic/src/tests.rs | 1 + frame/examples/offchain-worker/src/tests.rs | 1 + frame/examples/parallel/src/tests.rs | 1 + frame/executive/src/lib.rs | 1 + frame/gilt/src/mock.rs | 1 + frame/grandpa/src/mock.rs | 1 + frame/identity/src/tests.rs | 1 + frame/im-online/src/mock.rs | 1 + frame/indices/src/mock.rs | 1 + frame/lottery/src/mock.rs | 1 + frame/membership/src/lib.rs | 1 + frame/merkle-mountain-range/src/mock.rs | 1 + frame/multisig/src/tests.rs | 1 + frame/nicks/src/lib.rs | 1 + frame/node-authorization/src/mock.rs | 1 + frame/offences/benchmarking/src/mock.rs | 1 + frame/offences/src/mock.rs | 1 + frame/proxy/src/tests.rs | 1 + frame/randomness-collective-flip/src/lib.rs | 1 + frame/recovery/src/mock.rs | 1 + frame/scheduler/src/lib.rs | 1 + frame/scored-pool/src/mock.rs | 1 + frame/session/benchmarking/src/mock.rs | 1 + frame/session/src/mock.rs | 1 + frame/society/src/mock.rs | 1 + frame/staking/fuzzer/src/mock.rs | 1 + frame/staking/src/mock.rs | 1 + frame/sudo/src/mock.rs | 1 + frame/support/test/compile_pass/src/lib.rs | 1 + frame/support/test/tests/pallet.rs | 1 + frame/support/test/tests/pallet_compatibility.rs | 1 + .../test/tests/pallet_compatibility_instance.rs | 1 + frame/support/test/tests/pallet_instance.rs | 1 + .../test/tests/pallet_with_name_trait_is_valid.rs | 1 + frame/system/benches/bench.rs | 1 + frame/system/benchmarking/src/mock.rs | 1 + frame/system/src/lib.rs | 12 ++++++++++-- frame/system/src/mock.rs | 1 + frame/timestamp/src/lib.rs | 1 + frame/tips/src/tests.rs | 1 + .../asset-tx-payment/src/tests.rs | 1 + frame/transaction-payment/src/lib.rs | 1 + frame/transaction-storage/src/mock.rs | 1 + frame/treasury/src/tests.rs | 1 + frame/uniques/src/mock.rs | 1 + frame/utility/src/tests.rs | 1 + frame/vesting/src/mock.rs | 1 + primitives/runtime/src/lib.rs | 4 ++++ test-utils/runtime/src/lib.rs | 1 + 77 files changed, 109 insertions(+), 6 deletions(-) diff --git a/bin/node-template/pallets/template/src/mock.rs b/bin/node-template/pallets/template/src/mock.rs index 4532d3d09b497..cc8d7ed2c165e 100644 --- a/bin/node-template/pallets/template/src/mock.rs +++ b/bin/node-template/pallets/template/src/mock.rs @@ -51,6 +51,7 @@ impl system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_template::Config for Test { diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 8ecb2199dda71..78541a93deaf2 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -191,6 +191,7 @@ impl frame_system::Config for Runtime { type SS58Prefix = SS58Prefix; /// The set code logic, just the default since we're not a parachain. type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_randomness_collective_flip::Config for Runtime {} diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 299b7257f9d45..5ad337e1eef89 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -219,6 +219,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = frame_system::weights::SubstrateWeight; type SS58Prefix = SS58Prefix; type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_randomness_collective_flip::Config for Runtime {} diff --git a/frame/assets/src/functions.rs b/frame/assets/src/functions.rs index 46e984830783c..35fe7b66da305 100644 --- a/frame/assets/src/functions.rs +++ b/frame/assets/src/functions.rs @@ -53,9 +53,12 @@ impl, I: 'static> Pallet { pub(super) fn new_account( who: &T::AccountId, d: &mut AssetDetails>, + maybe_deposit: Option>, ) -> Result>, DispatchError> { let accounts = d.accounts.checked_add(1).ok_or(ArithmeticError::Overflow)?; - let reason = if d.is_sufficient { + let reason = if let Some(deposit) = maybe_deposit { + ExistenceReason::DepositHeld(deposit) + } else if d.is_sufficient { frame_system::Pallet::::inc_sufficients(who); d.sufficients += 1; ExistenceReason::Sufficient @@ -278,11 +281,14 @@ impl, I: 'static> Pallet { ) -> DispatchResult { ensure!(!Account::::contains_key(id, &who), Error::::AlreadyExists); let deposit = T::AssetAccountDeposit::get(); + let mut details = Asset::::get(&id).ok_or(Error::::Unknown)?; + let reason = Self::new_account(&who, &mut details, Some(deposit))?; T::Currency::reserve(&who, deposit)?; + Asset::::insert(&id, details); Account::::insert(id, &who, AssetAccountOf:: { balance: Zero::zero(), is_frozen: false, - reason: ExistenceReason::DepositHeld(deposit), + reason, extra: T::Extra::default(), }); Ok(()) @@ -376,7 +382,7 @@ impl, I: 'static> Pallet { ensure!(amount >= details.min_balance, TokenError::BelowMinimum); *maybe_account = Some(AssetAccountOf:: { balance: amount, - reason: Self::new_account(beneficiary, details)?, + reason: Self::new_account(beneficiary, details, None)?, is_frozen: false, extra: T::Extra::default(), }); @@ -538,7 +544,7 @@ impl, I: 'static> Pallet { *maybe_account = Some(AssetAccountOf:: { balance: credit, is_frozen: false, - reason: Self::new_account(&dest, details)?, + reason: Self::new_account(&dest, details, None)?, extra: T::Extra::default(), }); } diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index caba67a56427c..91b5db59953c4 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -259,6 +259,18 @@ pub mod pallet { AssetDetails>, >; + #[pallet::storage] + /// The number of consumer asset-accounts being held. If this is some, the it implies a + pub(super) type ConsumerAccounts, I: 'static = ()> = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + u32, + OptionQuery, + GetDefault, + ConstU32<300_000>, + >; + #[pallet::storage] /// The holdings of a specific account for a specific asset. pub(super) type Account, I: 'static = ()> = StorageDoubleMap< diff --git a/frame/assets/src/mock.rs b/frame/assets/src/mock.rs index 7b85eb8a6f929..503ea13fdeaa0 100644 --- a/frame/assets/src/mock.rs +++ b/frame/assets/src/mock.rs @@ -66,6 +66,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<2>; } impl pallet_balances::Config for Test { diff --git a/frame/atomic-swap/src/tests.rs b/frame/atomic-swap/src/tests.rs index a76d0f20ffa3b..2a145de697e36 100644 --- a/frame/atomic-swap/src/tests.rs +++ b/frame/atomic-swap/src/tests.rs @@ -54,6 +54,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index 4418d9e85ae24..1a7c552023e82 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -78,6 +78,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_timestamp::Config for Test { diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index a6609860d7cf1..fea6a6b1267a6 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -260,6 +260,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } pub struct TestSessionHandler; diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 5d36adabe888f..08ab1ba5134fb 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -458,6 +458,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index e7ec692689032..c7f6300e3456e 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -96,6 +96,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl frame_system::offchain::SendTransactionTypes for Test diff --git a/frame/bags-list/src/mock.rs b/frame/bags-list/src/mock.rs index 45eb1d85abe3c..5353ea3989949 100644 --- a/frame/bags-list/src/mock.rs +++ b/frame/bags-list/src/mock.rs @@ -70,6 +70,7 @@ impl frame_system::Config for Runtime { type OnKilledAccount = (); type SystemWeightInfo = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index 60feedb326d8a..402974a80294a 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -73,6 +73,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const TransactionByteFee: u64 = 1; diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index c9de662b9e8fe..f1a68aecaedbf 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -75,6 +75,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const TransactionByteFee: u64 = 1; diff --git a/frame/balances/src/tests_reentrancy.rs b/frame/balances/src/tests_reentrancy.rs index 43edd16baf3b3..5d798eb4d67fd 100644 --- a/frame/balances/src/tests_reentrancy.rs +++ b/frame/balances/src/tests_reentrancy.rs @@ -77,6 +77,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const TransactionByteFee: u64 = 1; diff --git a/frame/beefy-mmr/src/mock.rs b/frame/beefy-mmr/src/mock.rs index 95b87c360510a..0fc5ed37bd2c6 100644 --- a/frame/beefy-mmr/src/mock.rs +++ b/frame/beefy-mmr/src/mock.rs @@ -86,6 +86,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/beefy/src/mock.rs b/frame/beefy/src/mock.rs index a1fbeda4ab35c..d1c97c9d8c70a 100644 --- a/frame/beefy/src/mock.rs +++ b/frame/beefy/src/mock.rs @@ -84,6 +84,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_beefy::Config for Test { diff --git a/frame/benchmarking/src/baseline.rs b/frame/benchmarking/src/baseline.rs index a2ffca60c5cf1..3fbb720149b8f 100644 --- a/frame/benchmarking/src/baseline.rs +++ b/frame/benchmarking/src/baseline.rs @@ -162,6 +162,7 @@ pub mod mock { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl super::Config for Test {} diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index a2cf381e6ecf8..4202e4dc2e430 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -108,6 +108,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/benchmarking/src/tests_instance.rs b/frame/benchmarking/src/tests_instance.rs index 0ad156ce5a88d..5aefb157a66b2 100644 --- a/frame/benchmarking/src/tests_instance.rs +++ b/frame/benchmarking/src/tests_instance.rs @@ -110,6 +110,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/bounties/src/tests.rs b/frame/bounties/src/tests.rs index 344bb6495c3bc..63ec1aecb478c 100644 --- a/frame/bounties/src/tests.rs +++ b/frame/bounties/src/tests.rs @@ -84,6 +84,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/collective/src/tests.rs b/frame/collective/src/tests.rs index cbd2f68ac73e8..e1eeea164eb31 100644 --- a/frame/collective/src/tests.rs +++ b/frame/collective/src/tests.rs @@ -115,6 +115,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl Config for Test { type Origin = Origin; diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index 2214ce8f40b1a..bd0d2c08b6829 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -219,6 +219,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_randomness_collective_flip::Config for Test {} impl pallet_balances::Config for Test { diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index 06c4ac666cfba..75191bb8c6827 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -105,6 +105,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * BlockWeights::get().max_block; diff --git a/frame/election-provider-multi-phase/src/mock.rs b/frame/election-provider-multi-phase/src/mock.rs index fbde6ad991706..16a2d6c4897eb 100644 --- a/frame/election-provider-multi-phase/src/mock.rs +++ b/frame/election-provider-multi-phase/src/mock.rs @@ -218,6 +218,7 @@ impl frame_system::Config for Runtime { type OnKilledAccount = (); type SystemWeightInfo = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); diff --git a/frame/election-provider-support/src/onchain.rs b/frame/election-provider-support/src/onchain.rs index 6379adae4206b..66f60b294d855 100644 --- a/frame/election-provider-support/src/onchain.rs +++ b/frame/election-provider-support/src/onchain.rs @@ -145,6 +145,7 @@ mod tests { type OnKilledAccount = (); type SystemWeightInfo = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl Config for Runtime { diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index 116c0937bf983..e6f75c071a7f2 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -1150,6 +1150,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index 91318e1e07bcc..aa877b5faf7d8 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -60,6 +60,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/examples/basic/src/tests.rs b/frame/examples/basic/src/tests.rs index e069cccf8d800..c5292e0258b28 100644 --- a/frame/examples/basic/src/tests.rs +++ b/frame/examples/basic/src/tests.rs @@ -79,6 +79,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/examples/offchain-worker/src/tests.rs b/frame/examples/offchain-worker/src/tests.rs index 1dde8a1df60c8..fb17c705585ea 100644 --- a/frame/examples/offchain-worker/src/tests.rs +++ b/frame/examples/offchain-worker/src/tests.rs @@ -77,6 +77,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } type Extrinsic = TestXt; diff --git a/frame/examples/parallel/src/tests.rs b/frame/examples/parallel/src/tests.rs index 4c36f0d6eb858..a192a8e4ec61a 100644 --- a/frame/examples/parallel/src/tests.rs +++ b/frame/examples/parallel/src/tests.rs @@ -68,6 +68,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index dd0a9abf8687b..4148c553e8047 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -779,6 +779,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } type Balance = u64; diff --git a/frame/gilt/src/mock.rs b/frame/gilt/src/mock.rs index ac3f4df1b71dd..57da5bb4dfedc 100644 --- a/frame/gilt/src/mock.rs +++ b/frame/gilt/src/mock.rs @@ -74,6 +74,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index 49e4022a4aaed..4fbf2b1c0edba 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -98,6 +98,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl frame_system::offchain::SendTransactionTypes for Test diff --git a/frame/identity/src/tests.rs b/frame/identity/src/tests.rs index c842b0e2f64be..44e56f98f5bc0 100644 --- a/frame/identity/src/tests.rs +++ b/frame/identity/src/tests.rs @@ -73,6 +73,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 1e4d4b43d5789..534debc7cc556 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -139,6 +139,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/indices/src/mock.rs b/frame/indices/src/mock.rs index f4c87016141b5..26fc03cc16d4d 100644 --- a/frame/indices/src/mock.rs +++ b/frame/indices/src/mock.rs @@ -69,6 +69,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/lottery/src/mock.rs b/frame/lottery/src/mock.rs index d1f090aa26dcb..8be943701dfa2 100644 --- a/frame/lottery/src/mock.rs +++ b/frame/lottery/src/mock.rs @@ -79,6 +79,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index 6cd8c13f39aff..006333318e3a8 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -560,6 +560,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } ord_parameter_types! { pub const One: u64 = 1; diff --git a/frame/merkle-mountain-range/src/mock.rs b/frame/merkle-mountain-range/src/mock.rs index 3616a8d1d5242..288abdb856483 100644 --- a/frame/merkle-mountain-range/src/mock.rs +++ b/frame/merkle-mountain-range/src/mock.rs @@ -69,6 +69,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl Config for Test { diff --git a/frame/multisig/src/tests.rs b/frame/multisig/src/tests.rs index 523aefd1e753c..1f05ad06c428c 100644 --- a/frame/multisig/src/tests.rs +++ b/frame/multisig/src/tests.rs @@ -74,6 +74,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index bfc23187fc5b5..36e3d7f72b786 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -297,6 +297,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/node-authorization/src/mock.rs b/frame/node-authorization/src/mock.rs index 6c79f601c197d..7ee4dbf23f3c0 100644 --- a/frame/node-authorization/src/mock.rs +++ b/frame/node-authorization/src/mock.rs @@ -71,6 +71,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } ord_parameter_types! { diff --git a/frame/offences/benchmarking/src/mock.rs b/frame/offences/benchmarking/src/mock.rs index 3097f9b95be3f..1f1ab0ec27b61 100644 --- a/frame/offences/benchmarking/src/mock.rs +++ b/frame/offences/benchmarking/src/mock.rs @@ -63,6 +63,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: Balance = 10; diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index bce51f527abc6..0d7b217c35ca2 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -112,6 +112,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl Config for Runtime { diff --git a/frame/proxy/src/tests.rs b/frame/proxy/src/tests.rs index d3565525910fb..1f2522a546d97 100644 --- a/frame/proxy/src/tests.rs +++ b/frame/proxy/src/tests.rs @@ -78,6 +78,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index 345b8072c5e47..d6fd72ee968d9 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -219,6 +219,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_randomness_collective_flip::Config for Test {} diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index f6d4a6b159431..8b04c23a10c9f 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -75,6 +75,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index d25fc3b376e83..f749aff9e02b3 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -928,6 +928,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl logger::Config for Test { type Event = Event; diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index 5c5425ae2bdd8..136f19e60693a 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -81,6 +81,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_balances::Config for Test { diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs index f534cc097e8a0..b5ae4acd55203 100644 --- a/frame/session/benchmarking/src/mock.rs +++ b/frame/session/benchmarking/src/mock.rs @@ -68,6 +68,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: Balance = 10; diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index 6db7727fa5391..b11f639b2c062 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -264,6 +264,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_timestamp::Config for Test { diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index 9356c083f2331..a7fe52b0982da 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -89,6 +89,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_balances::Config for Test { diff --git a/frame/staking/fuzzer/src/mock.rs b/frame/staking/fuzzer/src/mock.rs index d5ca78193b0c0..ef065318797ed 100644 --- a/frame/staking/fuzzer/src/mock.rs +++ b/frame/staking/fuzzer/src/mock.rs @@ -65,6 +65,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: Balance = 10; diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 2b74b0188cff4..9e72654d8edf0 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -150,6 +150,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_balances::Config for Test { type MaxLocks = MaxLocks; diff --git a/frame/sudo/src/mock.rs b/frame/sudo/src/mock.rs index bfbed0d38ab34..c9a7418f67f52 100644 --- a/frame/sudo/src/mock.rs +++ b/frame/sudo/src/mock.rs @@ -144,6 +144,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } // Implement the logger module's `Config` on the Test runtime. diff --git a/frame/support/test/compile_pass/src/lib.rs b/frame/support/test/compile_pass/src/lib.rs index 17ba40574adf7..9aa0a6c865bf3 100644 --- a/frame/support/test/compile_pass/src/lib.rs +++ b/frame/support/test/compile_pass/src/lib.rs @@ -73,6 +73,7 @@ impl system::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; } diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index dcf739af614b8..18fe0e02b313b 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -553,6 +553,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet::Config for Runtime { type Event = Event; diff --git a/frame/support/test/tests/pallet_compatibility.rs b/frame/support/test/tests/pallet_compatibility.rs index 4523063252ab9..4f6400ce0cde8 100644 --- a/frame/support/test/tests/pallet_compatibility.rs +++ b/frame/support/test/tests/pallet_compatibility.rs @@ -246,6 +246,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet::Config for Runtime { type Event = Event; diff --git a/frame/support/test/tests/pallet_compatibility_instance.rs b/frame/support/test/tests/pallet_compatibility_instance.rs index 768b9f28d35f3..d6610f14363a2 100644 --- a/frame/support/test/tests/pallet_compatibility_instance.rs +++ b/frame/support/test/tests/pallet_compatibility_instance.rs @@ -226,6 +226,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet::Config for Runtime { type Event = Event; diff --git a/frame/support/test/tests/pallet_instance.rs b/frame/support/test/tests/pallet_instance.rs index c031ac9fe1bf5..026cc1f1d5eec 100644 --- a/frame/support/test/tests/pallet_instance.rs +++ b/frame/support/test/tests/pallet_instance.rs @@ -274,6 +274,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet::Config for Runtime { type Event = Event; diff --git a/frame/support/test/tests/pallet_with_name_trait_is_valid.rs b/frame/support/test/tests/pallet_with_name_trait_is_valid.rs index 1c47d13a619f2..b49db0deeb387 100644 --- a/frame/support/test/tests/pallet_with_name_trait_is_valid.rs +++ b/frame/support/test/tests/pallet_with_name_trait_is_valid.rs @@ -152,6 +152,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_test::Trait for Runtime { diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index c8a9d4eadfea0..4df07ef42a911 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -92,6 +92,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl module::Config for Runtime { diff --git a/frame/system/benchmarking/src/mock.rs b/frame/system/benchmarking/src/mock.rs index d828fb22ff5ff..1501601ffde35 100644 --- a/frame/system/benchmarking/src/mock.rs +++ b/frame/system/benchmarking/src/mock.rs @@ -62,6 +62,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl crate::Config for Test {} diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index 0b00a7d8f5973..e78cbe5a4df2c 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -306,6 +306,10 @@ pub mod pallet { /// It's unlikely that this needs to be customized, unless you are writing a parachain using /// `Cumulus`, where the actual code change is deferred. type OnSetCode: SetCode; + + /// The maximum number of consumers allowed on a single account. + #[pallet::constant] + type MaxConsumers: Get; } #[pallet::pallet] @@ -1176,8 +1180,12 @@ impl Pallet { pub fn inc_consumers(who: &T::AccountId) -> Result<(), DispatchError> { Account::::try_mutate(who, |a| { if a.providers > 0 { - a.consumers = a.consumers.saturating_add(1); - Ok(()) + if a.consumers < T::MaxConsumers::get() { + a.consumers = a.consumers.saturating_add(1); + Ok(()) + } else { + Err(DispatchError::TooManyConsumers) + } } else { Err(DispatchError::NoProviders) } diff --git a/frame/system/src/mock.rs b/frame/system/src/mock.rs index 9dd35691cab84..e066cffb9b48a 100644 --- a/frame/system/src/mock.rs +++ b/frame/system/src/mock.rs @@ -111,6 +111,7 @@ impl Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } pub type SysEvent = frame_system::Event; diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index eeb840715f817..509e8002e453e 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -372,6 +372,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const MinimumPeriod: u64 = 5; diff --git a/frame/tips/src/tests.rs b/frame/tips/src/tests.rs index 2aac22ffe18ca..38599d3de8ed7 100644 --- a/frame/tips/src/tests.rs +++ b/frame/tips/src/tests.rs @@ -83,6 +83,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/transaction-payment/asset-tx-payment/src/tests.rs b/frame/transaction-payment/asset-tx-payment/src/tests.rs index bd5dc57239a28..7a8f1fd7d73d3 100644 --- a/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -112,6 +112,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index f912866f7bb39..11f2e4c26cf18 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -865,6 +865,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/transaction-storage/src/mock.rs b/frame/transaction-storage/src/mock.rs index 38d14129d76e2..e6f7c52c30b51 100644 --- a/frame/transaction-storage/src/mock.rs +++ b/frame/transaction-storage/src/mock.rs @@ -77,6 +77,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index 534661b2773bb..cd12d42e1ce38 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -79,6 +79,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/uniques/src/mock.rs b/frame/uniques/src/mock.rs index 658e82a5143e2..38523f3c84cd9 100644 --- a/frame/uniques/src/mock.rs +++ b/frame/uniques/src/mock.rs @@ -69,6 +69,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs index 32582fae82116..16a6cbe6635c4 100644 --- a/frame/utility/src/tests.rs +++ b/frame/utility/src/tests.rs @@ -127,6 +127,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/vesting/src/mock.rs b/frame/vesting/src/mock.rs index cb8961150003b..3ffd0b739fb6d 100644 --- a/frame/vesting/src/mock.rs +++ b/frame/vesting/src/mock.rs @@ -64,6 +64,7 @@ impl frame_system::Config for Test { type OnKilledAccount = (); type OnNewAccount = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; type Origin = Origin; type PalletInfo = PalletInfo; type SS58Prefix = (); diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 80293fe734844..bfae180a8e0db 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -494,6 +494,8 @@ pub enum DispatchError { ConsumerRemaining, /// There are no providers so the account cannot be created. NoProviders, + /// There are too many consumers so the account cannot be created. + TooManyConsumers, /// An error to do with tokens. Token(TokenError), /// An arithmetic error. @@ -629,6 +631,7 @@ impl From for &'static str { DispatchError::Module { message, .. } => message.unwrap_or("Unknown module error"), DispatchError::ConsumerRemaining => "Consumer remaining", DispatchError::NoProviders => "No providers", + DispatchError::TooManyConsumers => "Too many consumers", DispatchError::Token(e) => e.into(), DispatchError::Arithmetic(e) => e.into(), } @@ -660,6 +663,7 @@ impl traits::Printable for DispatchError { }, Self::ConsumerRemaining => "Consumer remaining".print(), Self::NoProviders => "No providers".print(), + Self::TooManyConsumers => "Too many consumers".print(), Self::Token(e) => { "Token error: ".print(); <&'static str>::from(*e).print(); diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 08863de510d09..44e22eb1e01f0 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -591,6 +591,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = ConstU32<16>; } impl pallet_timestamp::Config for Runtime { From ee20238d531438c7c0980e4cdf6ccdf1296c9258 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 27 Nov 2021 18:04:31 -0500 Subject: [PATCH 03/17] Maximum number of assets --- frame/assets/src/functions.rs | 21 ++++++++------ frame/assets/src/tests.rs | 54 +++++++++++++++++++++++++++++++++-- frame/system/src/lib.rs | 3 +- 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/frame/assets/src/functions.rs b/frame/assets/src/functions.rs index 35fe7b66da305..266ade9cb81c3 100644 --- a/frame/assets/src/functions.rs +++ b/frame/assets/src/functions.rs @@ -40,9 +40,14 @@ impl, I: 'static> Pallet { ExtraMutator::maybe_new(id, who) } - /// Get the asset `id` balance of `who`. + /// Get the asset `id` balance of `who`, or zero if the asset-account doesn't exist. pub fn balance(id: T::AssetId, who: impl sp_std::borrow::Borrow) -> T::Balance { - Account::::get(id, who.borrow()).map(|a| a.balance).unwrap_or_default() + Self::maybe_balance(id, who).unwrap_or_default() + } + + /// Get the asset `id` balance of `who` if the asset-account exists. + pub fn maybe_balance(id: T::AssetId, who: impl sp_std::borrow::Borrow) -> Option { + Account::::get(id, who.borrow()).map(|a| a.balance) } /// Get the total supply of an asset `id`. @@ -102,15 +107,15 @@ impl, I: 'static> Pallet { if details.supply.checked_add(&amount).is_none() { return DepositConsequence::Overflow } - let balance = Self::balance(id, who); - if balance.checked_add(&amount).is_none() { - return DepositConsequence::Overflow - } - if balance.is_zero() { + if let Some(balance) = Self::maybe_balance(id, who) { + if balance.checked_add(&amount).is_none() { + return DepositConsequence::Overflow + } + } else { if amount < details.min_balance { return DepositConsequence::BelowMinimum } - if !details.is_sufficient && frame_system::Pallet::::providers(who) == 0 { + if !details.is_sufficient && !frame_system::Pallet::::can_inc_consumer(who) { return DepositConsequence::CannotCreate } if details.is_sufficient && details.sufficients.checked_add(1).is_none() { diff --git a/frame/assets/src/tests.rs b/frame/assets/src/tests.rs index b2a26ccd0fd0a..5fa3e2f918120 100644 --- a/frame/assets/src/tests.rs +++ b/frame/assets/src/tests.rs @@ -34,6 +34,54 @@ fn basic_minting_should_work() { }); } +#[test] +fn minting_too_many_insufficient_assets_fails() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, false, 1)); + assert_ok!(Assets::force_create(Origin::root(), 1, 1, false, 1)); + assert_ok!(Assets::force_create(Origin::root(), 2, 1, false, 1)); + Balances::make_free_balance_be(&1, 100); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + assert_ok!(Assets::mint(Origin::signed(1), 1, 1, 100)); + assert_noop!(Assets::mint(Origin::signed(1), 2, 1, 100), TokenError::CannotCreate); + + Balances::make_free_balance_be(&2, 1); + assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 100)); + assert_ok!(Assets::mint(Origin::signed(1), 2, 1, 100)); + }); +} + +#[test] +fn minting_insufficient_asset_with_deposit_should_work_when_consumers_exhausted() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, false, 1)); + assert_ok!(Assets::force_create(Origin::root(), 1, 1, false, 1)); + assert_ok!(Assets::force_create(Origin::root(), 2, 1, false, 1)); + Balances::make_free_balance_be(&1, 100); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + assert_ok!(Assets::mint(Origin::signed(1), 1, 1, 100)); + assert_noop!(Assets::mint(Origin::signed(1), 2, 1, 100), TokenError::CannotCreate); + + assert_ok!(Assets::touch(Origin::signed(1), 2)); + assert_eq!(Balances::reserved_balance(&1), 10); + + assert_ok!(Assets::mint(Origin::signed(1), 2, 1, 100)); + }); +} + +#[test] +fn minting_insufficient_assets_with_deposit_without_consumer_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, false, 1)); + assert_noop!(Assets::mint(Origin::signed(1), 0, 1, 100), TokenError::CannotCreate); + Balances::make_free_balance_be(&1, 100); + assert_ok!(Assets::touch(Origin::signed(1), 0)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + assert_eq!(Balances::reserved_balance(&1), 10); + assert_eq!(System::consumers(&1), 0); + }); +} + #[test] fn approval_lifecycle_works() { new_test_ext().execute_with(|| { @@ -299,17 +347,17 @@ fn min_balance_should_work() { // When deducting from an account to below minimum, it should be reaped. assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 91)); - assert!(Assets::balance(0, 1).is_zero()); + assert!(Assets::maybe_balance(0, 1).is_none()); assert_eq!(Assets::balance(0, 2), 100); assert_eq!(Asset::::get(0).unwrap().accounts, 1); assert_ok!(Assets::force_transfer(Origin::signed(1), 0, 2, 1, 91)); - assert!(Assets::balance(0, 2).is_zero()); + assert!(Assets::maybe_balance(0, 2).is_none()); assert_eq!(Assets::balance(0, 1), 100); assert_eq!(Asset::::get(0).unwrap().accounts, 1); assert_ok!(Assets::burn(Origin::signed(1), 0, 1, 91)); - assert!(Assets::balance(0, 1).is_zero()); + assert!(Assets::maybe_balance(0, 1).is_none()); assert_eq!(Asset::::get(0).unwrap().accounts, 0); }); } diff --git a/frame/system/src/lib.rs b/frame/system/src/lib.rs index e78cbe5a4df2c..c72ec17d75307 100644 --- a/frame/system/src/lib.rs +++ b/frame/system/src/lib.rs @@ -1225,7 +1225,8 @@ impl Pallet { /// True if the account has at least one provider reference. pub fn can_inc_consumer(who: &T::AccountId) -> bool { - Account::::get(who).providers > 0 + let a = Account::::get(who); + a.providers > 0 && a.consumers < T::MaxConsumers::get() } /// Deposits an event into this block's event record. From a13abe54c69038c23f5e46928ed6ec9a85e91023 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 27 Nov 2021 19:12:47 -0500 Subject: [PATCH 04/17] Fixes --- bin/node-template/pallets/template/src/mock.rs | 2 +- bin/node-template/runtime/src/lib.rs | 4 ++-- bin/node/runtime/src/lib.rs | 5 +++-- frame/assets/src/lib.rs | 5 ----- frame/assets/src/mock.rs | 1 - frame/atomic-swap/src/tests.rs | 2 +- frame/aura/src/mock.rs | 2 +- frame/authority-discovery/src/lib.rs | 2 +- frame/authorship/src/lib.rs | 2 +- frame/babe/src/mock.rs | 2 +- frame/bags-list/src/mock.rs | 2 +- frame/balances/src/tests_composite.rs | 2 +- frame/balances/src/tests_local.rs | 2 +- frame/balances/src/tests_reentrancy.rs | 2 +- frame/beefy-mmr/src/mock.rs | 2 +- frame/beefy/src/mock.rs | 2 +- frame/benchmarking/src/baseline.rs | 2 +- frame/benchmarking/src/tests.rs | 2 +- frame/benchmarking/src/tests_instance.rs | 2 +- frame/bounties/src/tests.rs | 2 +- frame/collective/src/tests.rs | 5 +++-- frame/contracts/src/tests.rs | 2 +- frame/democracy/src/tests.rs | 2 +- frame/election-provider-multi-phase/src/mock.rs | 2 +- frame/election-provider-support/src/onchain.rs | 2 +- frame/elections-phragmen/src/lib.rs | 2 +- frame/elections/src/mock.rs | 2 +- frame/examples/basic/src/tests.rs | 2 +- frame/examples/offchain-worker/src/tests.rs | 2 +- frame/examples/parallel/src/tests.rs | 2 +- frame/executive/src/lib.rs | 2 +- frame/gilt/src/mock.rs | 2 +- frame/grandpa/src/mock.rs | 2 +- frame/identity/src/tests.rs | 2 +- frame/im-online/src/mock.rs | 2 +- frame/indices/src/mock.rs | 2 +- frame/lottery/src/mock.rs | 2 +- frame/membership/src/lib.rs | 2 +- frame/merkle-mountain-range/src/mock.rs | 2 +- frame/multisig/src/tests.rs | 2 +- frame/nicks/src/lib.rs | 2 +- frame/node-authorization/src/mock.rs | 2 +- frame/offences/benchmarking/src/mock.rs | 2 +- frame/offences/src/mock.rs | 2 +- frame/proxy/src/tests.rs | 2 +- frame/randomness-collective-flip/src/lib.rs | 2 +- frame/recovery/src/mock.rs | 2 +- frame/scheduler/src/lib.rs | 2 +- frame/scored-pool/src/mock.rs | 2 +- frame/session/benchmarking/src/mock.rs | 2 +- frame/session/src/mock.rs | 2 +- frame/society/src/mock.rs | 2 +- frame/staking/fuzzer/src/mock.rs | 2 +- frame/staking/src/mock.rs | 2 +- frame/sudo/src/mock.rs | 2 +- frame/support/test/compile_pass/Cargo.toml | 11 +++++++---- frame/support/test/compile_pass/src/lib.rs | 15 ++++++--------- frame/support/test/tests/pallet.rs | 2 +- frame/support/test/tests/pallet_compatibility.rs | 2 +- .../test/tests/pallet_compatibility_instance.rs | 2 +- frame/support/test/tests/pallet_instance.rs | 2 +- .../test/tests/pallet_with_name_trait_is_valid.rs | 2 +- frame/system/benches/bench.rs | 2 +- frame/system/benchmarking/src/mock.rs | 2 +- frame/system/src/mock.rs | 2 +- frame/timestamp/src/lib.rs | 2 +- frame/tips/src/tests.rs | 2 +- .../asset-tx-payment/src/tests.rs | 3 ++- frame/transaction-payment/src/lib.rs | 2 +- frame/transaction-storage/src/mock.rs | 2 +- frame/treasury/src/tests.rs | 2 +- frame/uniques/src/mock.rs | 2 +- frame/utility/src/tests.rs | 2 +- frame/vesting/src/mock.rs | 2 +- test-utils/runtime/src/lib.rs | 2 +- 75 files changed, 90 insertions(+), 93 deletions(-) diff --git a/bin/node-template/pallets/template/src/mock.rs b/bin/node-template/pallets/template/src/mock.rs index cc8d7ed2c165e..733ac79d6577c 100644 --- a/bin/node-template/pallets/template/src/mock.rs +++ b/bin/node-template/pallets/template/src/mock.rs @@ -51,7 +51,7 @@ impl system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_template::Config for Test { diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 78541a93deaf2..032c39fe76f60 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -26,7 +26,7 @@ use sp_version::RuntimeVersion; // A few exports that help ease life for downstream crates. pub use frame_support::{ construct_runtime, parameter_types, - traits::{KeyOwnerProofSystem, Randomness, StorageInfo}, + traits::{KeyOwnerProofSystem, Randomness, StorageInfo, ConstU32}, weights::{ constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, IdentityFee, Weight, @@ -191,7 +191,7 @@ impl frame_system::Config for Runtime { type SS58Prefix = SS58Prefix; /// The set code logic, just the default since we're not a parachain. type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_randomness_collective_flip::Config for Runtime {} diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 5ad337e1eef89..2d8664d5a58b4 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -27,7 +27,7 @@ use frame_support::{ construct_runtime, parameter_types, traits::{ Currency, EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter, KeyOwnerProofSystem, - LockIdentifier, Nothing, OnUnbalanced, U128CurrencyToVote, + LockIdentifier, Nothing, OnUnbalanced, U128CurrencyToVote, ConstU128, }, weights::{ constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, @@ -219,7 +219,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = frame_system::weights::SubstrateWeight; type SS58Prefix = SS58Prefix; type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_randomness_collective_flip::Config for Runtime {} @@ -1182,6 +1182,7 @@ impl pallet_assets::Config for Runtime { type Currency = Balances; type ForceOrigin = EnsureRoot; type AssetDeposit = AssetDeposit; + type AssetAccountDeposit = ConstU128; type MetadataDepositBase = MetadataDepositBase; type MetadataDepositPerByte = MetadataDepositPerByte; type ApprovalDeposit = ApprovalDeposit; diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 91b5db59953c4..c749db7011c46 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -234,11 +234,6 @@ pub mod pallet { #[pallet::constant] type StringLimit: Get; - /// The number of non-provider asset accounts which may exist per account without a deposit - /// being paid. - #[pallet::constant] - type FreeAssetAccounts: Get; - /// A hook to allow a per-asset, per-account minimum balance to be enforced. This must be /// respected in all permissionless operations. type Freezer: FrozenBalance; diff --git a/frame/assets/src/mock.rs b/frame/assets/src/mock.rs index 503ea13fdeaa0..7c310798d555b 100644 --- a/frame/assets/src/mock.rs +++ b/frame/assets/src/mock.rs @@ -92,7 +92,6 @@ impl Config for Test { type MetadataDepositBase = ConstU64<1>; type MetadataDepositPerByte = ConstU64<1>; type ApprovalDeposit = ConstU64<1>; - type FreeAssetAccounts = ConstU32<2>; type StringLimit = ConstU32<50>; type Freezer = TestFreezer; type WeightInfo = (); diff --git a/frame/atomic-swap/src/tests.rs b/frame/atomic-swap/src/tests.rs index 2a145de697e36..47e33252e0943 100644 --- a/frame/atomic-swap/src/tests.rs +++ b/frame/atomic-swap/src/tests.rs @@ -54,7 +54,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/aura/src/mock.rs b/frame/aura/src/mock.rs index 1a7c552023e82..12748bd212d37 100644 --- a/frame/aura/src/mock.rs +++ b/frame/aura/src/mock.rs @@ -78,7 +78,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_timestamp::Config for Test { diff --git a/frame/authority-discovery/src/lib.rs b/frame/authority-discovery/src/lib.rs index fea6a6b1267a6..c867f98af3e17 100644 --- a/frame/authority-discovery/src/lib.rs +++ b/frame/authority-discovery/src/lib.rs @@ -260,7 +260,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } pub struct TestSessionHandler; diff --git a/frame/authorship/src/lib.rs b/frame/authorship/src/lib.rs index 08ab1ba5134fb..cd91957475a1e 100644 --- a/frame/authorship/src/lib.rs +++ b/frame/authorship/src/lib.rs @@ -458,7 +458,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index c7f6300e3456e..457a61bb486a0 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -96,7 +96,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl frame_system::offchain::SendTransactionTypes for Test diff --git a/frame/bags-list/src/mock.rs b/frame/bags-list/src/mock.rs index 5353ea3989949..13e9e01c54a19 100644 --- a/frame/bags-list/src/mock.rs +++ b/frame/bags-list/src/mock.rs @@ -70,7 +70,7 @@ impl frame_system::Config for Runtime { type OnKilledAccount = (); type SystemWeightInfo = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/balances/src/tests_composite.rs b/frame/balances/src/tests_composite.rs index 402974a80294a..b1a7f2417df84 100644 --- a/frame/balances/src/tests_composite.rs +++ b/frame/balances/src/tests_composite.rs @@ -73,7 +73,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const TransactionByteFee: u64 = 1; diff --git a/frame/balances/src/tests_local.rs b/frame/balances/src/tests_local.rs index f1a68aecaedbf..4a5e50891057f 100644 --- a/frame/balances/src/tests_local.rs +++ b/frame/balances/src/tests_local.rs @@ -75,7 +75,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const TransactionByteFee: u64 = 1; diff --git a/frame/balances/src/tests_reentrancy.rs b/frame/balances/src/tests_reentrancy.rs index 5d798eb4d67fd..01b02943484bf 100644 --- a/frame/balances/src/tests_reentrancy.rs +++ b/frame/balances/src/tests_reentrancy.rs @@ -77,7 +77,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const TransactionByteFee: u64 = 1; diff --git a/frame/beefy-mmr/src/mock.rs b/frame/beefy-mmr/src/mock.rs index 0fc5ed37bd2c6..f1195dcc9c028 100644 --- a/frame/beefy-mmr/src/mock.rs +++ b/frame/beefy-mmr/src/mock.rs @@ -86,7 +86,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/beefy/src/mock.rs b/frame/beefy/src/mock.rs index d1c97c9d8c70a..3ce582b29d22d 100644 --- a/frame/beefy/src/mock.rs +++ b/frame/beefy/src/mock.rs @@ -84,7 +84,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_beefy::Config for Test { diff --git a/frame/benchmarking/src/baseline.rs b/frame/benchmarking/src/baseline.rs index 3fbb720149b8f..02fae487bdf1e 100644 --- a/frame/benchmarking/src/baseline.rs +++ b/frame/benchmarking/src/baseline.rs @@ -162,7 +162,7 @@ pub mod mock { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl super::Config for Test {} diff --git a/frame/benchmarking/src/tests.rs b/frame/benchmarking/src/tests.rs index 4202e4dc2e430..e27b3e09dbedb 100644 --- a/frame/benchmarking/src/tests.rs +++ b/frame/benchmarking/src/tests.rs @@ -108,7 +108,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/benchmarking/src/tests_instance.rs b/frame/benchmarking/src/tests_instance.rs index 5aefb157a66b2..09d11eb6c58d2 100644 --- a/frame/benchmarking/src/tests_instance.rs +++ b/frame/benchmarking/src/tests_instance.rs @@ -110,7 +110,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/bounties/src/tests.rs b/frame/bounties/src/tests.rs index 63ec1aecb478c..e18b41d2b8c85 100644 --- a/frame/bounties/src/tests.rs +++ b/frame/bounties/src/tests.rs @@ -84,7 +84,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/collective/src/tests.rs b/frame/collective/src/tests.rs index e1eeea164eb31..1614bc1d30bdb 100644 --- a/frame/collective/src/tests.rs +++ b/frame/collective/src/tests.rs @@ -18,7 +18,8 @@ use super::{Event as CollectiveEvent, *}; use crate as pallet_collective; use frame_support::{ - assert_noop, assert_ok, parameter_types, traits::GenesisBuild, weights::Pays, Hashable, + assert_noop, assert_ok, parameter_types, traits::GenesisBuild, + weights::Pays, Hashable, }; use frame_system::{EventRecord, Phase}; use sp_core::{ @@ -115,7 +116,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl Config for Test { type Origin = Origin; diff --git a/frame/contracts/src/tests.rs b/frame/contracts/src/tests.rs index bd0d2c08b6829..f0f51f530d7a6 100644 --- a/frame/contracts/src/tests.rs +++ b/frame/contracts/src/tests.rs @@ -219,7 +219,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_randomness_collective_flip::Config for Test {} impl pallet_balances::Config for Test { diff --git a/frame/democracy/src/tests.rs b/frame/democracy/src/tests.rs index 75191bb8c6827..3c223172987e8 100644 --- a/frame/democracy/src/tests.rs +++ b/frame/democracy/src/tests.rs @@ -105,7 +105,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) * BlockWeights::get().max_block; diff --git a/frame/election-provider-multi-phase/src/mock.rs b/frame/election-provider-multi-phase/src/mock.rs index 16a2d6c4897eb..46ac32b1eb6f5 100644 --- a/frame/election-provider-multi-phase/src/mock.rs +++ b/frame/election-provider-multi-phase/src/mock.rs @@ -218,7 +218,7 @@ impl frame_system::Config for Runtime { type OnKilledAccount = (); type SystemWeightInfo = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); diff --git a/frame/election-provider-support/src/onchain.rs b/frame/election-provider-support/src/onchain.rs index 66f60b294d855..a2eb53edcf84c 100644 --- a/frame/election-provider-support/src/onchain.rs +++ b/frame/election-provider-support/src/onchain.rs @@ -145,7 +145,7 @@ mod tests { type OnKilledAccount = (); type SystemWeightInfo = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl Config for Runtime { diff --git a/frame/elections-phragmen/src/lib.rs b/frame/elections-phragmen/src/lib.rs index e6f75c071a7f2..8daa4e7fe13c1 100644 --- a/frame/elections-phragmen/src/lib.rs +++ b/frame/elections-phragmen/src/lib.rs @@ -1150,7 +1150,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/elections/src/mock.rs b/frame/elections/src/mock.rs index aa877b5faf7d8..bce60534a3522 100644 --- a/frame/elections/src/mock.rs +++ b/frame/elections/src/mock.rs @@ -60,7 +60,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/examples/basic/src/tests.rs b/frame/examples/basic/src/tests.rs index c5292e0258b28..b97083f27d5ee 100644 --- a/frame/examples/basic/src/tests.rs +++ b/frame/examples/basic/src/tests.rs @@ -79,7 +79,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/examples/offchain-worker/src/tests.rs b/frame/examples/offchain-worker/src/tests.rs index fb17c705585ea..9fb965784f186 100644 --- a/frame/examples/offchain-worker/src/tests.rs +++ b/frame/examples/offchain-worker/src/tests.rs @@ -77,7 +77,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } type Extrinsic = TestXt; diff --git a/frame/examples/parallel/src/tests.rs b/frame/examples/parallel/src/tests.rs index a192a8e4ec61a..5de9af878723a 100644 --- a/frame/examples/parallel/src/tests.rs +++ b/frame/examples/parallel/src/tests.rs @@ -68,7 +68,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/executive/src/lib.rs b/frame/executive/src/lib.rs index 4148c553e8047..864efc801faf7 100644 --- a/frame/executive/src/lib.rs +++ b/frame/executive/src/lib.rs @@ -779,7 +779,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } type Balance = u64; diff --git a/frame/gilt/src/mock.rs b/frame/gilt/src/mock.rs index 57da5bb4dfedc..9ea33a6d6b68d 100644 --- a/frame/gilt/src/mock.rs +++ b/frame/gilt/src/mock.rs @@ -74,7 +74,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/grandpa/src/mock.rs b/frame/grandpa/src/mock.rs index 4fbf2b1c0edba..7670e06ccb092 100644 --- a/frame/grandpa/src/mock.rs +++ b/frame/grandpa/src/mock.rs @@ -98,7 +98,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl frame_system::offchain::SendTransactionTypes for Test diff --git a/frame/identity/src/tests.rs b/frame/identity/src/tests.rs index 44e56f98f5bc0..abb12f6320527 100644 --- a/frame/identity/src/tests.rs +++ b/frame/identity/src/tests.rs @@ -73,7 +73,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/im-online/src/mock.rs b/frame/im-online/src/mock.rs index 534debc7cc556..1d985b9007ea9 100644 --- a/frame/im-online/src/mock.rs +++ b/frame/im-online/src/mock.rs @@ -139,7 +139,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/indices/src/mock.rs b/frame/indices/src/mock.rs index 26fc03cc16d4d..3e3aed2986b9f 100644 --- a/frame/indices/src/mock.rs +++ b/frame/indices/src/mock.rs @@ -69,7 +69,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/lottery/src/mock.rs b/frame/lottery/src/mock.rs index 8be943701dfa2..df86e063c477f 100644 --- a/frame/lottery/src/mock.rs +++ b/frame/lottery/src/mock.rs @@ -79,7 +79,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/membership/src/lib.rs b/frame/membership/src/lib.rs index 006333318e3a8..4bcc28c0ef46a 100644 --- a/frame/membership/src/lib.rs +++ b/frame/membership/src/lib.rs @@ -560,7 +560,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } ord_parameter_types! { pub const One: u64 = 1; diff --git a/frame/merkle-mountain-range/src/mock.rs b/frame/merkle-mountain-range/src/mock.rs index 288abdb856483..392ae5050a96c 100644 --- a/frame/merkle-mountain-range/src/mock.rs +++ b/frame/merkle-mountain-range/src/mock.rs @@ -69,7 +69,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl Config for Test { diff --git a/frame/multisig/src/tests.rs b/frame/multisig/src/tests.rs index 1f05ad06c428c..f050ac9d72001 100644 --- a/frame/multisig/src/tests.rs +++ b/frame/multisig/src/tests.rs @@ -74,7 +74,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/nicks/src/lib.rs b/frame/nicks/src/lib.rs index 36e3d7f72b786..ea58ea693d3fb 100644 --- a/frame/nicks/src/lib.rs +++ b/frame/nicks/src/lib.rs @@ -297,7 +297,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/node-authorization/src/mock.rs b/frame/node-authorization/src/mock.rs index 7ee4dbf23f3c0..8e2bc7cfd2a6d 100644 --- a/frame/node-authorization/src/mock.rs +++ b/frame/node-authorization/src/mock.rs @@ -71,7 +71,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } ord_parameter_types! { diff --git a/frame/offences/benchmarking/src/mock.rs b/frame/offences/benchmarking/src/mock.rs index 1f1ab0ec27b61..0c21fc6266d72 100644 --- a/frame/offences/benchmarking/src/mock.rs +++ b/frame/offences/benchmarking/src/mock.rs @@ -63,7 +63,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: Balance = 10; diff --git a/frame/offences/src/mock.rs b/frame/offences/src/mock.rs index 0d7b217c35ca2..c2db42ec72fac 100644 --- a/frame/offences/src/mock.rs +++ b/frame/offences/src/mock.rs @@ -112,7 +112,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl Config for Runtime { diff --git a/frame/proxy/src/tests.rs b/frame/proxy/src/tests.rs index 1f2522a546d97..538527d47ecd0 100644 --- a/frame/proxy/src/tests.rs +++ b/frame/proxy/src/tests.rs @@ -78,7 +78,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/randomness-collective-flip/src/lib.rs b/frame/randomness-collective-flip/src/lib.rs index d6fd72ee968d9..eee70984f2576 100644 --- a/frame/randomness-collective-flip/src/lib.rs +++ b/frame/randomness-collective-flip/src/lib.rs @@ -219,7 +219,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_randomness_collective_flip::Config for Test {} diff --git a/frame/recovery/src/mock.rs b/frame/recovery/src/mock.rs index 8b04c23a10c9f..1bd7507436b7a 100644 --- a/frame/recovery/src/mock.rs +++ b/frame/recovery/src/mock.rs @@ -75,7 +75,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/scheduler/src/lib.rs b/frame/scheduler/src/lib.rs index f749aff9e02b3..afed9b129c8e9 100644 --- a/frame/scheduler/src/lib.rs +++ b/frame/scheduler/src/lib.rs @@ -928,7 +928,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl logger::Config for Test { type Event = Event; diff --git a/frame/scored-pool/src/mock.rs b/frame/scored-pool/src/mock.rs index 136f19e60693a..992aecba38e82 100644 --- a/frame/scored-pool/src/mock.rs +++ b/frame/scored-pool/src/mock.rs @@ -81,7 +81,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_balances::Config for Test { diff --git a/frame/session/benchmarking/src/mock.rs b/frame/session/benchmarking/src/mock.rs index b5ae4acd55203..4948b9233ceb6 100644 --- a/frame/session/benchmarking/src/mock.rs +++ b/frame/session/benchmarking/src/mock.rs @@ -68,7 +68,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: Balance = 10; diff --git a/frame/session/src/mock.rs b/frame/session/src/mock.rs index b11f639b2c062..d0511d3936822 100644 --- a/frame/session/src/mock.rs +++ b/frame/session/src/mock.rs @@ -264,7 +264,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_timestamp::Config for Test { diff --git a/frame/society/src/mock.rs b/frame/society/src/mock.rs index a7fe52b0982da..4348f2378c425 100644 --- a/frame/society/src/mock.rs +++ b/frame/society/src/mock.rs @@ -89,7 +89,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_balances::Config for Test { diff --git a/frame/staking/fuzzer/src/mock.rs b/frame/staking/fuzzer/src/mock.rs index ef065318797ed..4d569d1a59cfe 100644 --- a/frame/staking/fuzzer/src/mock.rs +++ b/frame/staking/fuzzer/src/mock.rs @@ -65,7 +65,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: Balance = 10; diff --git a/frame/staking/src/mock.rs b/frame/staking/src/mock.rs index 9e72654d8edf0..76ad1bdca1ce5 100644 --- a/frame/staking/src/mock.rs +++ b/frame/staking/src/mock.rs @@ -150,7 +150,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_balances::Config for Test { type MaxLocks = MaxLocks; diff --git a/frame/sudo/src/mock.rs b/frame/sudo/src/mock.rs index c9a7418f67f52..88379d0e5fda8 100644 --- a/frame/sudo/src/mock.rs +++ b/frame/sudo/src/mock.rs @@ -144,7 +144,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } // Implement the logger module's `Config` on the Test runtime. diff --git a/frame/support/test/compile_pass/Cargo.toml b/frame/support/test/compile_pass/Cargo.toml index b8a64f4e7022a..6eb22f6c5ea89 100644 --- a/frame/support/test/compile_pass/Cargo.toml +++ b/frame/support/test/compile_pass/Cargo.toml @@ -17,14 +17,17 @@ scale-info = { version = "1.0", default-features = false, features = ["derive"] sp-core = { version = "4.0.0-dev", default-features = false, path = "../../../../primitives/core" } sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../../../primitives/runtime" } sp-version = { version = "4.0.0-dev", default-features = false, path = "../../../../primitives/version" } -support = { package = "frame-support", version = "4.0.0-dev", default-features = false, path = "../../" } -system = { package = "frame-system", version = "4.0.0-dev", default-features = false, path = "../../../system" } +frame-support = { version = "4.0.0-dev", default-features = false, path = "../../" } +frame-system = { version = "4.0.0-dev", default-features = false, path = "../../../system" } [features] default = ["std"] std = [ "codec/std", "scale-info/std", - "support/std", - "system/std", + "sp-core/std", + "sp-runtime/std", + "sp-version/std", + "frame-support/std", + "frame-system/std", ] diff --git a/frame/support/test/compile_pass/src/lib.rs b/frame/support/test/compile_pass/src/lib.rs index 9aa0a6c865bf3..b3e9174f522ad 100644 --- a/frame/support/test/compile_pass/src/lib.rs +++ b/frame/support/test/compile_pass/src/lib.rs @@ -23,12 +23,9 @@ //! correctly even when frame-support is renamed in Cargo.toml use sp_core::{sr25519, H256}; -use sp_runtime::{ - create_runtime_str, generic, - traits::{BlakeTwo256, IdentityLookup, Verify}, -}; +use sp_runtime::{create_runtime_str, generic, traits::{BlakeTwo256, IdentityLookup, Verify}}; use sp_version::RuntimeVersion; -use support::{construct_runtime, parameter_types}; +use frame_support::{construct_runtime, parameter_types}; pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("frame-support-test-compile-pass"), @@ -51,8 +48,8 @@ parameter_types! { pub const SS58Prefix: u8 = 0; } -impl system::Config for Runtime { - type BaseCallFilter = support::traits::Everything; +impl frame_system::Config for Runtime { + type BaseCallFilter = frame_support::traits::Everything; type BlockWeights = (); type BlockLength = (); type Index = u128; @@ -73,7 +70,7 @@ impl system::Config for Runtime { type OnNewAccount = (); type OnKilledAccount = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; } @@ -88,6 +85,6 @@ construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic { - System: system, + System: frame_system, } ); diff --git a/frame/support/test/tests/pallet.rs b/frame/support/test/tests/pallet.rs index 18fe0e02b313b..4b81382d29562 100644 --- a/frame/support/test/tests/pallet.rs +++ b/frame/support/test/tests/pallet.rs @@ -553,7 +553,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet::Config for Runtime { type Event = Event; diff --git a/frame/support/test/tests/pallet_compatibility.rs b/frame/support/test/tests/pallet_compatibility.rs index 4f6400ce0cde8..0cd6a6e59cffc 100644 --- a/frame/support/test/tests/pallet_compatibility.rs +++ b/frame/support/test/tests/pallet_compatibility.rs @@ -246,7 +246,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet::Config for Runtime { type Event = Event; diff --git a/frame/support/test/tests/pallet_compatibility_instance.rs b/frame/support/test/tests/pallet_compatibility_instance.rs index d6610f14363a2..16f5e16cb873e 100644 --- a/frame/support/test/tests/pallet_compatibility_instance.rs +++ b/frame/support/test/tests/pallet_compatibility_instance.rs @@ -226,7 +226,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet::Config for Runtime { type Event = Event; diff --git a/frame/support/test/tests/pallet_instance.rs b/frame/support/test/tests/pallet_instance.rs index 026cc1f1d5eec..0f6533a6d39e7 100644 --- a/frame/support/test/tests/pallet_instance.rs +++ b/frame/support/test/tests/pallet_instance.rs @@ -274,7 +274,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet::Config for Runtime { type Event = Event; diff --git a/frame/support/test/tests/pallet_with_name_trait_is_valid.rs b/frame/support/test/tests/pallet_with_name_trait_is_valid.rs index b49db0deeb387..170e515740b3c 100644 --- a/frame/support/test/tests/pallet_with_name_trait_is_valid.rs +++ b/frame/support/test/tests/pallet_with_name_trait_is_valid.rs @@ -152,7 +152,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_test::Trait for Runtime { diff --git a/frame/system/benches/bench.rs b/frame/system/benches/bench.rs index 4df07ef42a911..0d513ff599d53 100644 --- a/frame/system/benches/bench.rs +++ b/frame/system/benches/bench.rs @@ -92,7 +92,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl module::Config for Runtime { diff --git a/frame/system/benchmarking/src/mock.rs b/frame/system/benchmarking/src/mock.rs index 1501601ffde35..ff00b76c45fdf 100644 --- a/frame/system/benchmarking/src/mock.rs +++ b/frame/system/benchmarking/src/mock.rs @@ -62,7 +62,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl crate::Config for Test {} diff --git a/frame/system/src/mock.rs b/frame/system/src/mock.rs index e066cffb9b48a..de89324ec9fb4 100644 --- a/frame/system/src/mock.rs +++ b/frame/system/src/mock.rs @@ -111,7 +111,7 @@ impl Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } pub type SysEvent = frame_system::Event; diff --git a/frame/timestamp/src/lib.rs b/frame/timestamp/src/lib.rs index 509e8002e453e..ae9a3b5f69ad9 100644 --- a/frame/timestamp/src/lib.rs +++ b/frame/timestamp/src/lib.rs @@ -372,7 +372,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const MinimumPeriod: u64 = 5; diff --git a/frame/tips/src/tests.rs b/frame/tips/src/tests.rs index 38599d3de8ed7..7d6a717347310 100644 --- a/frame/tips/src/tests.rs +++ b/frame/tips/src/tests.rs @@ -83,7 +83,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/transaction-payment/asset-tx-payment/src/tests.rs b/frame/transaction-payment/asset-tx-payment/src/tests.rs index 7a8f1fd7d73d3..106b361aff8f3 100644 --- a/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -112,7 +112,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { @@ -170,6 +170,7 @@ impl pallet_assets::Config for Runtime { type Currency = Balances; type ForceOrigin = EnsureRoot; type AssetDeposit = AssetDeposit; + type AssetAccountDeposit = frame_support::traits::ConstU64<2>; type MetadataDepositBase = MetadataDeposit; type MetadataDepositPerByte = MetadataDeposit; type ApprovalDeposit = MetadataDeposit; diff --git a/frame/transaction-payment/src/lib.rs b/frame/transaction-payment/src/lib.rs index 11f2e4c26cf18..badc088f0b13e 100644 --- a/frame/transaction-payment/src/lib.rs +++ b/frame/transaction-payment/src/lib.rs @@ -865,7 +865,7 @@ mod tests { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/transaction-storage/src/mock.rs b/frame/transaction-storage/src/mock.rs index e6f7c52c30b51..49b81348e7d4f 100644 --- a/frame/transaction-storage/src/mock.rs +++ b/frame/transaction-storage/src/mock.rs @@ -77,7 +77,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = SS58Prefix; type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/treasury/src/tests.rs b/frame/treasury/src/tests.rs index cd12d42e1ce38..c2b41e7165234 100644 --- a/frame/treasury/src/tests.rs +++ b/frame/treasury/src/tests.rs @@ -79,7 +79,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/uniques/src/mock.rs b/frame/uniques/src/mock.rs index 38523f3c84cd9..f65f69209b9ed 100644 --- a/frame/uniques/src/mock.rs +++ b/frame/uniques/src/mock.rs @@ -69,7 +69,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { diff --git a/frame/utility/src/tests.rs b/frame/utility/src/tests.rs index 16a6cbe6635c4..169ac6cfff897 100644 --- a/frame/utility/src/tests.rs +++ b/frame/utility/src/tests.rs @@ -127,7 +127,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1; diff --git a/frame/vesting/src/mock.rs b/frame/vesting/src/mock.rs index 3ffd0b739fb6d..1e04875a7e077 100644 --- a/frame/vesting/src/mock.rs +++ b/frame/vesting/src/mock.rs @@ -64,7 +64,7 @@ impl frame_system::Config for Test { type OnKilledAccount = (); type OnNewAccount = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; type Origin = Origin; type PalletInfo = PalletInfo; type SS58Prefix = (); diff --git a/test-utils/runtime/src/lib.rs b/test-utils/runtime/src/lib.rs index 44e22eb1e01f0..7b78880c2c3bf 100644 --- a/test-utils/runtime/src/lib.rs +++ b/test-utils/runtime/src/lib.rs @@ -591,7 +591,7 @@ impl frame_system::Config for Runtime { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); - type MaxConsumers = ConstU32<16>; + type MaxConsumers = frame_support::traits::ConstU32<16>; } impl pallet_timestamp::Config for Runtime { From 3c3d4d1710c378657945ca884abe76686697ea45 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 27 Nov 2021 19:39:25 -0500 Subject: [PATCH 05/17] Fixes --- frame/assets/src/functions.rs | 5 ++-- frame/assets/src/tests.rs | 43 +++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/frame/assets/src/functions.rs b/frame/assets/src/functions.rs index 266ade9cb81c3..be390efa8aed4 100644 --- a/frame/assets/src/functions.rs +++ b/frame/assets/src/functions.rs @@ -562,11 +562,10 @@ impl, I: 'static> Pallet { debug_assert!(source_account.balance.is_zero(), "checked in prep; qed"); if let Remove = Self::dead_account(id, &source, details, &source_account.reason) { Account::::remove(id, &source); + return Ok(()) } - } else { - Account::::insert(id, &source, &source_account) } - + Account::::insert(id, &source, &source_account); Ok(()) })?; diff --git a/frame/assets/src/tests.rs b/frame/assets/src/tests.rs index 5fa3e2f918120..a3eacdda4452f 100644 --- a/frame/assets/src/tests.rs +++ b/frame/assets/src/tests.rs @@ -82,6 +82,49 @@ fn minting_insufficient_assets_with_deposit_without_consumer_should_work() { }); } +#[test] +fn refunding_asset_deposit_with_burn_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, false, 1)); + Balances::make_free_balance_be(&1, 100); + assert_ok!(Assets::touch(Origin::signed(1), 0)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + assert_ok!(Assets::refund(Origin::signed(1), 0, true)); + assert_eq!(Balances::reserved_balance(&1), 0); + assert_eq!(Assets::balance(1, 0), 0); + }); +} + +#[test] +fn refunding_asset_deposit_with_burn_disallowed_should_fail() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, false, 1)); + Balances::make_free_balance_be(&1, 100); + assert_ok!(Assets::touch(Origin::signed(1), 0)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + assert_noop!(Assets::refund(Origin::signed(1), 0, false), Error::::WouldBurn); + }); +} + +#[test] +fn refunding_asset_deposit_without_burn_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Assets::force_create(Origin::root(), 0, 1, false, 1)); + assert_noop!(Assets::mint(Origin::signed(1), 0, 1, 100), TokenError::CannotCreate); + Balances::make_free_balance_be(&1, 100); + assert_ok!(Assets::touch(Origin::signed(1), 0)); + assert_ok!(Assets::mint(Origin::signed(1), 0, 1, 100)); + Balances::make_free_balance_be(&2, 100); + assert_ok!(Assets::transfer(Origin::signed(1), 0, 2, 100)); + assert_eq!(Assets::balance(0, 2), 100); + assert_eq!(Assets::balance(0, 1), 0); + assert_eq!(Balances::reserved_balance(&1), 10); + assert_ok!(Assets::refund(Origin::signed(1), 0, false)); + assert_eq!(Balances::reserved_balance(&1), 0); + assert_eq!(Assets::balance(1, 0), 0); + }); +} + #[test] fn approval_lifecycle_works() { new_test_ext().execute_with(|| { From 4a698aa810518b35b657ed2dd30afb325c1e0037 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 27 Nov 2021 19:51:30 -0500 Subject: [PATCH 06/17] Formatting --- bin/node-template/runtime/src/lib.rs | 2 +- bin/node/runtime/src/lib.rs | 4 +- frame/assets/src/extra_mutator.rs | 5 +- frame/assets/src/functions.rs | 57 ++++++++++++---------- frame/assets/src/lib.rs | 11 ++--- frame/assets/src/mock.rs | 5 +- frame/assets/src/types.rs | 6 ++- frame/collective/src/tests.rs | 3 +- frame/support/src/traits.rs | 4 +- frame/support/src/traits/misc.rs | 2 +- frame/support/test/compile_pass/src/lib.rs | 7 ++- 11 files changed, 59 insertions(+), 47 deletions(-) diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index 032c39fe76f60..39d73653f5ac7 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -26,7 +26,7 @@ use sp_version::RuntimeVersion; // A few exports that help ease life for downstream crates. pub use frame_support::{ construct_runtime, parameter_types, - traits::{KeyOwnerProofSystem, Randomness, StorageInfo, ConstU32}, + traits::{ConstU32, KeyOwnerProofSystem, Randomness, StorageInfo}, weights::{ constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, IdentityFee, Weight, diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 2d8664d5a58b4..ad5529409788b 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -26,8 +26,8 @@ use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{ construct_runtime, parameter_types, traits::{ - Currency, EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter, KeyOwnerProofSystem, - LockIdentifier, Nothing, OnUnbalanced, U128CurrencyToVote, ConstU128, + ConstU128, Currency, EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter, + KeyOwnerProofSystem, LockIdentifier, Nothing, OnUnbalanced, U128CurrencyToVote, }, weights::{ constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, diff --git a/frame/assets/src/extra_mutator.rs b/frame/assets/src/extra_mutator.rs index af263113b45c3..702a523acb9ac 100644 --- a/frame/assets/src/extra_mutator.rs +++ b/frame/assets/src/extra_mutator.rs @@ -89,7 +89,10 @@ impl, I: 'static> ExtraMutator { pub fn revert(mut self) -> Result<(), ()> { self.pending = None; Account::::try_mutate_exists(self.id, self.who.borrow(), |maybe_account| { - maybe_account.as_mut().ok_or(()).map(|account| account.extra = self.original.clone()) + maybe_account + .as_mut() + .ok_or(()) + .map(|account| account.extra = self.original.clone()) }) } } diff --git a/frame/assets/src/functions.rs b/frame/assets/src/functions.rs index be390efa8aed4..5c2d66d062014 100644 --- a/frame/assets/src/functions.rs +++ b/frame/assets/src/functions.rs @@ -21,7 +21,7 @@ use super::*; use frame_support::{traits::Get, BoundedVec}; #[must_use] -pub(super)enum DeadConsequence { +pub(super) enum DeadConsequence { Remove, Keep, } @@ -46,7 +46,10 @@ impl, I: 'static> Pallet { } /// Get the asset `id` balance of `who` if the asset-account exists. - pub fn maybe_balance(id: T::AssetId, who: impl sp_std::borrow::Borrow) -> Option { + pub fn maybe_balance( + id: T::AssetId, + who: impl sp_std::borrow::Borrow, + ) -> Option { Account::::get(id, who.borrow()).map(|a| a.balance) } @@ -87,8 +90,8 @@ impl, I: 'static> Pallet { d.sufficients = d.sufficients.saturating_sub(1); frame_system::Pallet::::dec_sufficients(who); }, - ExistenceReason::DepositHeld(_) => { return Keep } - ExistenceReason::DepositRefunded => {} + ExistenceReason::DepositHeld(_) => return Keep, + ExistenceReason::DepositRefunded => {}, } d.accounts = d.accounts.saturating_sub(1); T::Freezer::died(what, who); @@ -280,31 +283,28 @@ impl, I: 'static> Pallet { } /// Creates a account for `who` to hold asset `id` with a zero balance and takes a deposit. - pub(super) fn do_touch( - id: T::AssetId, - who: T::AccountId, - ) -> DispatchResult { + pub(super) fn do_touch(id: T::AssetId, who: T::AccountId) -> DispatchResult { ensure!(!Account::::contains_key(id, &who), Error::::AlreadyExists); let deposit = T::AssetAccountDeposit::get(); let mut details = Asset::::get(&id).ok_or(Error::::Unknown)?; let reason = Self::new_account(&who, &mut details, Some(deposit))?; T::Currency::reserve(&who, deposit)?; Asset::::insert(&id, details); - Account::::insert(id, &who, AssetAccountOf:: { - balance: Zero::zero(), - is_frozen: false, - reason, - extra: T::Extra::default(), - }); + Account::::insert( + id, + &who, + AssetAccountOf:: { + balance: Zero::zero(), + is_frozen: false, + reason, + extra: T::Extra::default(), + }, + ); Ok(()) } /// Returns a deposit, destroying an asset-account unless sufficient. - pub(super) fn do_refund( - id: T::AssetId, - who: T::AccountId, - allow_burn: bool, - ) -> DispatchResult { + pub(super) fn do_refund(id: T::AssetId, who: T::AccountId, allow_burn: bool) -> DispatchResult { let mut account = Account::::get(id, &who).ok_or(Error::::NoDeposit)?; let deposit = account.reason.take_deposit().ok_or(Error::::NoDeposit)?; let mut details = Asset::::get(&id).ok_or(Error::::Unknown)?; @@ -382,7 +382,7 @@ impl, I: 'static> Pallet { match maybe_account { Some(ref mut account) => { account.balance.saturating_accrue(amount); - } + }, maybe_account @ None => { ensure!(amount >= details.min_balance, TokenError::BelowMinimum); *maybe_account = Some(AssetAccountOf:: { @@ -391,7 +391,7 @@ impl, I: 'static> Pallet { is_frozen: false, extra: T::Extra::default(), }); - } + }, } Ok(()) })?; @@ -511,7 +511,8 @@ impl, I: 'static> Pallet { let debit = Self::prep_debit(id, &source, amount, f.into())?; let (credit, maybe_burn) = Self::prep_credit(id, &dest, amount, debit, f.burn_dust)?; - let mut source_account = Account::::get(id, &source).ok_or(Error::::NoAccount)?; + let mut source_account = + Account::::get(id, &source).ok_or(Error::::NoAccount)?; Asset::::try_mutate(id, |maybe_details| -> DispatchResult { let details = maybe_details.as_mut().ok_or(Error::::Unknown)?; @@ -541,10 +542,14 @@ impl, I: 'static> Pallet { Account::::try_mutate(id, &dest, |maybe_account| -> DispatchResult { match maybe_account { Some(ref mut account) => { - // Calculate new balance; this will not saturate since it's already checked in prep. - debug_assert!(account.balance.checked_add(&credit).is_some(), "checked in prep; qed"); + // Calculate new balance; this will not saturate since it's already checked + // in prep. + debug_assert!( + account.balance.checked_add(&credit).is_some(), + "checked in prep; qed" + ); account.balance.saturating_accrue(credit); - } + }, maybe_account @ None => { *maybe_account = Some(AssetAccountOf:: { balance: credit, @@ -552,7 +557,7 @@ impl, I: 'static> Pallet { reason: Self::new_account(&dest, details, None)?, extra: T::Extra::default(), }); - } + }, } Ok(()) })?; diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index c749db7011c46..d80b66ce7eedb 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -255,7 +255,7 @@ pub mod pallet { >; #[pallet::storage] - /// The number of consumer asset-accounts being held. If this is some, the it implies a + /// The number of consumer asset-accounts being held. If this is some, the it implies a pub(super) type ConsumerAccounts, I: 'static = ()> = StorageMap< _, Blake2_128Concat, @@ -686,16 +686,13 @@ pub mod pallet { /// /// A deposit will be taken from the signer account. /// - /// - `origin`: Must be Signed; the signer account must have sufficient funds for a - /// deposit to be taken. + /// - `origin`: Must be Signed; the signer account must have sufficient funds for a deposit + /// to be taken. /// - `id`: The identifier of the asset for the account to be created. /// /// Emits `Touched` event when successful. #[pallet::weight(T::WeightInfo::mint())] - pub fn touch( - origin: OriginFor, - #[pallet::compact] id: T::AssetId, - ) -> DispatchResult { + pub fn touch(origin: OriginFor, #[pallet::compact] id: T::AssetId) -> DispatchResult { Self::do_touch(id, ensure_signed(origin)?) } diff --git a/frame/assets/src/mock.rs b/frame/assets/src/mock.rs index 7c310798d555b..1e88421dd5acd 100644 --- a/frame/assets/src/mock.rs +++ b/frame/assets/src/mock.rs @@ -20,7 +20,10 @@ use super::*; use crate as pallet_assets; -use frame_support::{construct_runtime, traits::{ConstU32, ConstU64, GenesisBuild}}; +use frame_support::{ + construct_runtime, + traits::{ConstU32, ConstU64, GenesisBuild}, +}; use sp_core::H256; use sp_runtime::{ testing::Header, diff --git a/frame/assets/src/types.rs b/frame/assets/src/types.rs index fd329865132c1..06b7b9dbe6e12 100644 --- a/frame/assets/src/types.rs +++ b/frame/assets/src/types.rs @@ -27,7 +27,7 @@ use sp_runtime::{traits::Convert, FixedPointNumber, FixedPointOperand, FixedU128 pub(super) type DepositBalanceOf = <>::Currency as Currency<::AccountId>>::Balance; pub(super) type AssetAccountOf = - AssetAccount::<>::Balance, DepositBalanceOf, >::Extra>; + AssetAccount<>::Balance, DepositBalanceOf, >::Extra>; #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, MaxEncodedLen, TypeInfo)] pub struct AssetDetails { @@ -101,7 +101,9 @@ impl ExistenceReason { if !matches!(self, ExistenceReason::DepositHeld(_)) { return None } - if let ExistenceReason::DepositHeld(deposit) = sp_std::mem::replace(self, ExistenceReason::DepositRefunded) { + if let ExistenceReason::DepositHeld(deposit) = + sp_std::mem::replace(self, ExistenceReason::DepositRefunded) + { return Some(deposit) } else { return None diff --git a/frame/collective/src/tests.rs b/frame/collective/src/tests.rs index 1614bc1d30bdb..466cdb3eeeb5b 100644 --- a/frame/collective/src/tests.rs +++ b/frame/collective/src/tests.rs @@ -18,8 +18,7 @@ use super::{Event as CollectiveEvent, *}; use crate as pallet_collective; use frame_support::{ - assert_noop, assert_ok, parameter_types, traits::GenesisBuild, - weights::Pays, Hashable, + assert_noop, assert_ok, parameter_types, traits::GenesisBuild, weights::Pays, Hashable, }; use frame_system::{EventRecord, Phase}; use sp_core::{ diff --git a/frame/support/src/traits.rs b/frame/support/src/traits.rs index 27c7ad8b2323a..a61188088058b 100644 --- a/frame/support/src/traits.rs +++ b/frame/support/src/traits.rs @@ -50,8 +50,8 @@ pub use filter::{ClearFilterGuard, FilterStack, FilterStackGuard, InstanceFilter mod misc; pub use misc::{ - Backing, ConstBool, ConstU8, ConstU16, ConstU32, ConstU64, ConstU128, ConstI8, ConstI16, - ConstI32, ConstI64, ConstI128, EnsureInherentsAreFirst, EqualPrivilegeOnly, EstimateCallFee, + Backing, ConstBool, ConstI128, ConstI16, ConstI32, ConstI64, ConstI8, ConstU128, ConstU16, + ConstU32, ConstU64, ConstU8, EnsureInherentsAreFirst, EqualPrivilegeOnly, EstimateCallFee, ExecuteBlock, ExtrinsicCall, Get, GetBacking, GetDefault, HandleLifetime, IsSubType, IsType, Len, OffchainWorker, OnKilledAccount, OnNewAccount, PrivilegeCmp, SameOrOther, Time, TryDrop, UnixTime, WrapperKeepOpaque, WrapperOpaque, diff --git a/frame/support/src/traits/misc.rs b/frame/support/src/traits/misc.rs index b346886b720bf..165a83b4be2a0 100644 --- a/frame/support/src/traits/misc.rs +++ b/frame/support/src/traits/misc.rs @@ -73,7 +73,7 @@ macro_rules! impl_const_get { Some(T) } } - } + }; } impl_const_get!(ConstBool, bool); diff --git a/frame/support/test/compile_pass/src/lib.rs b/frame/support/test/compile_pass/src/lib.rs index b3e9174f522ad..06fb6345d3c8d 100644 --- a/frame/support/test/compile_pass/src/lib.rs +++ b/frame/support/test/compile_pass/src/lib.rs @@ -22,10 +22,13 @@ //! This crate tests that `construct_runtime!` expands the pallet parts //! correctly even when frame-support is renamed in Cargo.toml +use frame_support::{construct_runtime, parameter_types}; use sp_core::{sr25519, H256}; -use sp_runtime::{create_runtime_str, generic, traits::{BlakeTwo256, IdentityLookup, Verify}}; +use sp_runtime::{ + create_runtime_str, generic, + traits::{BlakeTwo256, IdentityLookup, Verify}, +}; use sp_version::RuntimeVersion; -use frame_support::{construct_runtime, parameter_types}; pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("frame-support-test-compile-pass"), From bc08627904311379b937a2f0ff5a7faa4f147751 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 28 Nov 2021 09:44:03 -0500 Subject: [PATCH 07/17] Docs --- frame/assets/src/functions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/assets/src/functions.rs b/frame/assets/src/functions.rs index 5c2d66d062014..dbd44e69e3553 100644 --- a/frame/assets/src/functions.rs +++ b/frame/assets/src/functions.rs @@ -303,7 +303,7 @@ impl, I: 'static> Pallet { Ok(()) } - /// Returns a deposit, destroying an asset-account unless sufficient. + /// Returns a deposit, destroying an asset-account. pub(super) fn do_refund(id: T::AssetId, who: T::AccountId, allow_burn: bool) -> DispatchResult { let mut account = Account::::get(id, &who).ok_or(Error::::NoDeposit)?; let deposit = account.reason.take_deposit().ok_or(Error::::NoDeposit)?; From c16bf992a5a6ccb4e158ea80fb3b46aaff8dbd96 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sun, 28 Nov 2021 09:44:10 -0500 Subject: [PATCH 08/17] Formatting --- bin/node/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 44cdb0f22d6ff..ea313b626322d 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -26,7 +26,7 @@ use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{ construct_runtime, parameter_types, traits::{ - ConstU32, ConstU128, Currency, EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter, + ConstU128, ConstU32, Currency, EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter, KeyOwnerProofSystem, LockIdentifier, Nothing, OnUnbalanced, U128CurrencyToVote, }, weights::{ From b6d42af1e651cde5a4f124511fdaed999950e328 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 30 Nov 2021 14:13:38 -0500 Subject: [PATCH 09/17] Destroyed assets are properly tidied --- frame/assets/src/functions.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/frame/assets/src/functions.rs b/frame/assets/src/functions.rs index dbd44e69e3553..c4ae23771ff9f 100644 --- a/frame/assets/src/functions.rs +++ b/frame/assets/src/functions.rs @@ -83,19 +83,22 @@ impl, I: 'static> Pallet { who: &T::AccountId, d: &mut AssetDetails>, reason: &ExistenceReason>, + force: bool, ) -> DeadConsequence { + let mut result = Remove; match *reason { ExistenceReason::Consumer => frame_system::Pallet::::dec_consumers(who), ExistenceReason::Sufficient => { d.sufficients = d.sufficients.saturating_sub(1); frame_system::Pallet::::dec_sufficients(who); }, - ExistenceReason::DepositHeld(_) => return Keep, ExistenceReason::DepositRefunded => {}, + ExistenceReason::DepositHeld(_) if !force => return Keep, + ExistenceReason::DepositHeld(_) => result = Keep, } d.accounts = d.accounts.saturating_sub(1); T::Freezer::died(what, who); - Remove + result } pub(super) fn can_increase( @@ -315,7 +318,7 @@ impl, I: 'static> Pallet { T::Currency::unreserve(&who, deposit); - if let Remove = Self::dead_account(id, &who, &mut details, &account.reason) { + if let Remove = Self::dead_account(id, &who, &mut details, &account.reason, false) { Account::::remove(id, &who); } else { debug_assert!(false, "refund did not result in dead account?!"); @@ -466,7 +469,7 @@ impl, I: 'static> Pallet { account.balance = account.balance.saturating_sub(actual); if account.balance < details.min_balance { debug_assert!(account.balance.is_zero(), "checked in prep; qed"); - if let Remove = Self::dead_account(id, target, &mut details, &account.reason) { + if let Remove = Self::dead_account(id, target, &mut details, &account.reason, false) { return Ok(()) } }; @@ -565,7 +568,7 @@ impl, I: 'static> Pallet { // Remove source account if it's now dead. if source_account.balance < details.min_balance { debug_assert!(source_account.balance.is_zero(), "checked in prep; qed"); - if let Remove = Self::dead_account(id, &source, details, &source_account.reason) { + if let Remove = Self::dead_account(id, &source, details, &source_account.reason, false) { Account::::remove(id, &source); return Ok(()) } @@ -643,7 +646,10 @@ impl, I: 'static> Pallet { ensure!(details.approvals <= witness.approvals, Error::::BadWitness); for (who, v) in Account::::drain_prefix(id) { - let _ = Self::dead_account(id, &who, &mut details, &v.reason); + // We have to force this as it's destroying the entire asset class. + // This could mean that means that some accounts now have irreversibly reserved + // funds. + let _ = Self::dead_account(id, &who, &mut details, &v.reason, true); } debug_assert_eq!(details.accounts, 0); debug_assert_eq!(details.sufficients, 0); From 1ea28c1dee3fbbea1c470007a7a55d01df23d767 Mon Sep 17 00:00:00 2001 From: Gavin Wood Date: Tue, 7 Dec 2021 17:22:35 +0100 Subject: [PATCH 10/17] Update frame/assets/src/types.rs Co-authored-by: Guillaume Thiolliere --- frame/assets/src/types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/assets/src/types.rs b/frame/assets/src/types.rs index 06b7b9dbe6e12..817dcfffaf158 100644 --- a/frame/assets/src/types.rs +++ b/frame/assets/src/types.rs @@ -117,7 +117,7 @@ pub struct AssetAccount { pub(super) balance: Balance, /// Whether the account is frozen. pub(super) is_frozen: bool, - /// `true` if this balance gave the account a self-sufficient reference. + /// The reason for the existence of the account. pub(super) reason: ExistenceReason, /// Additional "sidecar" data, in case some other pallet wants to use this storage item. pub(super) extra: Extra, From d562a9f858fce7e6c815503ecf183e0383009434 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 7 Dec 2021 17:30:22 +0100 Subject: [PATCH 11/17] Docs --- frame/assets/src/functions.rs | 2 +- frame/assets/src/lib.rs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/frame/assets/src/functions.rs b/frame/assets/src/functions.rs index c4ae23771ff9f..e998e2e41ec0d 100644 --- a/frame/assets/src/functions.rs +++ b/frame/assets/src/functions.rs @@ -647,7 +647,7 @@ impl, I: 'static> Pallet { for (who, v) in Account::::drain_prefix(id) { // We have to force this as it's destroying the entire asset class. - // This could mean that means that some accounts now have irreversibly reserved + // This could mean that some accounts now have irreversibly reserved // funds. let _ = Self::dead_account(id, &who, &mut details, &v.reason, true); } diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index d80b66ce7eedb..8c1bc28e3ec0c 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -702,8 +702,6 @@ pub mod pallet { /// /// - `id`: The identifier of the asset for the account to be created. /// - `allow_burn`: If `true` then assets may be destroyed in order to complete the refund. - /// This will be needed unless the asset is a provider and the balance is greater than the - /// asset's minimum balance. /// /// Emits `Refunded` event when successful. #[pallet::weight(T::WeightInfo::mint())] From 5c3faac2bf7c8f171483f82219e991937648effd Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 7 Dec 2021 17:33:04 +0100 Subject: [PATCH 12/17] Docs --- frame/assets/src/functions.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/assets/src/functions.rs b/frame/assets/src/functions.rs index e998e2e41ec0d..6f689586c386e 100644 --- a/frame/assets/src/functions.rs +++ b/frame/assets/src/functions.rs @@ -387,6 +387,7 @@ impl, I: 'static> Pallet { account.balance.saturating_accrue(amount); }, maybe_account @ None => { + // Note this should never fail as it's already checked by `can_increase`. ensure!(amount >= details.min_balance, TokenError::BelowMinimum); *maybe_account = Some(AssetAccountOf:: { balance: amount, From 7dc7fa9b0620eb7c9e2cfb2bf26b9a95367401d2 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 7 Dec 2021 17:35:42 +0100 Subject: [PATCH 13/17] Formatting --- frame/assets/src/functions.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/frame/assets/src/functions.rs b/frame/assets/src/functions.rs index 6f689586c386e..a34900e74bbbd 100644 --- a/frame/assets/src/functions.rs +++ b/frame/assets/src/functions.rs @@ -470,7 +470,9 @@ impl, I: 'static> Pallet { account.balance = account.balance.saturating_sub(actual); if account.balance < details.min_balance { debug_assert!(account.balance.is_zero(), "checked in prep; qed"); - if let Remove = Self::dead_account(id, target, &mut details, &account.reason, false) { + if let Remove = + Self::dead_account(id, target, &mut details, &account.reason, false) + { return Ok(()) } }; @@ -569,7 +571,9 @@ impl, I: 'static> Pallet { // Remove source account if it's now dead. if source_account.balance < details.min_balance { debug_assert!(source_account.balance.is_zero(), "checked in prep; qed"); - if let Remove = Self::dead_account(id, &source, details, &source_account.reason, false) { + if let Remove = + Self::dead_account(id, &source, details, &source_account.reason, false) + { Account::::remove(id, &source); return Ok(()) } From eb48ea4a7a1c5163127a9da58d9e4690e4d64d33 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 7 Dec 2021 17:36:38 +0100 Subject: [PATCH 14/17] Docs --- frame/assets/src/lib.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 8c1bc28e3ec0c..60fa4e784e870 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -254,18 +254,6 @@ pub mod pallet { AssetDetails>, >; - #[pallet::storage] - /// The number of consumer asset-accounts being held. If this is some, the it implies a - pub(super) type ConsumerAccounts, I: 'static = ()> = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - u32, - OptionQuery, - GetDefault, - ConstU32<300_000>, - >; - #[pallet::storage] /// The holdings of a specific account for a specific asset. pub(super) type Account, I: 'static = ()> = StorageDoubleMap< From fcd82a7949eb75ac0431e95fb5e0c37b054614c0 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 7 Dec 2021 17:37:21 +0100 Subject: [PATCH 15/17] Docs --- frame/assets/src/lib.rs | 62 +++++++++++++++++++-------------------- frame/assets/src/types.rs | 2 +- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 60fa4e784e870..b86661d9fa4fd 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -670,37 +670,6 @@ pub mod pallet { Ok(()) } - /// Create an asset account for non-provider assets. - /// - /// A deposit will be taken from the signer account. - /// - /// - `origin`: Must be Signed; the signer account must have sufficient funds for a deposit - /// to be taken. - /// - `id`: The identifier of the asset for the account to be created. - /// - /// Emits `Touched` event when successful. - #[pallet::weight(T::WeightInfo::mint())] - pub fn touch(origin: OriginFor, #[pallet::compact] id: T::AssetId) -> DispatchResult { - Self::do_touch(id, ensure_signed(origin)?) - } - - /// Return the deposit (if any) of an asset account. - /// - /// The origin must be Signed. - /// - /// - `id`: The identifier of the asset for the account to be created. - /// - `allow_burn`: If `true` then assets may be destroyed in order to complete the refund. - /// - /// Emits `Refunded` event when successful. - #[pallet::weight(T::WeightInfo::mint())] - pub fn refund( - origin: OriginFor, - #[pallet::compact] id: T::AssetId, - allow_burn: bool, - ) -> DispatchResult { - Self::do_refund(id, ensure_signed(origin)?, allow_burn) - } - /// Move some assets from the sender account to another. /// /// Origin must be Signed. @@ -1320,5 +1289,36 @@ pub mod pallet { let destination = T::Lookup::lookup(destination)?; Self::do_transfer_approved(id, &owner, &delegate, &destination, amount) } + + /// Create an asset account for non-provider assets. + /// + /// A deposit will be taken from the signer account. + /// + /// - `origin`: Must be Signed; the signer account must have sufficient funds for a deposit + /// to be taken. + /// - `id`: The identifier of the asset for the account to be created. + /// + /// Emits `Touched` event when successful. + #[pallet::weight(T::WeightInfo::mint())] + pub fn touch(origin: OriginFor, #[pallet::compact] id: T::AssetId) -> DispatchResult { + Self::do_touch(id, ensure_signed(origin)?) + } + + /// Return the deposit (if any) of an asset account. + /// + /// The origin must be Signed. + /// + /// - `id`: The identifier of the asset for the account to be created. + /// - `allow_burn`: If `true` then assets may be destroyed in order to complete the refund. + /// + /// Emits `Refunded` event when successful. + #[pallet::weight(T::WeightInfo::mint())] + pub fn refund( + origin: OriginFor, + #[pallet::compact] id: T::AssetId, + allow_burn: bool, + ) -> DispatchResult { + Self::do_refund(id, ensure_signed(origin)?, allow_burn) + } } } diff --git a/frame/assets/src/types.rs b/frame/assets/src/types.rs index 817dcfffaf158..bdb8c0026c4c4 100644 --- a/frame/assets/src/types.rs +++ b/frame/assets/src/types.rs @@ -161,7 +161,7 @@ pub trait FrozenBalance { /// withdrawable. /// /// In reality, the balance of every account must be at least the sum of this (if `Some`) and - /// the asset's minimum_balance, since there may be complications to destroying an asset's + /// the asset's `minimum_balance`, since there may be complications to destroying an asset's /// account completely. /// /// If `None` is returned, then nothing special is enforced. From d5aad9a136af17624ce762662c4fd46365951a18 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 7 Dec 2021 17:39:38 +0100 Subject: [PATCH 16/17] Fixes --- frame/assets/src/extra_mutator.rs | 2 +- frame/assets/src/impl_stored_map.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frame/assets/src/extra_mutator.rs b/frame/assets/src/extra_mutator.rs index 702a523acb9ac..5ebfc3e547132 100644 --- a/frame/assets/src/extra_mutator.rs +++ b/frame/assets/src/extra_mutator.rs @@ -88,7 +88,7 @@ impl, I: 'static> ExtraMutator { /// Revert any changes, even those already committed by `self` and drop self. pub fn revert(mut self) -> Result<(), ()> { self.pending = None; - Account::::try_mutate_exists(self.id, self.who.borrow(), |maybe_account| { + Account::::try_mutate(self.id, self.who.borrow(), |maybe_account| { maybe_account .as_mut() .ok_or(()) diff --git a/frame/assets/src/impl_stored_map.rs b/frame/assets/src/impl_stored_map.rs index c72a19fadcfae..88e2203f046b6 100644 --- a/frame/assets/src/impl_stored_map.rs +++ b/frame/assets/src/impl_stored_map.rs @@ -36,7 +36,7 @@ impl, I: 'static> StoredMap<(T::AssetId, T::AccountId), T::Extra> f // If the account existed and they want to write a value, then we write. // If the account didn't exist and they want to delete it, then we let it pass. // Otherwise, we fail. - Account::::try_mutate_exists(id, who, |maybe_account| { + Account::::try_mutate(id, who, |maybe_account| { if let Some(extra) = maybe_extra { // They want to write a value. Let this happen only if the account actually exists. if let Some(ref mut account) = maybe_account { From 1f0dbfa65adb96170e32ccc60437e5fecc60a00c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 9 Dec 2021 08:43:25 +0100 Subject: [PATCH 17/17] Fixes --- frame/child-bounties/src/tests.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/frame/child-bounties/src/tests.rs b/frame/child-bounties/src/tests.rs index ada13e968c4d4..8e2569738b1f2 100644 --- a/frame/child-bounties/src/tests.rs +++ b/frame/child-bounties/src/tests.rs @@ -86,6 +86,7 @@ impl frame_system::Config for Test { type SystemWeightInfo = (); type SS58Prefix = (); type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; } parameter_types! { pub const ExistentialDeposit: u64 = 1;