From 8697a1261a31b0b55801ebf3892a7ed4cc09fad0 Mon Sep 17 00:00:00 2001 From: clearloop Date: Thu, 10 Jun 2021 18:41:16 +0800 Subject: [PATCH 01/11] feat(asset-index): add trait AtLeast32Bit for pallet_asset_index::AssetId --- pallets/asset-index/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/asset-index/src/lib.rs b/pallets/asset-index/src/lib.rs index aae50e7d30..3a25c9a085 100644 --- a/pallets/asset-index/src/lib.rs +++ b/pallets/asset-index/src/lib.rs @@ -91,7 +91,7 @@ pub mod pallet { Self::Balance, >; /// Type used to identify assets - type AssetId: Parameter + Member + From + Copy; + type AssetId: Parameter + Member + AtLeast32BitUnsigned + Copy; /// Handles asset depositing and withdrawing from sovereign user accounts type MultiAssetDepository: MultiAssetDepository< Self::AssetId, From 8e415f671a321bdd92ebca36b49dba3f8f7f115a Mon Sep 17 00:00:00 2001 From: clearloop Date: Thu, 10 Jun 2021 19:06:26 +0800 Subject: [PATCH 02/11] feat(asset-index): fix benchmarking.rs --- pallets/asset-index/src/benchmarking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/asset-index/src/benchmarking.rs b/pallets/asset-index/src/benchmarking.rs index 016a2475a5..0bd33fd8a9 100644 --- a/pallets/asset-index/src/benchmarking.rs +++ b/pallets/asset-index/src/benchmarking.rs @@ -9,7 +9,7 @@ use xcm::v0::MultiLocation; benchmarks! { add_asset { - let asset_id = 42.into(); + let asset_id = 42_u32.into(); let caller: T::AccountId = whitelisted_caller(); let million = 1_000_000u32.into(); T::IndexToken::deposit_creating(&caller, million); From 34b24bfd45c113ce8bf04d1039539c7a9268ae95 Mon Sep 17 00:00:00 2001 From: clearloop Date: Tue, 15 Jun 2021 21:15:22 +0800 Subject: [PATCH 03/11] feat(asset-index): refactor MultiAssetRegistry with appended name and symbol --- pallets/asset-index/src/benchmarking.rs | 4 +++ pallets/asset-index/src/lib.rs | 21 ++++++++++++++- pallets/asset-index/src/mock.rs | 8 +++++- pallets/asset-index/src/tests.rs | 32 +++++++++++++++++++++++ pallets/asset-index/src/traits.rs | 20 +++++++++++--- pallets/asset-index/src/types.rs | 11 +++++++- pallets/saft-registry/src/benchmarking.rs | 11 +++++++- pallets/saft-registry/src/lib.rs | 10 ++++++- 8 files changed, 108 insertions(+), 9 deletions(-) diff --git a/pallets/asset-index/src/benchmarking.rs b/pallets/asset-index/src/benchmarking.rs index 0bd33fd8a9..2a8f42d852 100644 --- a/pallets/asset-index/src/benchmarking.rs +++ b/pallets/asset-index/src/benchmarking.rs @@ -15,6 +15,8 @@ benchmarks! { T::IndexToken::deposit_creating(&caller, million); }: _( RawOrigin::Signed(caller.clone()), + b"asset".to_vec(), + b"asset".to_vec(), asset_id, million, AssetAvailability::Liquid(MultiLocation::Null), @@ -23,6 +25,8 @@ benchmarks! { assert_eq!( >::get(asset_id), Some(IndexAssetData::new( + b"asset".to_vec(), + b"asset".to_vec(), million, AssetAvailability::Liquid(MultiLocation::Null) )) diff --git a/pallets/asset-index/src/lib.rs b/pallets/asset-index/src/lib.rs index 3a25c9a085..7d5f36c74a 100644 --- a/pallets/asset-index/src/lib.rs +++ b/pallets/asset-index/src/lib.rs @@ -183,6 +183,8 @@ pub mod pallet { /// Creates IndexAssetData if it doesn’t exist, otherwise adds to list of deposits pub fn add_asset( origin: OriginFor, + name: Vec, + symbol: Vec, asset_id: T::AssetId, units: T::Balance, availability: AssetAvailability, @@ -191,6 +193,8 @@ pub mod pallet { T::AdminOrigin::ensure_origin(origin.clone())?; let caller = ensure_signed(origin)?; >::add_asset( + name, + symbol, &asset_id, &units, &availability, @@ -518,13 +522,20 @@ pub mod pallet { /// Creates IndexAssetData if entry with given assetID does not exist. /// Otherwise adds the units to the existing holding fn add_asset( + name: Vec, + symbol: Vec, asset_id: &T::AssetId, units: &T::Balance, availability: &AssetAvailability, ) -> DispatchResult { Holdings::::try_mutate(asset_id, |value| -> Result<_, Error> { let index_asset_data = value.get_or_insert_with(|| { - IndexAssetData::::new(T::Balance::zero(), availability.clone()) + IndexAssetData::::new( + name, + symbol, + T::Balance::zero(), + availability.clone(), + ) }); index_asset_data.units = index_asset_data .units @@ -541,6 +552,14 @@ pub mod pallet { } impl MultiAssetRegistry for Pallet { + fn asset_name(asset: &T::AssetId) -> Option> { + Holdings::::get(asset).and_then(|holding| Some(holding.name)) + } + + fn asset_symbol(asset: &T::AssetId) -> Option> { + Holdings::::get(asset).and_then(|holding| Some(holding.symbol)) + } + fn native_asset_location(asset: &T::AssetId) -> Option { Holdings::::get(asset).and_then(|holding| { if let AssetAvailability::Liquid(location) = holding.availability { diff --git a/pallets/asset-index/src/mock.rs b/pallets/asset-index/src/mock.rs index 85c39bc51f..a161752d94 100644 --- a/pallets/asset-index/src/mock.rs +++ b/pallets/asset-index/src/mock.rs @@ -82,7 +82,13 @@ ord_parameter_types! { pub struct MockAssetRecorder; impl AssetRecorder for MockAssetRecorder { - fn add_asset(_: &AssetId, _: &Balance, _: &AssetAvailability) -> Result<(), DispatchError> { + fn add_asset( + _name: Vec, + _symbol: Vec, + _: &AssetId, + _: &Balance, + _: &AssetAvailability, + ) -> Result<(), DispatchError> { Ok(()) } fn remove_asset(_: &AssetId) -> Result<(), DispatchError> { diff --git a/pallets/asset-index/src/tests.rs b/pallets/asset-index/src/tests.rs index 643d18ba2e..d948ecf02c 100644 --- a/pallets/asset-index/src/tests.rs +++ b/pallets/asset-index/src/tests.rs @@ -22,6 +22,8 @@ fn non_admin_cannot_call_get_asset() { assert_noop!( AssetIndex::add_asset( Origin::signed(ASHLEY), + b"asset".to_vec(), + b"asset".to_vec(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -39,6 +41,8 @@ fn admin_can_add_asset() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -47,6 +51,8 @@ fn admin_can_add_asset() { assert_eq!( pallet::Holdings::::get(ASSET_A_ID), Some(IndexAssetData::new( + b"asset".to_vec(), + b"asset".to_vec(), 100, AssetAvailability::Liquid(MultiLocation::Null) )) @@ -64,6 +70,8 @@ fn admin_can_add_asset_twice_and_units_accumulate() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -71,6 +79,8 @@ fn admin_can_add_asset_twice_and_units_accumulate() { )); assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -79,6 +89,8 @@ fn admin_can_add_asset_twice_and_units_accumulate() { assert_eq!( pallet::Holdings::::get(ASSET_A_ID), Some(IndexAssetData::new( + b"asset".to_vec(), + b"asset".to_vec(), 200, AssetAvailability::Liquid(MultiLocation::Null) )) @@ -97,6 +109,8 @@ fn deposit_only_works_for_added_liquid_assets() { ); assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), ASSET_A_ID, 100, AssetAvailability::Saft, @@ -115,6 +129,8 @@ fn deposit_works_with_user_balance() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -150,6 +166,8 @@ fn deposit_fails_for_unknown_assets() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -168,6 +186,8 @@ fn deposit_fails_for_when_price_feed_unavailable() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), UNKNOWN_ASSET_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -186,6 +206,8 @@ fn deposit_fails_on_overflowing() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -215,6 +237,8 @@ fn can_calculates_nav() { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), ASSET_A_ID, a_units, AssetAvailability::Liquid(MultiLocation::Null), @@ -223,6 +247,8 @@ fn can_calculates_nav() { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), ASSET_B_ID, b_units, AssetAvailability::Saft, @@ -275,6 +301,8 @@ fn can_withdraw() { // create liquid assets assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), ASSET_A_ID, a_units, AssetAvailability::Liquid(MultiLocation::Null), @@ -282,6 +310,8 @@ fn can_withdraw() { )); assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), ASSET_B_ID, b_units, AssetAvailability::Liquid(MultiLocation::Null), @@ -355,6 +385,8 @@ fn can_withdraw() { // all SAFT holdings are ignored during withdrawal and don't have any effect on the payout assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), + b"asset".to_vec(), + b"asset".to_vec(), 99, 1_000, AssetAvailability::Saft, diff --git a/pallets/asset-index/src/traits.rs b/pallets/asset-index/src/traits.rs index c26bcd61ea..5e4ac06d97 100644 --- a/pallets/asset-index/src/traits.rs +++ b/pallets/asset-index/src/traits.rs @@ -2,8 +2,9 @@ // SPDX-License-Identifier: LGPL-3.0-only pub use crate::types::AssetAvailability; -use frame_support::dispatch::DispatchResult; -use frame_support::sp_runtime::traits::AtLeast32BitUnsigned; +use frame_support::{ + dispatch::DispatchResult, sp_runtime::traits::AtLeast32BitUnsigned, sp_std::vec::Vec, +}; use xcm::v0::MultiLocation; pub trait AssetRecorder { @@ -12,14 +13,25 @@ pub trait AssetRecorder { /// The provided NAV parameter is the Net Asset Value of the total units provided /// given in units of some stable asset. In the case of an AssetId that already exists the /// newly provided NAV will be used to re-value the existing units and compute a total NAV - fn add_asset(id: &AssetId, units: &Balance, availability: &AssetAvailability) - -> DispatchResult; + fn add_asset( + name: Vec, + symbol: Vec, + id: &AssetId, + units: &Balance, + availability: &AssetAvailability, + ) -> DispatchResult; fn remove_asset(id: &AssetId) -> DispatchResult; } /// Type that provides the mapping between `AssetId` and `MultiLocation`. pub trait MultiAssetRegistry { + // Asset name + fn asset_name(asset: &AssetId) -> Option>; + + // Asset symbol + fn asset_symbol(asset: &AssetId) -> Option>; + /// Determines the relative location of the consensus system where the given asset is native from the point of view of the current system fn native_asset_location(asset: &AssetId) -> Option; diff --git a/pallets/asset-index/src/types.rs b/pallets/asset-index/src/types.rs index 3fc051e2a1..0215a7ca21 100644 --- a/pallets/asset-index/src/types.rs +++ b/pallets/asset-index/src/types.rs @@ -35,13 +35,22 @@ pub enum AssetAvailability { #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] /// A representation of some number of assets that are managed by the index pub struct IndexAssetData { + pub name: Vec, + pub symbol: Vec, pub units: Balance, pub availability: AssetAvailability, } impl IndexAssetData { - pub fn new(units: Balance, availability: AssetAvailability) -> Self { + pub fn new( + name: Vec, + symbol: Vec, + units: Balance, + availability: AssetAvailability, + ) -> Self { Self { + name, + symbol, units, availability, } diff --git a/pallets/saft-registry/src/benchmarking.rs b/pallets/saft-registry/src/benchmarking.rs index 0850d6d9f0..78fe2de8ea 100644 --- a/pallets/saft-registry/src/benchmarking.rs +++ b/pallets/saft-registry/src/benchmarking.rs @@ -9,6 +9,8 @@ benchmarks! { add_saft { }: _( >::Root, + b"asset".to_vec(), + b"asset".to_vec(), 0_u32.into(), 100_u32.into(), 20_u32.into() @@ -36,7 +38,14 @@ benchmarks! { // } report_nav { - assert_ok!(>::add_saft(>::Root.into(), 0.into(), 100_u32.into(), 20_u32.into())); + assert_ok!(>::add_saft( + >::Root.into(), + b"asset".to_vec(), + b"".to_vec(), + 0.into(), + 100_u32.into(), + 20_u32.into(), + )); }: _( >::Root, 0.into(), diff --git a/pallets/saft-registry/src/lib.rs b/pallets/saft-registry/src/lib.rs index cf72257167..ba007570bd 100644 --- a/pallets/saft-registry/src/lib.rs +++ b/pallets/saft-registry/src/lib.rs @@ -91,6 +91,8 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::add_saft())] pub fn add_saft( origin: OriginFor, + name: Vec, + symbol: Vec, asset_id: T::AssetId, nav: T::Balance, units: T::Balance, @@ -98,7 +100,13 @@ pub mod pallet { T::AdminOrigin::ensure_origin(origin)?; ActiveSAFTs::::append(asset_id.clone(), SAFTRecord::new(nav, units.clone())); - ::AssetRecorder::add_asset(&asset_id, &units, &AssetAvailability::Saft)?; + ::AssetRecorder::add_asset( + name, + symbol, + &asset_id, + &units, + &AssetAvailability::Saft, + )?; Self::deposit_event(Event::::SAFTAdded(asset_id, 0)); Ok(().into()) From ad695e4ebc03956bc3b97890524654c6cdcb726a Mon Sep 17 00:00:00 2001 From: clearloop Date: Tue, 15 Jun 2021 22:07:27 +0800 Subject: [PATCH 04/11] feat(asset-index): use AssetMetadata --- Cargo.lock | 20 +++++------ pallets/asset-index/src/benchmarking.rs | 6 ++-- pallets/asset-index/src/lib.rs | 25 +++++-------- pallets/asset-index/src/mock.rs | 3 +- pallets/asset-index/src/tests.rs | 48 +++++++++---------------- pallets/asset-index/src/traits.rs | 16 +++------ pallets/asset-index/src/types.rs | 31 ++++++++++------ pallets/saft-registry/src/lib.rs | 11 +++--- pallets/saft-registry/src/mock.rs | 12 +++++-- pallets/saft-registry/src/tests.rs | 5 ++- 10 files changed, 84 insertions(+), 93 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d73941e87..b1b885ba72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8380,10 +8380,10 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" version = "0.9.0" -source = "git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6#1d04678e20555e623c974ee1127bc8a45abcf3d6" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.4#ea5d3570673d125dfe0b7da33b345c3c13195380" dependencies = [ "sc-client-api", - "sp-authorship 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", + "sp-authorship 3.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.4)", "sp-runtime", "thiserror", ] @@ -8391,10 +8391,10 @@ dependencies = [ [[package]] name = "sc-consensus-uncles" version = "0.9.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.4#ea5d3570673d125dfe0b7da33b345c3c13195380" +source = "git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6#1d04678e20555e623c974ee1127bc8a45abcf3d6" dependencies = [ "sc-client-api", - "sp-authorship 3.0.0 (git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.4)", + "sp-authorship 3.0.0 (git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6)", "sp-runtime", "thiserror", ] @@ -8604,7 +8604,7 @@ dependencies = [ [[package]] name = "sc-light" version = "3.0.0" -source = "git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6#1d04678e20555e623c974ee1127bc8a45abcf3d6" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.4#1d04678e20555e623c974ee1127bc8a45abcf3d6" dependencies = [ "hash-db", "lazy_static", @@ -8623,7 +8623,7 @@ dependencies = [ [[package]] name = "sc-light" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.4#1d04678e20555e623c974ee1127bc8a45abcf3d6" +source = "git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6#1d04678e20555e623c974ee1127bc8a45abcf3d6" dependencies = [ "hash-db", "lazy_static", @@ -9532,7 +9532,7 @@ dependencies = [ [[package]] name = "sp-authorship" version = "3.0.0" -source = "git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6#1d04678e20555e623c974ee1127bc8a45abcf3d6" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.4#ea5d3570673d125dfe0b7da33b345c3c13195380" dependencies = [ "async-trait", "parity-scale-codec", @@ -9544,7 +9544,7 @@ dependencies = [ [[package]] name = "sp-authorship" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.4#ea5d3570673d125dfe0b7da33b345c3c13195380" +source = "git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6#1d04678e20555e623c974ee1127bc8a45abcf3d6" dependencies = [ "async-trait", "parity-scale-codec", @@ -9814,7 +9814,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "3.0.0" -source = "git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6#1d04678e20555e623c974ee1127bc8a45abcf3d6" +source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.4#1d04678e20555e623c974ee1127bc8a45abcf3d6" dependencies = [ "lazy_static", "sp-core", @@ -9825,7 +9825,7 @@ dependencies = [ [[package]] name = "sp-keyring" version = "3.0.0" -source = "git+https://github.com/paritytech/substrate?branch=polkadot-v0.9.4#1d04678e20555e623c974ee1127bc8a45abcf3d6" +source = "git+https://github.com/paritytech//substrate?rev=1d04678e20555e623c974ee1127bc8a45abcf3d6#1d04678e20555e623c974ee1127bc8a45abcf3d6" dependencies = [ "lazy_static", "sp-core", diff --git a/pallets/asset-index/src/benchmarking.rs b/pallets/asset-index/src/benchmarking.rs index 2a8f42d852..4d8383bd44 100644 --- a/pallets/asset-index/src/benchmarking.rs +++ b/pallets/asset-index/src/benchmarking.rs @@ -15,8 +15,7 @@ benchmarks! { T::IndexToken::deposit_creating(&caller, million); }: _( RawOrigin::Signed(caller.clone()), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), asset_id, million, AssetAvailability::Liquid(MultiLocation::Null), @@ -25,8 +24,7 @@ benchmarks! { assert_eq!( >::get(asset_id), Some(IndexAssetData::new( - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), million, AssetAvailability::Liquid(MultiLocation::Null) )) diff --git a/pallets/asset-index/src/lib.rs b/pallets/asset-index/src/lib.rs index c34d5dea00..a6621b5989 100644 --- a/pallets/asset-index/src/lib.rs +++ b/pallets/asset-index/src/lib.rs @@ -18,7 +18,7 @@ mod tests; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; pub mod traits; -mod types; +pub mod types; #[frame_support::pallet] // this is requires as the #[pallet::event] proc macro generates code that violates this lint @@ -49,7 +49,8 @@ pub mod pallet { pub use crate::traits::{AssetRecorder, MultiAssetRegistry}; pub use crate::types::MultiAssetAdapter; use crate::types::{ - AssetAvailability, AssetWithdrawal, IndexAssetData, PendingRedemption, RedemptionState, + AssetAvailability, AssetMetadata, AssetWithdrawal, IndexAssetData, PendingRedemption, + RedemptionState, }; type AccountIdFor = ::AccountId; @@ -183,8 +184,7 @@ pub mod pallet { /// Creates IndexAssetData if it doesn’t exist, otherwise adds to list of deposits pub fn add_asset( origin: OriginFor, - name: Vec, - symbol: Vec, + metadata: AssetMetadata, asset_id: T::AssetId, units: T::Balance, availability: AssetAvailability, @@ -200,8 +200,7 @@ pub mod pallet { )?; >::add_asset( - name, - symbol, + metadata, &asset_id, &units, &availability, @@ -529,8 +528,7 @@ pub mod pallet { /// Creates IndexAssetData if entry with given assetID does not exist. /// Otherwise adds the units to the existing holding fn add_asset( - name: Vec, - symbol: Vec, + metadata: AssetMetadata, asset_id: &T::AssetId, units: &T::Balance, availability: &AssetAvailability, @@ -538,8 +536,7 @@ pub mod pallet { Holdings::::try_mutate(asset_id, |value| -> Result<_, Error> { let index_asset_data = value.get_or_insert_with(|| { IndexAssetData::::new( - name, - symbol, + metadata, T::Balance::zero(), availability.clone(), ) @@ -559,12 +556,8 @@ pub mod pallet { } impl MultiAssetRegistry for Pallet { - fn asset_name(asset: &T::AssetId) -> Option> { - Holdings::::get(asset).and_then(|holding| Some(holding.name)) - } - - fn asset_symbol(asset: &T::AssetId) -> Option> { - Holdings::::get(asset).and_then(|holding| Some(holding.symbol)) + fn asset_metadata(asset: &T::AssetId) -> Option { + Holdings::::get(asset).and_then(|holding| Some(holding.metadata)) } fn native_asset_location(asset: &T::AssetId) -> Option { diff --git a/pallets/asset-index/src/mock.rs b/pallets/asset-index/src/mock.rs index cd609fec75..4e1d0fecd7 100644 --- a/pallets/asset-index/src/mock.rs +++ b/pallets/asset-index/src/mock.rs @@ -83,8 +83,7 @@ pub struct MockAssetRecorder; impl AssetRecorder for MockAssetRecorder { fn add_asset( - _name: Vec, - _symbol: Vec, + _: pallet_asset_index::types::AssetMetadata, _: &AssetId, _: &Balance, _: &AssetAvailability, diff --git a/pallets/asset-index/src/tests.rs b/pallets/asset-index/src/tests.rs index 55ed96fea4..dd9327ae24 100644 --- a/pallets/asset-index/src/tests.rs +++ b/pallets/asset-index/src/tests.rs @@ -22,8 +22,7 @@ fn non_admin_cannot_call_get_asset() { assert_noop!( AssetIndex::add_asset( Origin::signed(ASHLEY), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -41,8 +40,7 @@ fn admin_can_add_asset() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -51,8 +49,7 @@ fn admin_can_add_asset() { assert_eq!( pallet::Holdings::::get(ASSET_A_ID), Some(IndexAssetData::new( - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), 100, AssetAvailability::Liquid(MultiLocation::Null) )) @@ -70,8 +67,7 @@ fn admin_can_add_asset_twice_and_units_accumulate() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -79,8 +75,7 @@ fn admin_can_add_asset_twice_and_units_accumulate() { )); assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -89,8 +84,7 @@ fn admin_can_add_asset_twice_and_units_accumulate() { assert_eq!( pallet::Holdings::::get(ASSET_A_ID), Some(IndexAssetData::new( - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), 200, AssetAvailability::Liquid(MultiLocation::Null) )) @@ -109,8 +103,7 @@ fn deposit_only_works_for_added_liquid_assets() { ); assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), ASSET_A_ID, 100, AssetAvailability::Saft, @@ -129,8 +122,7 @@ fn deposit_works_with_user_balance() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -166,8 +158,7 @@ fn deposit_fails_for_unknown_assets() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -186,8 +177,7 @@ fn deposit_ok_for_when_price_feed_unavailable() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), UNKNOWN_ASSET_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -208,8 +198,7 @@ fn deposit_fails_on_overflowing() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -234,8 +223,7 @@ fn can_calculates_nav() { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), ASSET_A_ID, a_units, AssetAvailability::Liquid(MultiLocation::Null), @@ -244,8 +232,7 @@ fn can_calculates_nav() { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), ASSET_B_ID, b_units, AssetAvailability::Saft, @@ -298,8 +285,7 @@ fn can_withdraw() { // create liquid assets assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), ASSET_A_ID, a_units, AssetAvailability::Liquid(MultiLocation::Null), @@ -307,8 +293,7 @@ fn can_withdraw() { )); assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), ASSET_B_ID, b_units, AssetAvailability::Liquid(MultiLocation::Null), @@ -382,8 +367,7 @@ fn can_withdraw() { // all SAFT holdings are ignored during withdrawal and don't have any effect on the payout assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), 99, 1_000, AssetAvailability::Saft, diff --git a/pallets/asset-index/src/traits.rs b/pallets/asset-index/src/traits.rs index 5e4ac06d97..4687febbf1 100644 --- a/pallets/asset-index/src/traits.rs +++ b/pallets/asset-index/src/traits.rs @@ -1,10 +1,8 @@ // Copyright 2021 ChainSafe Systems // SPDX-License-Identifier: LGPL-3.0-only -pub use crate::types::AssetAvailability; -use frame_support::{ - dispatch::DispatchResult, sp_runtime::traits::AtLeast32BitUnsigned, sp_std::vec::Vec, -}; +pub use crate::types::{AssetAvailability, AssetMetadata}; +use frame_support::{dispatch::DispatchResult, sp_runtime::traits::AtLeast32BitUnsigned}; use xcm::v0::MultiLocation; pub trait AssetRecorder { @@ -14,8 +12,7 @@ pub trait AssetRecorder { /// given in units of some stable asset. In the case of an AssetId that already exists the /// newly provided NAV will be used to re-value the existing units and compute a total NAV fn add_asset( - name: Vec, - symbol: Vec, + metadata: AssetMetadata, id: &AssetId, units: &Balance, availability: &AssetAvailability, @@ -26,11 +23,8 @@ pub trait AssetRecorder { /// Type that provides the mapping between `AssetId` and `MultiLocation`. pub trait MultiAssetRegistry { - // Asset name - fn asset_name(asset: &AssetId) -> Option>; - - // Asset symbol - fn asset_symbol(asset: &AssetId) -> Option>; + // Asset metadata + fn asset_metadata(asset: &AssetId) -> Option; /// Determines the relative location of the consensus system where the given asset is native from the point of view of the current system fn native_asset_location(asset: &AssetId) -> Option; diff --git a/pallets/asset-index/src/types.rs b/pallets/asset-index/src/types.rs index 59cb6695da..a8abb0a08d 100644 --- a/pallets/asset-index/src/types.rs +++ b/pallets/asset-index/src/types.rs @@ -33,25 +33,36 @@ pub enum AssetAvailability { Saft, } +/// Metadata for an asset #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -/// A representation of some number of assets that are managed by the index -pub struct IndexAssetData { +pub struct AssetMetadata { pub name: Vec, pub symbol: Vec, + pub decimals: u8, +} + +impl Default for AssetMetadata { + fn default() -> Self { + AssetMetadata { + decimals: 8, + name: Vec::new(), + symbol: Vec::new(), + } + } +} + +#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] +/// A representation of some number of assets that are managed by the index +pub struct IndexAssetData { + pub metadata: AssetMetadata, pub units: Balance, pub availability: AssetAvailability, } impl IndexAssetData { - pub fn new( - name: Vec, - symbol: Vec, - units: Balance, - availability: AssetAvailability, - ) -> Self { + pub fn new(metadata: AssetMetadata, units: Balance, availability: AssetAvailability) -> Self { Self { - name, - symbol, + metadata, units, availability, } diff --git a/pallets/saft-registry/src/lib.rs b/pallets/saft-registry/src/lib.rs index ba007570bd..cd1c07803c 100644 --- a/pallets/saft-registry/src/lib.rs +++ b/pallets/saft-registry/src/lib.rs @@ -22,7 +22,10 @@ pub mod pallet { sp_runtime::traits::AtLeast32BitUnsigned, sp_std::prelude::*, }; use frame_system::pallet_prelude::*; - use pallet_asset_index::traits::{AssetAvailability, AssetRecorder}; + use pallet_asset_index::{ + traits::{AssetAvailability, AssetRecorder}, + types::AssetMetadata, + }; #[pallet::config] pub trait Config: frame_system::Config { @@ -91,8 +94,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::add_saft())] pub fn add_saft( origin: OriginFor, - name: Vec, - symbol: Vec, + metadata: AssetMetadata, asset_id: T::AssetId, nav: T::Balance, units: T::Balance, @@ -101,8 +103,7 @@ pub mod pallet { ActiveSAFTs::::append(asset_id.clone(), SAFTRecord::new(nav, units.clone())); ::AssetRecorder::add_asset( - name, - symbol, + metadata, &asset_id, &units, &AssetAvailability::Saft, diff --git a/pallets/saft-registry/src/mock.rs b/pallets/saft-registry/src/mock.rs index 34def6b3a7..3f588bab39 100644 --- a/pallets/saft-registry/src/mock.rs +++ b/pallets/saft-registry/src/mock.rs @@ -7,7 +7,10 @@ use crate as pallet_saft_registry; use frame_support::{ord_parameter_types, parameter_types}; use frame_system as system; -use pallet_asset_index::traits::{AssetAvailability, AssetRecorder}; +use pallet_asset_index::{ + traits::{AssetAvailability, AssetRecorder}, + types::AssetMetadata, +}; use sp_core::H256; use sp_runtime::{ @@ -74,7 +77,12 @@ ord_parameter_types! { pub struct MockAssetRecorder(); impl AssetRecorder for MockAssetRecorder { - fn add_asset(_: &AssetId, _: &Balance, _: &AssetAvailability) -> Result<(), DispatchError> { + fn add_asset( + _: AssetMetadata, + _: &AssetId, + _: &Balance, + _: &AssetAvailability, + ) -> Result<(), DispatchError> { Ok(()) } fn remove_asset(_: &AssetId) -> Result<(), DispatchError> { diff --git a/pallets/saft-registry/src/tests.rs b/pallets/saft-registry/src/tests.rs index ea4d1fc8fd..26ce23531b 100644 --- a/pallets/saft-registry/src/tests.rs +++ b/pallets/saft-registry/src/tests.rs @@ -14,7 +14,7 @@ const ASSET_A: u32 = 0; fn non_admin_cannot_call_any_extrinsics() { new_test_ext().execute_with(|| { assert_noop!( - SaftRegistry::add_saft(Origin::signed(ASHLEY), ASSET_A, 0, 0), + SaftRegistry::add_saft(Origin::signed(ASHLEY), Default::default(), ASSET_A, 0, 0), BadOrigin ); assert_noop!( @@ -34,6 +34,7 @@ fn admin_can_add_and_remove_saft() { // add assert_ok!(SaftRegistry::add_saft( Origin::signed(ADMIN_ACCOUNT_ID), + Default::default(), ASSET_A, 100, 20 @@ -58,6 +59,7 @@ fn admin_can_add_then_update_saft() { // add assert_ok!(SaftRegistry::add_saft( Origin::signed(ADMIN_ACCOUNT_ID), + Default::default(), ASSET_A, 100, 20 @@ -87,6 +89,7 @@ fn admin_cannot_update_or_remove_invalid_index() { // add assert_ok!(SaftRegistry::add_saft( Origin::signed(ADMIN_ACCOUNT_ID), + Default::default(), ASSET_A, 100, 20 From dc64a999fad6bd70a0922b2316381e4c3b9466cb Mon Sep 17 00:00:00 2001 From: clearloop Date: Tue, 15 Jun 2021 22:08:35 +0800 Subject: [PATCH 05/11] chore(saft-registry): fix benchmarking --- pallets/saft-registry/src/benchmarking.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pallets/saft-registry/src/benchmarking.rs b/pallets/saft-registry/src/benchmarking.rs index 78fe2de8ea..8e55f7a00c 100644 --- a/pallets/saft-registry/src/benchmarking.rs +++ b/pallets/saft-registry/src/benchmarking.rs @@ -9,8 +9,7 @@ benchmarks! { add_saft { }: _( >::Root, - b"asset".to_vec(), - b"asset".to_vec(), + Default::default(), 0_u32.into(), 100_u32.into(), 20_u32.into() @@ -40,8 +39,7 @@ benchmarks! { report_nav { assert_ok!(>::add_saft( >::Root.into(), - b"asset".to_vec(), - b"".to_vec(), + Default::default(), 0.into(), 100_u32.into(), 20_u32.into(), From 9f7fc8e84e7fc3a195321230e60a0f0e801cfe39 Mon Sep 17 00:00:00 2001 From: clearloop Date: Wed, 16 Jun 2021 18:52:49 +0800 Subject: [PATCH 06/11] feat(asset-index): add storage AssetMetadata --- pallets/asset-index/src/benchmarking.rs | 2 -- pallets/asset-index/src/lib.rs | 28 +++++++++++++---------- pallets/asset-index/src/mock.rs | 8 ++----- pallets/asset-index/src/tests.rs | 16 ------------- pallets/asset-index/src/traits.rs | 11 ++------- pallets/asset-index/src/types.rs | 22 ++++-------------- pallets/saft-registry/src/benchmarking.rs | 2 -- pallets/saft-registry/src/lib.rs | 13 ++--------- pallets/saft-registry/src/mock.rs | 12 ++-------- pallets/saft-registry/src/tests.rs | 5 +--- runtime/src/lib.rs | 2 ++ 11 files changed, 32 insertions(+), 89 deletions(-) diff --git a/pallets/asset-index/src/benchmarking.rs b/pallets/asset-index/src/benchmarking.rs index 4d8383bd44..0bd33fd8a9 100644 --- a/pallets/asset-index/src/benchmarking.rs +++ b/pallets/asset-index/src/benchmarking.rs @@ -15,7 +15,6 @@ benchmarks! { T::IndexToken::deposit_creating(&caller, million); }: _( RawOrigin::Signed(caller.clone()), - Default::default(), asset_id, million, AssetAvailability::Liquid(MultiLocation::Null), @@ -24,7 +23,6 @@ benchmarks! { assert_eq!( >::get(asset_id), Some(IndexAssetData::new( - Default::default(), million, AssetAvailability::Liquid(MultiLocation::Null) )) diff --git a/pallets/asset-index/src/lib.rs b/pallets/asset-index/src/lib.rs index a6621b5989..252ff4133c 100644 --- a/pallets/asset-index/src/lib.rs +++ b/pallets/asset-index/src/lib.rs @@ -108,6 +108,9 @@ pub mod pallet { type TreasuryPalletId: Get; type Event: From> + IsType<::Event>; + /// The maximum length of a name or symbol stored on-chain. + type StringLimit: Get; + /// The weight for this pallet's extrinsics. type WeightInfo: WeightInfo; } @@ -131,6 +134,18 @@ pub mod pallet { OptionQuery, >; + #[pallet::storage] + /// Metadata of an asset ( for reversed usage now ). + pub(super) type Metadata = StorageMap< + _, + Blake2_128Concat, + T::AssetId, + AssetMetadata>, + ValueQuery, + GetDefault, + ConstU32<300_000>, + >; + #[pallet::event] #[pallet::metadata(T::AssetId = "AccountId", AccountIdFor < T > = "AccountId", T::Balance = "Balance")] #[pallet::generate_deposit(pub (super) fn deposit_event)] @@ -184,7 +199,6 @@ pub mod pallet { /// Creates IndexAssetData if it doesn’t exist, otherwise adds to list of deposits pub fn add_asset( origin: OriginFor, - metadata: AssetMetadata, asset_id: T::AssetId, units: T::Balance, availability: AssetAvailability, @@ -200,7 +214,6 @@ pub mod pallet { )?; >::add_asset( - metadata, &asset_id, &units, &availability, @@ -528,18 +541,13 @@ pub mod pallet { /// Creates IndexAssetData if entry with given assetID does not exist. /// Otherwise adds the units to the existing holding fn add_asset( - metadata: AssetMetadata, asset_id: &T::AssetId, units: &T::Balance, availability: &AssetAvailability, ) -> DispatchResult { Holdings::::try_mutate(asset_id, |value| -> Result<_, Error> { let index_asset_data = value.get_or_insert_with(|| { - IndexAssetData::::new( - metadata, - T::Balance::zero(), - availability.clone(), - ) + IndexAssetData::::new(T::Balance::zero(), availability.clone()) }); index_asset_data.units = index_asset_data .units @@ -556,10 +564,6 @@ pub mod pallet { } impl MultiAssetRegistry for Pallet { - fn asset_metadata(asset: &T::AssetId) -> Option { - Holdings::::get(asset).and_then(|holding| Some(holding.metadata)) - } - fn native_asset_location(asset: &T::AssetId) -> Option { Holdings::::get(asset).and_then(|holding| { if let AssetAvailability::Liquid(location) = holding.availability { diff --git a/pallets/asset-index/src/mock.rs b/pallets/asset-index/src/mock.rs index 4e1d0fecd7..0bf45bcddd 100644 --- a/pallets/asset-index/src/mock.rs +++ b/pallets/asset-index/src/mock.rs @@ -82,12 +82,7 @@ ord_parameter_types! { pub struct MockAssetRecorder; impl AssetRecorder for MockAssetRecorder { - fn add_asset( - _: pallet_asset_index::types::AssetMetadata, - _: &AssetId, - _: &Balance, - _: &AssetAvailability, - ) -> Result<(), DispatchError> { + fn add_asset(_: &AssetId, _: &Balance, _: &AssetAvailability) -> Result<(), DispatchError> { Ok(()) } fn remove_asset(_: &AssetId) -> Result<(), DispatchError> { @@ -144,6 +139,7 @@ impl pallet_asset_index::Config for Test { type MultiAssetDepository = AssetDepository; type PriceFeed = MockPriceFeed; type TreasuryPalletId = TreasuryPalletId; + type StringLimit = (); type WithdrawalFee = (); type WeightInfo = (); } diff --git a/pallets/asset-index/src/tests.rs b/pallets/asset-index/src/tests.rs index dd9327ae24..6331366bf8 100644 --- a/pallets/asset-index/src/tests.rs +++ b/pallets/asset-index/src/tests.rs @@ -22,7 +22,6 @@ fn non_admin_cannot_call_get_asset() { assert_noop!( AssetIndex::add_asset( Origin::signed(ASHLEY), - Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -40,7 +39,6 @@ fn admin_can_add_asset() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -49,7 +47,6 @@ fn admin_can_add_asset() { assert_eq!( pallet::Holdings::::get(ASSET_A_ID), Some(IndexAssetData::new( - Default::default(), 100, AssetAvailability::Liquid(MultiLocation::Null) )) @@ -67,7 +64,6 @@ fn admin_can_add_asset_twice_and_units_accumulate() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -75,7 +71,6 @@ fn admin_can_add_asset_twice_and_units_accumulate() { )); assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -84,7 +79,6 @@ fn admin_can_add_asset_twice_and_units_accumulate() { assert_eq!( pallet::Holdings::::get(ASSET_A_ID), Some(IndexAssetData::new( - Default::default(), 200, AssetAvailability::Liquid(MultiLocation::Null) )) @@ -103,7 +97,6 @@ fn deposit_only_works_for_added_liquid_assets() { ); assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_A_ID, 100, AssetAvailability::Saft, @@ -122,7 +115,6 @@ fn deposit_works_with_user_balance() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -158,7 +150,6 @@ fn deposit_fails_for_unknown_assets() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -177,7 +168,6 @@ fn deposit_ok_for_when_price_feed_unavailable() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), UNKNOWN_ASSET_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -198,7 +188,6 @@ fn deposit_fails_on_overflowing() { new_test_ext(initial_balances).execute_with(|| { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_A_ID, 100, AssetAvailability::Liquid(MultiLocation::Null), @@ -223,7 +212,6 @@ fn can_calculates_nav() { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_A_ID, a_units, AssetAvailability::Liquid(MultiLocation::Null), @@ -232,7 +220,6 @@ fn can_calculates_nav() { assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_B_ID, b_units, AssetAvailability::Saft, @@ -285,7 +272,6 @@ fn can_withdraw() { // create liquid assets assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_A_ID, a_units, AssetAvailability::Liquid(MultiLocation::Null), @@ -293,7 +279,6 @@ fn can_withdraw() { )); assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_B_ID, b_units, AssetAvailability::Liquid(MultiLocation::Null), @@ -367,7 +352,6 @@ fn can_withdraw() { // all SAFT holdings are ignored during withdrawal and don't have any effect on the payout assert_ok!(AssetIndex::add_asset( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), 99, 1_000, AssetAvailability::Saft, diff --git a/pallets/asset-index/src/traits.rs b/pallets/asset-index/src/traits.rs index 4687febbf1..af90736b40 100644 --- a/pallets/asset-index/src/traits.rs +++ b/pallets/asset-index/src/traits.rs @@ -11,21 +11,14 @@ pub trait AssetRecorder { /// The provided NAV parameter is the Net Asset Value of the total units provided /// given in units of some stable asset. In the case of an AssetId that already exists the /// newly provided NAV will be used to re-value the existing units and compute a total NAV - fn add_asset( - metadata: AssetMetadata, - id: &AssetId, - units: &Balance, - availability: &AssetAvailability, - ) -> DispatchResult; + fn add_asset(id: &AssetId, units: &Balance, availability: &AssetAvailability) + -> DispatchResult; fn remove_asset(id: &AssetId) -> DispatchResult; } /// Type that provides the mapping between `AssetId` and `MultiLocation`. pub trait MultiAssetRegistry { - // Asset metadata - fn asset_metadata(asset: &AssetId) -> Option; - /// Determines the relative location of the consensus system where the given asset is native from the point of view of the current system fn native_asset_location(asset: &AssetId) -> Option; diff --git a/pallets/asset-index/src/types.rs b/pallets/asset-index/src/types.rs index a8abb0a08d..485da04b0e 100644 --- a/pallets/asset-index/src/types.rs +++ b/pallets/asset-index/src/types.rs @@ -34,35 +34,23 @@ pub enum AssetAvailability { } /// Metadata for an asset -#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] -pub struct AssetMetadata { - pub name: Vec, - pub symbol: Vec, +#[derive(PartialEq, Eq, Clone, Default, Encode, Decode, RuntimeDebug)] +pub struct AssetMetadata { + pub name: BoundedString, + pub symbol: BoundedString, pub decimals: u8, } -impl Default for AssetMetadata { - fn default() -> Self { - AssetMetadata { - decimals: 8, - name: Vec::new(), - symbol: Vec::new(), - } - } -} - #[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug)] /// A representation of some number of assets that are managed by the index pub struct IndexAssetData { - pub metadata: AssetMetadata, pub units: Balance, pub availability: AssetAvailability, } impl IndexAssetData { - pub fn new(metadata: AssetMetadata, units: Balance, availability: AssetAvailability) -> Self { + pub fn new(units: Balance, availability: AssetAvailability) -> Self { Self { - metadata, units, availability, } diff --git a/pallets/saft-registry/src/benchmarking.rs b/pallets/saft-registry/src/benchmarking.rs index 8e55f7a00c..af200ff412 100644 --- a/pallets/saft-registry/src/benchmarking.rs +++ b/pallets/saft-registry/src/benchmarking.rs @@ -9,7 +9,6 @@ benchmarks! { add_saft { }: _( >::Root, - Default::default(), 0_u32.into(), 100_u32.into(), 20_u32.into() @@ -39,7 +38,6 @@ benchmarks! { report_nav { assert_ok!(>::add_saft( >::Root.into(), - Default::default(), 0.into(), 100_u32.into(), 20_u32.into(), diff --git a/pallets/saft-registry/src/lib.rs b/pallets/saft-registry/src/lib.rs index cd1c07803c..cf72257167 100644 --- a/pallets/saft-registry/src/lib.rs +++ b/pallets/saft-registry/src/lib.rs @@ -22,10 +22,7 @@ pub mod pallet { sp_runtime::traits::AtLeast32BitUnsigned, sp_std::prelude::*, }; use frame_system::pallet_prelude::*; - use pallet_asset_index::{ - traits::{AssetAvailability, AssetRecorder}, - types::AssetMetadata, - }; + use pallet_asset_index::traits::{AssetAvailability, AssetRecorder}; #[pallet::config] pub trait Config: frame_system::Config { @@ -94,7 +91,6 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::add_saft())] pub fn add_saft( origin: OriginFor, - metadata: AssetMetadata, asset_id: T::AssetId, nav: T::Balance, units: T::Balance, @@ -102,12 +98,7 @@ pub mod pallet { T::AdminOrigin::ensure_origin(origin)?; ActiveSAFTs::::append(asset_id.clone(), SAFTRecord::new(nav, units.clone())); - ::AssetRecorder::add_asset( - metadata, - &asset_id, - &units, - &AssetAvailability::Saft, - )?; + ::AssetRecorder::add_asset(&asset_id, &units, &AssetAvailability::Saft)?; Self::deposit_event(Event::::SAFTAdded(asset_id, 0)); Ok(().into()) diff --git a/pallets/saft-registry/src/mock.rs b/pallets/saft-registry/src/mock.rs index 3f588bab39..34def6b3a7 100644 --- a/pallets/saft-registry/src/mock.rs +++ b/pallets/saft-registry/src/mock.rs @@ -7,10 +7,7 @@ use crate as pallet_saft_registry; use frame_support::{ord_parameter_types, parameter_types}; use frame_system as system; -use pallet_asset_index::{ - traits::{AssetAvailability, AssetRecorder}, - types::AssetMetadata, -}; +use pallet_asset_index::traits::{AssetAvailability, AssetRecorder}; use sp_core::H256; use sp_runtime::{ @@ -77,12 +74,7 @@ ord_parameter_types! { pub struct MockAssetRecorder(); impl AssetRecorder for MockAssetRecorder { - fn add_asset( - _: AssetMetadata, - _: &AssetId, - _: &Balance, - _: &AssetAvailability, - ) -> Result<(), DispatchError> { + fn add_asset(_: &AssetId, _: &Balance, _: &AssetAvailability) -> Result<(), DispatchError> { Ok(()) } fn remove_asset(_: &AssetId) -> Result<(), DispatchError> { diff --git a/pallets/saft-registry/src/tests.rs b/pallets/saft-registry/src/tests.rs index 26ce23531b..ea4d1fc8fd 100644 --- a/pallets/saft-registry/src/tests.rs +++ b/pallets/saft-registry/src/tests.rs @@ -14,7 +14,7 @@ const ASSET_A: u32 = 0; fn non_admin_cannot_call_any_extrinsics() { new_test_ext().execute_with(|| { assert_noop!( - SaftRegistry::add_saft(Origin::signed(ASHLEY), Default::default(), ASSET_A, 0, 0), + SaftRegistry::add_saft(Origin::signed(ASHLEY), ASSET_A, 0, 0), BadOrigin ); assert_noop!( @@ -34,7 +34,6 @@ fn admin_can_add_and_remove_saft() { // add assert_ok!(SaftRegistry::add_saft( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_A, 100, 20 @@ -59,7 +58,6 @@ fn admin_can_add_then_update_saft() { // add assert_ok!(SaftRegistry::add_saft( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_A, 100, 20 @@ -89,7 +87,6 @@ fn admin_cannot_update_or_remove_invalid_index() { // add assert_ok!(SaftRegistry::add_saft( Origin::signed(ADMIN_ACCOUNT_ID), - Default::default(), ASSET_A, 100, 20 diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 7762244ffa..c1a5f748bc 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -567,6 +567,7 @@ parameter_types! { pub MinimumRedemption: u32 = 0; pub WithdrawalPeriod: ::BlockNumber = 10; pub DOTContributionLimit: Balance = 999; + pub PalletIndexStringLimit: u32 = 8; } impl pallet_asset_index::Config for Runtime { @@ -585,6 +586,7 @@ impl pallet_asset_index::Config for Runtime { type PriceFeed = PriceFeed; type TreasuryPalletId = TreasuryPalletId; type WithdrawalFee = (); + type StringLimit = PalletIndexStringLimit; type WeightInfo = weights::pallet_asset_index::WeightInfo; } From a7883083553e696ffa903aa0ef6c28d2a20be4fe Mon Sep 17 00:00:00 2001 From: clearloop Date: Wed, 16 Jun 2021 19:44:31 +0800 Subject: [PATCH 07/11] feat(asset-index): add call set_metadata --- pallets/asset-index/src/lib.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pallets/asset-index/src/lib.rs b/pallets/asset-index/src/lib.rs index 252ff4133c..3d063497c5 100644 --- a/pallets/asset-index/src/lib.rs +++ b/pallets/asset-index/src/lib.rs @@ -223,6 +223,17 @@ pub mod pallet { Ok(().into()) } + #[pallet::weight(1000)] + pub fn set_metadata( + origin: OriginFor, + asset_id: T::AssetId, + metadata: AssetMetadata>, + ) -> DispatchResultWithPostInfo { + T::AdminOrigin::ensure_origin(origin.clone())?; + >::insert(&asset_id, metadata); + Ok(().into()) + } + /// Initiate a transfer from the user's sovereign account into the index. /// /// This will withdraw the given amount from the user's sovereign account and mints PINT From cb6da08164077810542adab868b73a3d051bcf01 Mon Sep 17 00:00:00 2001 From: clearloop Date: Wed, 16 Jun 2021 22:37:43 +0800 Subject: [PATCH 08/11] feat(asset-index): add benchmark for asset-index --- pallets/asset-index/src/benchmarking.rs | 18 ++++++++ pallets/asset-index/src/lib.rs | 59 +++++++++++++++++++++--- pallets/asset-index/src/mock.rs | 3 +- pallets/asset-index/src/tests.rs | 60 +++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 8 deletions(-) diff --git a/pallets/asset-index/src/benchmarking.rs b/pallets/asset-index/src/benchmarking.rs index 0bd33fd8a9..2e79335567 100644 --- a/pallets/asset-index/src/benchmarking.rs +++ b/pallets/asset-index/src/benchmarking.rs @@ -28,4 +28,22 @@ benchmarks! { )) ); } + + set_metadata { + let asset_id = 0_u32.into(); + let name = b"pint".to_vec(); + let symbol = b"pint".to_vec(); + let decimals = 8_u8; + }: _( + RawOrigin::Root, + asset_id, + name.clone(), + symbol.clone(), + decimals + ) verify { + let metadata = >::get(asset_id); + assert_eq!(metadata.name.as_slice(), name.as_slice()); + assert_eq!(metadata.symbol.as_slice(), symbol.as_slice()); + assert_eq!(metadata.decimals, decimals); + } } diff --git a/pallets/asset-index/src/lib.rs b/pallets/asset-index/src/lib.rs index 3d063497c5..f31d409e14 100644 --- a/pallets/asset-index/src/lib.rs +++ b/pallets/asset-index/src/lib.rs @@ -168,12 +168,18 @@ pub mod pallet { AccountIdFor, Vec>, ), + /// New metadata has been set for an asset. \[asset_id, name, symbol, decimals\] + MetadataSet(T::AssetId, Vec, Vec, u8), } #[pallet::error] pub enum Error { /// Thrown if adding units to an asset holding causes its numerical type to overflow AssetUnitsOverflow, + /// The given asset ID is unknown. + UnknownAsset, + /// Invalid metadata given. + BadMetadata, /// Thrown if no index could be found for an asset identifier. UnsupportedAsset, /// Thrown if calculating the volume of units of an asset with it's price overflows. @@ -223,15 +229,49 @@ pub mod pallet { Ok(().into()) } - #[pallet::weight(1000)] + /// Force the metadata for an asset to some value. + /// + /// Origin must be ForceOrigin. + /// + /// Any deposit is left alone. + /// + /// - `id`: The identifier of the asset to update. + /// - `name`: The user friendly name of this asset. Limited in length by `StringLimit`. + /// - `symbol`: The exchange symbol for this asset. Limited in length by `StringLimit`. + /// - `decimals`: The number of decimals this asset uses to represent one unit. + /// + /// Emits `MetadataSet`. + /// + /// Weight: `O(N + S)` where N and S are the length of the name and symbol respectively. + #[pallet::weight(T::WeightInfo::add_asset())] pub fn set_metadata( origin: OriginFor, - asset_id: T::AssetId, - metadata: AssetMetadata>, - ) -> DispatchResultWithPostInfo { - T::AdminOrigin::ensure_origin(origin.clone())?; - >::insert(&asset_id, metadata); - Ok(().into()) + #[pallet::compact] id: T::AssetId, + name: Vec, + symbol: Vec, + decimals: u8, + ) -> DispatchResult { + T::AdminOrigin::ensure_origin(origin)?; + + let bounded_name: BoundedVec = name + .clone() + .try_into() + .map_err(|_| >::BadMetadata)?; + let bounded_symbol: BoundedVec = symbol + .clone() + .try_into() + .map_err(|_| >::BadMetadata)?; + + >::try_mutate_exists(id, |metadata| { + *metadata = Some(AssetMetadata { + name: bounded_name, + symbol: bounded_symbol, + decimals, + }); + + Self::deposit_event(Event::MetadataSet(id, name, symbol, decimals)); + Ok(()) + }) } /// Initiate a transfer from the user's sovereign account into the index. @@ -595,6 +635,7 @@ pub mod pallet { /// Trait for the asset-index pallet extrinsic weights. pub trait WeightInfo { fn add_asset() -> Weight; + // fn set_metadata() -> Weight; } /// For backwards compatibility and tests @@ -602,5 +643,9 @@ pub mod pallet { fn add_asset() -> Weight { Default::default() } + + // fn set_metadata() -> Weight { + // Default::default() + // } } } diff --git a/pallets/asset-index/src/mock.rs b/pallets/asset-index/src/mock.rs index 0bf45bcddd..e7924ff59f 100644 --- a/pallets/asset-index/src/mock.rs +++ b/pallets/asset-index/src/mock.rs @@ -123,6 +123,7 @@ parameter_types! { pub WithdrawalPeriod: ::BlockNumber = 10; pub DOTContributionLimit: Balance = 999; pub TreasuryPalletId: PalletId = PalletId(*b"12345678"); + pub StringLimit: u32 = 4; } impl pallet_asset_index::Config for Test { @@ -139,7 +140,7 @@ impl pallet_asset_index::Config for Test { type MultiAssetDepository = AssetDepository; type PriceFeed = MockPriceFeed; type TreasuryPalletId = TreasuryPalletId; - type StringLimit = (); + type StringLimit = StringLimit; type WithdrawalFee = (); type WeightInfo = (); } diff --git a/pallets/asset-index/src/tests.rs b/pallets/asset-index/src/tests.rs index 6331366bf8..f4c07ec2cc 100644 --- a/pallets/asset-index/src/tests.rs +++ b/pallets/asset-index/src/tests.rs @@ -87,6 +87,66 @@ fn admin_can_add_asset_twice_and_units_accumulate() { }); } +#[test] +fn non_admin_cannot_set_metadata() { + new_test_ext(vec![]).execute_with(|| { + assert_noop!( + AssetIndex::set_metadata( + Origin::signed(ASHLEY), + ASSET_A_ID, + b"dot".to_vec(), + b"dot".to_vec(), + 8, + ), + BadOrigin + ); + }); +} + +#[test] +fn admin_can_set_metadata() { + new_test_ext(vec![]).execute_with(|| { + assert_ok!(AssetIndex::set_metadata( + Origin::signed(ADMIN_ACCOUNT_ID), + ASSET_A_ID, + b"dot".to_vec(), + b"dot".to_vec(), + 8, + )); + }); +} + +#[test] +fn admin_can_update_metadata() { + new_test_ext(vec![]).execute_with(|| { + assert_ok!(AssetIndex::set_metadata( + Origin::signed(ADMIN_ACCOUNT_ID), + ASSET_A_ID, + b"dot".to_vec(), + b"dot".to_vec(), + 8, + )); + + assert_eq!( + >::get(ASSET_A_ID).name, + b"dot".to_vec() + ); + + assert_ok!(AssetIndex::set_metadata( + Origin::signed(ADMIN_ACCOUNT_ID), + ASSET_A_ID, + b"pint".to_vec(), + b"pint".to_vec(), + 8, + )); + + assert_eq!( + >::get(ASSET_A_ID).name, + b"pint".to_vec() + ); + }); +} + #[test] fn deposit_only_works_for_added_liquid_assets() { let initial_balances: Vec<(AccountId, Balance)> = vec![(ADMIN_ACCOUNT_ID, 0)]; From 923c1489b97978dba5ec8e6be2c533a894f7d25e Mon Sep 17 00:00:00 2001 From: clearloop Date: Wed, 16 Jun 2021 23:11:01 +0800 Subject: [PATCH 09/11] feat(asset-index): add benchmark for set_metadata --- pallets/asset-index/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pallets/asset-index/src/lib.rs b/pallets/asset-index/src/lib.rs index f31d409e14..00c43ab37e 100644 --- a/pallets/asset-index/src/lib.rs +++ b/pallets/asset-index/src/lib.rs @@ -635,7 +635,7 @@ pub mod pallet { /// Trait for the asset-index pallet extrinsic weights. pub trait WeightInfo { fn add_asset() -> Weight; - // fn set_metadata() -> Weight; + fn set_metadata() -> Weight; } /// For backwards compatibility and tests @@ -644,8 +644,8 @@ pub mod pallet { Default::default() } - // fn set_metadata() -> Weight { - // Default::default() - // } + fn set_metadata() -> Weight { + Default::default() + } } } From 9fa71ce6a192ac7b7ef78a9602c65f359689b950 Mon Sep 17 00:00:00 2001 From: clearloop Date: Wed, 16 Jun 2021 23:55:40 +0800 Subject: [PATCH 10/11] Update runtime/src/lib.rs Co-authored-by: Matthias Seitz --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 3c58eb4275..3e9490f79c 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -617,7 +617,7 @@ parameter_types! { pub MinimumRedemption: u32 = 0; pub WithdrawalPeriod: ::BlockNumber = 10; pub DOTContributionLimit: Balance = 999; - pub PalletIndexStringLimit: u32 = 8; + pub PalletIndexStringLimit: u32 = 50; } impl pallet_asset_index::Config for Runtime { From 68c91a3ec4d83faf41351232889354f1b54bd356 Mon Sep 17 00:00:00 2001 From: clearloop Date: Thu, 17 Jun 2021 00:02:47 +0800 Subject: [PATCH 11/11] chore(runtime): make clippy happy --- runtime/src/weights/pallet_asset_index.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/runtime/src/weights/pallet_asset_index.rs b/runtime/src/weights/pallet_asset_index.rs index eb49048846..cb2b1c78f2 100644 --- a/runtime/src/weights/pallet_asset_index.rs +++ b/runtime/src/weights/pallet_asset_index.rs @@ -1,3 +1,5 @@ +// Copyright 2021 ChainSafe Systems +// SPDX-License-Identifier: LGPL-3.0-only //! Autogenerated weights for pallet_asset_index //! @@ -22,7 +24,6 @@ // --chain // pint-local - #![allow(unused_parens)] #![allow(unused_imports)] @@ -32,14 +33,14 @@ use sp_std::marker::PhantomData; /// Weight functions for pallet_asset_index. pub struct WeightInfo(PhantomData); impl pallet_asset_index::WeightInfo for WeightInfo { - fn add_asset() -> Weight { - (38_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) - } - fn set_metadata() -> Weight { - (18_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) - } + fn add_asset() -> Weight { + (38_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + fn set_metadata() -> Weight { + (18_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } }