diff --git a/pallets/foreign-assets/src/benchmarking.rs b/pallets/foreign-assets/src/benchmarking.rs index c6ca9ece7f..a88035ae2b 100644 --- a/pallets/foreign-assets/src/benchmarking.rs +++ b/pallets/foreign-assets/src/benchmarking.rs @@ -48,4 +48,30 @@ mod benchmarks { Ok(()) } + + #[benchmark] + fn force_reset_foreign_asset_location() -> Result<(), BenchmarkError> { + let old_asset_id: AssetId = (Parachain(1000), PalletInstance(42), GeneralIndex(1)).into(); + let new_asset_id: AssetId = (Parachain(2000), PalletInstance(42), GeneralIndex(1)).into(); + let name = create_u16_data::(); + let token_prefix = create_data::(); + let mode = ForeignCollectionMode::NFT; + + >::force_register_foreign_asset( + RawOrigin::Root.into(), + Box::new(old_asset_id.clone().into()), + name, + token_prefix, + mode, + )?; + + #[extrinsic_call] + _( + RawOrigin::Root, + Box::new(old_asset_id.into()), + Box::new(new_asset_id.into()), + ); + + Ok(()) + } } diff --git a/pallets/foreign-assets/src/lib.rs b/pallets/foreign-assets/src/lib.rs index 49c89a93d2..17519fcbf7 100644 --- a/pallets/foreign-assets/src/lib.rs +++ b/pallets/foreign-assets/src/lib.rs @@ -118,6 +118,9 @@ pub mod module { /// The given asset ID could not be converted into the current XCM version. BadForeignAssetId, + + /// The specified foreign asset is not found. + ForeignAssetNotFound, } #[pallet::event] @@ -131,6 +134,11 @@ pub mod module { /// The migration status. MigrationStatus(Box), + + ForeignAssetMoved { + old_asset_id: Box, + new_asset_id: Box, + } } /// The corresponding collections of foreign assets. @@ -233,6 +241,44 @@ pub mod module { Ok(()) } + + #[pallet::call_index(1)] + #[pallet::weight(::WeightInfo::force_reset_foreign_asset_location())] + pub fn force_reset_foreign_asset_location( + origin: OriginFor, + existing_versioned_asset_id: Box, + new_versioned_asset_id: Box, + ) -> DispatchResult { + T::ManagerOrigin::ensure_origin(origin.clone())?; + + let existing_asset_id: AssetId = existing_versioned_asset_id + .as_ref() + .clone() + .try_into() + .map_err(|()| Error::::BadForeignAssetId)?; + + let new_asset_id: AssetId = new_versioned_asset_id + .as_ref() + .clone() + .try_into() + .map_err(|()| Error::::BadForeignAssetId)?; + + let collection_id = >::get(&existing_asset_id) + .ok_or(Error::::ForeignAssetNotFound)?; + + >::remove(&existing_asset_id); + >::remove(collection_id); + + >::insert(&new_asset_id, collection_id); + >::insert(collection_id, new_asset_id); + + Self::deposit_event(Event::::ForeignAssetMoved { + old_asset_id: existing_versioned_asset_id, + new_asset_id: new_versioned_asset_id, + }); + + Ok(()) + } } #[pallet::genesis_config] diff --git a/pallets/foreign-assets/src/weights.rs b/pallets/foreign-assets/src/weights.rs index e1da49d0c0..50f4fce3be 100644 --- a/pallets/foreign-assets/src/weights.rs +++ b/pallets/foreign-assets/src/weights.rs @@ -34,6 +34,8 @@ use sp_std::marker::PhantomData; /// Weight functions needed for pallet_foreign_assets. pub trait WeightInfo { fn force_register_foreign_asset() -> Weight; + + fn force_reset_foreign_asset_location() -> Weight; } /// Weights for pallet_foreign_assets using the Substrate node and recommended hardware. @@ -64,6 +66,17 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(3_u64)) .saturating_add(T::DbWeight::get().writes(7_u64)) } + + // FIXME run the benchmarks + fn force_reset_foreign_asset_location() -> Weight { + // Proof Size summary in bytes: + // Measured: `146` + // Estimated: `4080` + // Minimum execution time: 26_678_000 picoseconds. + Weight::from_parts(27_177_000, 4080) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(7_u64)) + } } // For backwards compatibility and tests @@ -93,5 +106,16 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(3_u64)) .saturating_add(RocksDbWeight::get().writes(7_u64)) } + + // FIXME run the benchmarks + fn force_reset_foreign_asset_location() -> Weight { + // Proof Size summary in bytes: + // Measured: `146` + // Estimated: `4080` + // Minimum execution time: 26_678_000 picoseconds. + Weight::from_parts(27_177_000, 4080) + .saturating_add(RocksDbWeight::get().reads(3_u64)) + .saturating_add(RocksDbWeight::get().writes(7_u64)) + } }