From be3c96b81ea39385ab23d44c58995876957f7b34 Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Sun, 30 Oct 2022 17:29:48 +0100 Subject: [PATCH 1/4] add CreateOrigin to Assets pallet --- bin/node/runtime/src/lib.rs | 1 + frame/assets/src/benchmarking.rs | 8 +++++--- frame/assets/src/lib.rs | 27 ++++++++++++++++++--------- frame/assets/src/mock.rs | 3 ++- frame/uniques/src/lib.rs | 2 +- 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index d49312bd6fe3f..7e047cfa433c8 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -1431,6 +1431,7 @@ impl pallet_assets::Config for Runtime { type Balance = u128; type AssetId = u32; type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = EnsureRoot; type AssetDeposit = AssetDeposit; type AssetAccountDeposit = ConstU128; diff --git a/frame/assets/src/benchmarking.rs b/frame/assets/src/benchmarking.rs index ca891c2f42e4a..fc03d0a9c0e7b 100644 --- a/frame/assets/src/benchmarking.rs +++ b/frame/assets/src/benchmarking.rs @@ -150,12 +150,14 @@ fn assert_event, I: 'static>(generic_event: >::Runti benchmarks_instance_pallet! { create { - let caller: T::AccountId = whitelisted_caller(); + let asset_id = Default::default(); + let origin = T::CreateOrigin::successful_origin(&asset_id); + let caller = T::CreateOrigin::ensure_origin(origin, &asset_id).unwrap(); let caller_lookup = T::Lookup::unlookup(caller.clone()); T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); - }: _(SystemOrigin::Signed(caller.clone()), Default::default(), caller_lookup, 1u32.into()) + }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, 1u32.into()) verify { - assert_last_event::(Event::Created { asset_id: Default::default(), creator: caller.clone(), owner: caller }.into()); + assert_last_event::(Event::Created { asset_id: asset_id, creator: caller.clone(), owner: caller }.into()); } force_create { diff --git a/frame/assets/src/lib.rs b/frame/assets/src/lib.rs index 28743f917d323..7e7d68fa6c7dd 100644 --- a/frame/assets/src/lib.rs +++ b/frame/assets/src/lib.rs @@ -36,15 +36,15 @@ //! //! ### Terminology //! -//! * **Admin**: An account ID uniquely privileged to be able to unfreeze (thaw) an account and it's +//! * **Admin**: An account ID uniquely privileged to be able to unfreeze (thaw) an account and its //! assets, as well as forcibly transfer a particular class of assets between arbitrary accounts //! and reduce the balance of a particular class of assets of arbitrary accounts. //! * **Asset issuance/minting**: The creation of a new asset, whose total supply will belong to the -//! account that issues the asset. This is a privileged operation. +//! account designated as the beneficiary of the asset. This is a privileged operation. //! * **Asset transfer**: The reduction of the balance of an asset of one account with the //! corresponding increase in the balance of another. -//! * **Asset destruction**: The process of reduce the balance of an asset of one account. This is a -//! privileged operation. +//! * **Asset destruction**: The process of reducing the balance of an asset of one account. This is +//! a privileged operation. //! * **Fungible asset**: An asset whose units are interchangeable. //! * **Issuer**: An account ID uniquely privileged to be able to mint a particular class of assets. //! * **Freezer**: An account ID uniquely privileged to be able to freeze an account from @@ -63,12 +63,12 @@ //! //! The assets system in Substrate is designed to make the following possible: //! -//! * Issue a new assets in a permissioned or permissionless way, if permissionless, then with a +//! * Issue new assets in a permissioned or permissionless way, if permissionless, then with a //! deposit required. //! * Allow accounts to be delegated the ability to transfer assets without otherwise existing //! on-chain (*approvals*). //! * Move assets between accounts. -//! * Update the asset's total supply. +//! * Update an asset class's total supply. //! * Allow administrative activities by specially privileged accounts including freezing account //! balances and minting/burning assets. //! @@ -92,6 +92,7 @@ //! * `force_cancel_approval`: Rescind a previous approval. //! //! ### Privileged Functions +//! //! * `destroy`: Destroys an entire asset class; called by the asset class's Owner. //! * `mint`: Increases the asset balance of an account; called by the asset class's Issuer. //! * `burn`: Decreases the asset balance of an account; called by the asset class's Admin. @@ -156,7 +157,7 @@ use frame_support::{ traits::{ tokens::{fungibles, DepositConsequence, WithdrawConsequence}, BalanceStatus::Reserved, - Currency, ReservableCurrency, StoredMap, + Currency, EnsureOriginWithArg, ReservableCurrency, StoredMap, }, }; use frame_system::Config as SystemConfig; @@ -206,6 +207,14 @@ pub mod pallet { /// The currency mechanism. type Currency: ReservableCurrency; + /// Standard asset class creation is only allowed if the origin attempting it and the + /// asset class are in this set. + type CreateOrigin: EnsureOriginWithArg< + Self::RuntimeOrigin, + Self::AssetId, + Success = Self::AccountId, + >; + /// The origin which may forcibly create or destroy an asset or otherwise alter privileged /// attributes. type ForceOrigin: EnsureOrigin; @@ -485,7 +494,7 @@ pub mod pallet { /// /// This new asset class has no assets initially and its owner is the origin. /// - /// The origin must be Signed and the sender must have sufficient funds free. + /// The origin must conform to the configured `CreateOrigin` and have sufficient funds free. /// /// Funds of sender are reserved by `AssetDeposit`. /// @@ -507,7 +516,7 @@ pub mod pallet { admin: AccountIdLookupOf, min_balance: T::Balance, ) -> DispatchResult { - let owner = ensure_signed(origin)?; + let owner = T::CreateOrigin::ensure_origin(origin, &id)?; let admin = T::Lookup::lookup(admin)?; ensure!(!Asset::::contains_key(id), Error::::InUse); diff --git a/frame/assets/src/mock.rs b/frame/assets/src/mock.rs index 1f105eb6b4fbc..21fb52c9cd931 100644 --- a/frame/assets/src/mock.rs +++ b/frame/assets/src/mock.rs @@ -22,7 +22,7 @@ use crate as pallet_assets; use frame_support::{ construct_runtime, parameter_types, - traits::{ConstU32, ConstU64, GenesisBuild}, + traits::{AsEnsureOriginWithArg, ConstU32, ConstU64, GenesisBuild}, }; use sp_core::H256; use sp_runtime::{ @@ -89,6 +89,7 @@ impl Config for Test { type Balance = u64; type AssetId = u32; type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = frame_system::EnsureRoot; type AssetDeposit = ConstU64<1>; type AssetAccountDeposit = ConstU64<10>; diff --git a/frame/uniques/src/lib.rs b/frame/uniques/src/lib.rs index d519eedd2787f..185d8fc0c8edd 100644 --- a/frame/uniques/src/lib.rs +++ b/frame/uniques/src/lib.rs @@ -437,7 +437,7 @@ pub mod pallet { /// /// This new collection has no items initially and its owner is the origin. /// - /// The origin must be Signed and the sender must have sufficient funds free. + /// The origin must conform to the configured `CreateOrigin` and have sufficient funds free. /// /// `ItemDeposit` funds of sender are reserved. /// From ff55b1d4f2c7316acad2c32ee6316fa04ed2471e Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Mon, 31 Oct 2022 08:23:49 +0100 Subject: [PATCH 2/4] fix asset-tx-payment test --- frame/transaction-payment/asset-tx-payment/src/tests.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frame/transaction-payment/asset-tx-payment/src/tests.rs b/frame/transaction-payment/asset-tx-payment/src/tests.rs index e775f3aa92990..6120d725da78f 100644 --- a/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -21,7 +21,7 @@ use frame_support::{ dispatch::{DispatchClass, DispatchInfo, PostDispatchInfo}, pallet_prelude::*, parameter_types, - traits::{fungibles::Mutate, ConstU32, ConstU64, ConstU8, FindAuthor}, + traits::{fungibles::Mutate, AsEnsureOriginWithArg, ConstU32, ConstU64, ConstU8, FindAuthor}, weights::{Weight, WeightToFee as WeightToFeeT}, ConsensusEngineId, }; @@ -157,6 +157,7 @@ impl pallet_assets::Config for Runtime { type Balance = Balance; type AssetId = u32; type Currency = Balances; + type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = EnsureRoot; type AssetDeposit = ConstU64<2>; type AssetAccountDeposit = ConstU64<2>; From 0ab10d83b73eaa4b7669e126824eb9fcfb9612ed Mon Sep 17 00:00:00 2001 From: joepetrowski Date: Mon, 31 Oct 2022 08:44:01 +0100 Subject: [PATCH 3/4] use AccountId > u64 in test --- frame/transaction-payment/asset-tx-payment/src/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/transaction-payment/asset-tx-payment/src/tests.rs b/frame/transaction-payment/asset-tx-payment/src/tests.rs index 6120d725da78f..cfed1c33c9b24 100644 --- a/frame/transaction-payment/asset-tx-payment/src/tests.rs +++ b/frame/transaction-payment/asset-tx-payment/src/tests.rs @@ -157,7 +157,7 @@ impl pallet_assets::Config for Runtime { type Balance = Balance; type AssetId = u32; type Currency = Balances; - type CreateOrigin = AsEnsureOriginWithArg>; + type CreateOrigin = AsEnsureOriginWithArg>; type ForceOrigin = EnsureRoot; type AssetDeposit = ConstU64<2>; type AssetAccountDeposit = ConstU64<2>; From 0c0a5d5b746f977d8bf2e80d303db70d37d82ba0 Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Tue, 1 Nov 2022 17:46:23 +0100 Subject: [PATCH 4/4] Update frame/assets/src/benchmarking.rs Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com> --- frame/assets/src/benchmarking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/assets/src/benchmarking.rs b/frame/assets/src/benchmarking.rs index fc03d0a9c0e7b..2bde2b0c98945 100644 --- a/frame/assets/src/benchmarking.rs +++ b/frame/assets/src/benchmarking.rs @@ -157,7 +157,7 @@ benchmarks_instance_pallet! { T::Currency::make_free_balance_be(&caller, DepositBalanceOf::::max_value()); }: _(SystemOrigin::Signed(caller.clone()), asset_id, caller_lookup, 1u32.into()) verify { - assert_last_event::(Event::Created { asset_id: asset_id, creator: caller.clone(), owner: caller }.into()); + assert_last_event::(Event::Created { asset_id, creator: caller.clone(), owner: caller }.into()); } force_create {