diff --git a/frame/assets-registry/src/lib.rs b/frame/assets-registry/src/lib.rs index a1c7e5d60c5..7c85bfee1d5 100644 --- a/frame/assets-registry/src/lib.rs +++ b/frame/assets-registry/src/lib.rs @@ -73,6 +73,11 @@ pub mod pallet { ForeignAdminApproved, } + #[derive(Debug, Clone, Copy, PartialEq, Eq, Encode, Decode, TypeInfo)] + pub struct ForeignMetadata { + pub decimals: u8, + } + #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(_); @@ -114,6 +119,12 @@ pub mod pallet { OptionQuery, >; + #[pallet::storage] + #[pallet::getter(fn foreign_asset_metadata)] + /// Mapping local asset to foreign asset metadata. + pub type ForeignAssetMetadata = + StorageMap<_, Blake2_128Concat, T::LocalAssetId, ForeignMetadata, OptionQuery>; + #[pallet::type_value] pub fn LocalAdminOnEmpty() -> T::AccountId { T::AccountId::default() @@ -170,6 +181,7 @@ pub mod pallet { local_asset_id: T::LocalAssetId, foreign_asset_id: T::ForeignAssetId, }, + AssetMetadataUpdated(T::LocalAssetId), } #[pallet::error] @@ -177,6 +189,7 @@ pub mod pallet { OnlyAllowedForAdmins, LocalAssetIdAlreadyUsed, ForeignAssetIdAlreadyUsed, + LocalAssetIdNotFound, } #[pallet::call] @@ -226,6 +239,24 @@ pub mod pallet { }); Ok(().into()) } + + #[pallet::weight(10_000)] + pub fn set_metadata( + origin: OriginFor, + local_asset_id: T::LocalAssetId, + metadata: ForeignMetadata, + ) -> DispatchResultWithPostInfo { + let _ = ensure_signed(origin.clone())?; + Self::ensure_admins_only(origin)?; + ensure!( + >::contains_key(local_asset_id), + Error::::LocalAssetIdNotFound + ); + + >::insert(local_asset_id, metadata); + Self::deposit_event(Event::AssetMetadataUpdated(local_asset_id)); + Ok(().into()) + } } impl RemoteAssetRegistry for Pallet { diff --git a/frame/assets-registry/src/tests.rs b/frame/assets-registry/src/tests.rs index 79e589d47e3..c1026d1eebd 100644 --- a/frame/assets-registry/src/tests.rs +++ b/frame/assets-registry/src/tests.rs @@ -98,3 +98,37 @@ fn approve_assets_mapping_candidate_tests() { ); }) } + +#[test] +fn set_metadata_tests() { + new_test_ext().execute_with(|| { + let (local_asset_id, foreign_asset_id) = (0, 100); + assert_ok!(AssetsRegistry::set_local_admin(Origin::signed(ROOT), ALICE)); + assert_ok!(AssetsRegistry::set_foreign_admin(Origin::signed(ROOT), BOB)); + + assert_noop!( + AssetsRegistry::set_metadata( + Origin::signed(ALICE), + local_asset_id, + ForeignMetadata { decimals: 12 } + ), + Error::::LocalAssetIdNotFound + ); + + assert_ok!(AssetsRegistry::approve_assets_mapping_candidate( + Origin::signed(ALICE), + local_asset_id, + foreign_asset_id + )); + assert_ok!(AssetsRegistry::approve_assets_mapping_candidate( + Origin::signed(BOB), + local_asset_id, + foreign_asset_id + )); + assert_ok!(AssetsRegistry::set_metadata( + Origin::signed(ALICE), + local_asset_id, + ForeignMetadata { decimals: 12 } + )); + }) +}