difftreelog
Merge pull request #1068 from UniqueNetwork/chore/migrate-foreign-asset-to-v4
in: master
migrate foreign asset to v4 + fix foreign flags
3 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -7279,6 +7279,7 @@
name = "pallet-foreign-assets"
version = "0.1.0"
dependencies = [
+ "derivative",
"frame-benchmarking",
"frame-support",
"frame-system",
pallets/foreign-assets/Cargo.tomldiffbeforeafterboth--- a/pallets/foreign-assets/Cargo.toml
+++ b/pallets/foreign-assets/Cargo.toml
@@ -21,6 +21,7 @@
staging-xcm = { workspace = true }
staging-xcm-executor = { workspace = true }
up-data-structs = { workspace = true }
+derivative = { workspace = true }
[features]
default = ["std"]
pallets/foreign-assets/src/lib.rsdiffbeforeafterboth252526use core::ops::Deref;26use core::ops::Deref;272728use derivative::Derivative;28use frame_support::{dispatch::DispatchResult, pallet_prelude::*, traits::EnsureOrigin, PalletId};29use frame_support::{30 dispatch::DispatchResult, pallet_prelude::*, storage_alias, traits::EnsureOrigin, PalletId,31};29use frame_system::pallet_prelude::*;32use frame_system::pallet_prelude::*;30use pallet_common::{33use pallet_common::{38 AssetsInHolding,41 AssetsInHolding,39};42};40use up_data_structs::{43use up_data_structs::{41 budget::ZeroBudget, CollectionId, CollectionMode, CollectionName, CollectionTokenPrefix,44 budget::ZeroBudget, CollectionFlags, CollectionId, CollectionMode, CollectionName,42 CreateCollectionData, CreateFungibleData, CreateItemData, TokenId,45 CollectionTokenPrefix, CreateCollectionData, CreateFungibleData, CreateItemData, TokenId,43};46};444750pub use module::*;53pub use module::*;51pub use weights::WeightInfo;54pub use weights::WeightInfo;5556/// Status of storage migration from an old XCM version to a new one.57#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]58pub enum MigrationStatus {59 V3ToV4(MigrationStatusV3ToV4),60}6162/// Status of storage migration from XCMv3 to XCMv4.63#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]64pub enum MigrationStatusV3ToV4 {65 /// The migration is completed.66 Done,6768 /// An asset is skipped during the migration69 /// due to its inconsistent state.70 SkippedInconsistentAssetData(staging_xcm::v3::AssetId),7172 /// An asset instance is skipped during the migration73 /// due to its inconsistent state.74 SkippedInconsistentAssetInstanceData {75 asset_id: staging_xcm::v3::AssetId,76 asset_instance: staging_xcm::v3::AssetInstance,77 },7879 /// An asset is skipped during the migration80 /// because it couldn't be converted to the new XCM version.81 SkippedNotConvertibleAssetId(staging_xcm::v3::AssetId),8283 /// An asset instance is skipped during the migration84 /// because it couldn't be converted to the new XCM version.85 SkippedNotConvertibleAssetInstance {86 asset_id: staging_xcm::v3::AssetId,87 asset_instance: staging_xcm::v3::AssetInstance,88 },89}529053#[frame_support::pallet]91#[frame_support::pallet]54pub mod module {92pub mod module {93 use frame_support::traits::BuildGenesisConfig;55 use pallet_common::CollectionIssuer;94 use pallet_common::CollectionIssuer;56 use up_data_structs::CollectionDescription;95 use up_data_structs::CollectionDescription;579693 }132 }9413395 #[pallet::event]134 #[pallet::event]96 #[pallet::generate_deposit(fn deposit_event)]135 #[pallet::generate_deposit(pub(crate) fn deposit_event)]97 pub enum Event<T: Config> {136 pub enum Event<T: Config> {98 /// The foreign asset registered.137 /// The foreign asset registered.99 ForeignAssetRegistered {138 ForeignAssetRegistered {100 collection_id: CollectionId,139 collection_id: CollectionId,101 asset_id: Box<VersionedAssetId>,140 asset_id: Box<VersionedAssetId>,102 },141 },142143 /// The migration status.144 MigrationStatus(MigrationStatus),103 }145 }104146105 /// The corresponding collections of foreign assets.147 /// The corresponding collections of foreign assets.106 #[pallet::storage]148 #[pallet::storage]107 #[pallet::getter(fn foreign_asset_to_collection)]149 #[pallet::getter(fn foreign_asset_to_collection)]108 pub type ForeignAssetToCollection<T: Config> =150 pub type ForeignAssetToCollection<T: Config> =109 StorageMap<_, Twox64Concat, staging_xcm::v4::AssetId, CollectionId, OptionQuery>;151 StorageMap<_, Blake2_128Concat, staging_xcm::v4::AssetId, CollectionId, OptionQuery>;110152111 /// The corresponding foreign assets of collections.153 /// The corresponding foreign assets of collections.112 #[pallet::storage]154 #[pallet::storage]113 #[pallet::getter(fn collection_to_foreign_asset)]155 #[pallet::getter(fn collection_to_foreign_asset)]114 pub type CollectionToForeignAsset<T: Config> =156 pub type CollectionToForeignAsset<T: Config> =115 StorageMap<_, Twox64Concat, CollectionId, staging_xcm::v4::AssetId, OptionQuery>;157 StorageMap<_, Blake2_128Concat, CollectionId, staging_xcm::v4::AssetId, OptionQuery>;116158117 /// The correponding NFT token id of reserve NFTs159 /// The correponding NFT token id of reserve NFTs118 #[pallet::storage]160 #[pallet::storage]119 #[pallet::getter(fn foreign_reserve_asset_instance_to_token_id)]161 #[pallet::getter(fn foreign_reserve_asset_instance_to_token_id)]120 pub type ForeignReserveAssetInstanceToTokenId<T: Config> = StorageDoubleMap<162 pub type ForeignReserveAssetInstanceToTokenId<T: Config> = StorageDoubleMap<121 Hasher1 = Twox64Concat,163 Hasher1 = Blake2_128Concat,122 Key1 = CollectionId,164 Key1 = CollectionId,123 Hasher2 = Blake2_128Concat,165 Hasher2 = Blake2_128Concat,124 // Key2 = staging_xcm::v3::AssetInstance,125 Key2 = staging_xcm::v4::AssetInstance,166 Key2 = staging_xcm::v4::AssetInstance,126 Value = TokenId,167 Value = TokenId,127 QueryKind = OptionQuery,168 QueryKind = OptionQuery,131 #[pallet::storage]172 #[pallet::storage]132 #[pallet::getter(fn token_id_to_foreign_reserve_asset_instance)]173 #[pallet::getter(fn token_id_to_foreign_reserve_asset_instance)]133 pub type TokenIdToForeignReserveAssetInstance<T: Config> = StorageDoubleMap<174 pub type TokenIdToForeignReserveAssetInstance<T: Config> = StorageDoubleMap<134 Hasher1 = Twox64Concat,175 Hasher1 = Blake2_128Concat,135 Key1 = CollectionId,176 Key1 = CollectionId,136 Hasher2 = Blake2_128Concat,177 Hasher2 = Blake2_128Concat,137 Key2 = TokenId,178 Key2 = TokenId,138 // Value = staging_xcm::v3::AssetInstance,139 Value = staging_xcm::v4::AssetInstance,179 Value = staging_xcm::v4::AssetInstance,140 QueryKind = OptionQuery,180 QueryKind = OptionQuery,141 >;181 >;182183 const STORAGE_VERSION: StorageVersion = StorageVersion::new(staging_xcm::v4::VERSION as u16);142184143 #[pallet::pallet]185 #[pallet::pallet]186 #[pallet::storage_version(STORAGE_VERSION)]144 pub struct Pallet<T>(_);187 pub struct Pallet<T>(_);145188146 #[pallet::call]189 #[pallet::call]183 token_prefix,226 token_prefix,184 description,227 description,185 mode: mode.into(),228 mode: mode.into(),229 flags: CollectionFlags {230 foreign: true,231 ..Default::default()232 },186 ..Default::default()233 ..Default::default()187 },234 },188 )?;235 )?;199 }246 }200 }247 }248249 #[pallet::genesis_config]250 #[derive(Derivative)]251 #[derivative(Default(bound = ""))]252 pub struct GenesisConfig<T: Config>(PhantomData<T>);253254 #[pallet::genesis_build]255 impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {256 fn build(&self) {257 <Pallet<T>>::in_code_storage_version().put::<Pallet<T>>();258 }259 }260261 #[pallet::hooks]262 impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {263 fn on_runtime_upgrade() -> Weight {264 if Self::on_chain_storage_version() < staging_xcm::v4::VERSION as u16 {265 let put_version_weight = T::DbWeight::get().writes(1);266 let fix_foreign_flag_weight = Self::fix_foreign_flag();267 let weight_v3_to_v4 = Self::migrate_v3_to_v4();268269 Self::in_code_storage_version().put::<Self>();270271 put_version_weight272 .saturating_add(fix_foreign_flag_weight)273 .saturating_add(weight_v3_to_v4)274 } else {275 Weight::zero()276 }277 }278 }201}279}280281mod v3_storage {282 use super::*;283284 #[storage_alias]285 pub type ForeignAssetToCollection<T: Config> =286 StorageMap<Pallet<T>, Twox64Concat, staging_xcm::v3::AssetId, CollectionId, OptionQuery>;287288 #[storage_alias]289 pub type CollectionToForeignAsset<T: Config> =290 StorageMap<Pallet<T>, Twox64Concat, CollectionId, staging_xcm::v3::AssetId, OptionQuery>;291292 #[storage_alias]293 pub type ForeignReserveAssetInstanceToTokenId<T: Config> = StorageDoubleMap<294 Pallet<T>,295 Twox64Concat,296 CollectionId,297 Blake2_128Concat,298 staging_xcm::v3::AssetInstance,299 TokenId,300 OptionQuery,301 >;302303 #[storage_alias]304 pub type TokenIdToForeignReserveAssetInstance<T: Config> = StorageDoubleMap<305 Pallet<T>,306 Twox64Concat,307 CollectionId,308 Blake2_128Concat,309 TokenId,310 staging_xcm::v3::AssetInstance,311 OptionQuery,312 >;313}202314203impl<T: Config> Pallet<T> {315impl<T: Config> Pallet<T> {316 fn fix_foreign_flag() -> Weight {317 let mut weight = Weight::zero();318319 for (_, collection_id) in v3_storage::ForeignAssetToCollection::<T>::iter() {320 pallet_common::CollectionById::<T>::mutate(collection_id, |collection| {321 if let Some(collection) = collection {322 collection.flags.foreign = true;323 }324 });325326 weight = weight.saturating_add(T::DbWeight::get().reads_writes(2, 1));327 }328329 weight330 }331332 fn migrate_v3_to_v4() -> Weight {333 let event_weight = T::DbWeight::get().writes(1);334 let collection_migration_weight = Self::migrate_collections();335336 Self::deposit_event(Event::<T>::MigrationStatus(MigrationStatus::V3ToV4(337 MigrationStatusV3ToV4::Done,338 )));339340 collection_migration_weight.saturating_add(event_weight)341 }342343 fn migrate_collections() -> Weight {344 use MigrationStatus::*;345 use MigrationStatusV3ToV4::*;346347 let mut weight = Weight::zero();348349 for (fwd_asset_id, collection_id) in v3_storage::ForeignAssetToCollection::<T>::drain() {350 let bwd_asset_id = v3_storage::CollectionToForeignAsset::<T>::take(collection_id);351 weight = weight.saturating_add(T::DbWeight::get().reads(2));352353 let Some(bwd_asset_id) = bwd_asset_id else {354 Self::deposit_event(Event::<T>::MigrationStatus(V3ToV4(355 SkippedInconsistentAssetData(fwd_asset_id),356 )));357358 weight = weight.saturating_add(T::DbWeight::get().writes(1));359 continue;360 };361362 if fwd_asset_id != bwd_asset_id {363 Self::deposit_event(Event::<T>::MigrationStatus(V3ToV4(364 SkippedInconsistentAssetData(fwd_asset_id),365 )));366367 weight = weight.saturating_add(T::DbWeight::get().writes(1));368 continue;369 }370371 let Ok(asset_id) = staging_xcm::v4::AssetId::try_from(fwd_asset_id) else {372 Self::deposit_event(Event::<T>::MigrationStatus(V3ToV4(373 SkippedNotConvertibleAssetId(fwd_asset_id),374 )));375376 weight = weight.saturating_add(T::DbWeight::get().writes(1));377 continue;378 };379380 <ForeignAssetToCollection<T>>::insert(&asset_id, collection_id);381 <CollectionToForeignAsset<T>>::insert(collection_id, asset_id);382 weight = weight.saturating_add(T::DbWeight::get().writes(2));383384 let migrate_tokens_weight = Self::migrate_tokens(&fwd_asset_id, collection_id);385 weight = weight.saturating_add(migrate_tokens_weight);386 }387388 weight389 }390391 fn migrate_tokens(asset_id: &staging_xcm::v3::AssetId, collection_id: CollectionId) -> Weight {392 use MigrationStatus::*;393 use MigrationStatusV3ToV4::*;394395 let mut weight = Weight::zero();396397 for (fwd_asset_instance, token_id) in398 v3_storage::ForeignReserveAssetInstanceToTokenId::<T>::drain_prefix(collection_id)399 {400 let bwd_asset_instance = v3_storage::TokenIdToForeignReserveAssetInstance::<T>::take(401 collection_id,402 token_id,403 );404 weight = weight.saturating_add(T::DbWeight::get().reads(2));405406 let Some(bwd_asset_instance) = bwd_asset_instance else {407 Self::deposit_event(Event::<T>::MigrationStatus(V3ToV4(408 SkippedInconsistentAssetInstanceData {409 asset_id: *asset_id,410 asset_instance: fwd_asset_instance,411 },412 )));413414 weight = weight.saturating_add(T::DbWeight::get().writes(1));415 continue;416 };417418 if fwd_asset_instance != bwd_asset_instance {419 Self::deposit_event(Event::<T>::MigrationStatus(V3ToV4(420 SkippedInconsistentAssetInstanceData {421 asset_id: *asset_id,422 asset_instance: fwd_asset_instance,423 },424 )));425426 weight = weight.saturating_add(T::DbWeight::get().writes(1));427 continue;428 }429430 let Ok(asset_instance) = staging_xcm::v4::AssetInstance::try_from(fwd_asset_instance)431 else {432 Self::deposit_event(Event::<T>::MigrationStatus(V3ToV4(433 SkippedNotConvertibleAssetInstance {434 asset_id: *asset_id,435 asset_instance: fwd_asset_instance,436 },437 )));438439 weight = weight.saturating_add(T::DbWeight::get().writes(1));440 continue;441 };442443 <ForeignReserveAssetInstanceToTokenId<T>>::insert(444 collection_id,445 &asset_instance,446 token_id,447 );448 <TokenIdToForeignReserveAssetInstance<T>>::insert(449 collection_id,450 token_id,451 asset_instance,452 );453 weight = weight.saturating_add(T::DbWeight::get().writes(2));454 }455456 weight457 }458204 fn pallet_account() -> T::CrossAccountId {459 fn pallet_account() -> T::CrossAccountId {205 let owner: T::AccountId = T::PalletId::get().into_account_truncating();460 let owner: T::AccountId = T::PalletId::get().into_account_truncating();