git.delta.rocks / unique-network / refs/commits / be35f7200710

difftreelog

chore migrate foreign-assets to v4

Daniel Shiposha2024-05-27parent: #f78f490.patch.diff
in: master

1 file changed

modifiedpallets/foreign-assets/src/lib.rsdiffbeforeafterboth
26use core::ops::Deref;26use core::ops::Deref;
2727
28use frame_support::{dispatch::DispatchResult, pallet_prelude::*, traits::EnsureOrigin, PalletId};28use frame_support::{
29 dispatch::DispatchResult, pallet_prelude::*, storage_alias, traits::EnsureOrigin, PalletId,
30};
29use frame_system::pallet_prelude::*;31use frame_system::pallet_prelude::*;
30use pallet_common::{32use pallet_common::{
50pub use module::*;52pub use module::*;
51pub use weights::WeightInfo;53pub use weights::WeightInfo;
54
55/// Status of storage migration from an old XCM version to a new one.
56#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]
57pub enum MigrationStatus {
58 V3ToV4(MigrationStatusV3ToV4),
59}
60
61/// Status of storage migration from XCMv3 to XCMv4.
62#[derive(Clone, Copy, PartialEq, Eq, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)]
63pub enum MigrationStatusV3ToV4 {
64 /// The migration is completed.
65 Done,
66
67 /// An asset is skipped during the migration
68 /// due to its inconsistent state.
69 SkippedInconsistentAssetData(staging_xcm::v3::AssetId),
70
71 /// An asset instance is skipped during the migration
72 /// due to its inconsistent state.
73 SkippedInconsistentAssetInstanceData {
74 asset_id: staging_xcm::v3::AssetId,
75 asset_instance: staging_xcm::v3::AssetInstance,
76 },
77
78 /// An asset is skipped during the migration
79 /// because it couldn't be converted to the new XCM version.
80 SkippedNotConvertibleAssetId(staging_xcm::v3::AssetId),
81
82 /// An asset instance is skipped during the migration
83 /// because it couldn't be converted to the new XCM version.
84 SkippedNotConvertibleAssetInstance {
85 asset_id: staging_xcm::v3::AssetId,
86 asset_instance: staging_xcm::v3::AssetInstance,
87 },
88}
5289
53#[frame_support::pallet]90#[frame_support::pallet]
54pub mod module {91pub mod module {
93 }130 }
94131
95 #[pallet::event]132 #[pallet::event]
96 #[pallet::generate_deposit(fn deposit_event)]133 #[pallet::generate_deposit(pub(crate) fn deposit_event)]
97 pub enum Event<T: Config> {134 pub enum Event<T: Config> {
98 /// The foreign asset registered.135 /// The foreign asset registered.
99 ForeignAssetRegistered {136 ForeignAssetRegistered {
100 collection_id: CollectionId,137 collection_id: CollectionId,
101 asset_id: Box<VersionedAssetId>,138 asset_id: Box<VersionedAssetId>,
102 },139 },
140
141 /// The migration status.
142 MigrationStatus(MigrationStatus),
103 }143 }
104144
105 /// The corresponding collections of foreign assets.145 /// The corresponding collections of foreign assets.
106 #[pallet::storage]146 #[pallet::storage]
107 #[pallet::getter(fn foreign_asset_to_collection)]147 #[pallet::getter(fn foreign_asset_to_collection)]
108 pub type ForeignAssetToCollection<T: Config> =148 pub type ForeignAssetToCollection<T: Config> =
109 StorageMap<_, Twox64Concat, staging_xcm::v4::AssetId, CollectionId, OptionQuery>;149 StorageMap<_, Blake2_128Concat, staging_xcm::v4::AssetId, CollectionId, OptionQuery>;
110150
111 /// The corresponding foreign assets of collections.151 /// The corresponding foreign assets of collections.
112 #[pallet::storage]152 #[pallet::storage]
113 #[pallet::getter(fn collection_to_foreign_asset)]153 #[pallet::getter(fn collection_to_foreign_asset)]
114 pub type CollectionToForeignAsset<T: Config> =154 pub type CollectionToForeignAsset<T: Config> =
115 StorageMap<_, Twox64Concat, CollectionId, staging_xcm::v4::AssetId, OptionQuery>;155 StorageMap<_, Blake2_128Concat, CollectionId, staging_xcm::v4::AssetId, OptionQuery>;
116156
117 /// The correponding NFT token id of reserve NFTs157 /// The correponding NFT token id of reserve NFTs
118 #[pallet::storage]158 #[pallet::storage]
119 #[pallet::getter(fn foreign_reserve_asset_instance_to_token_id)]159 #[pallet::getter(fn foreign_reserve_asset_instance_to_token_id)]
120 pub type ForeignReserveAssetInstanceToTokenId<T: Config> = StorageDoubleMap<160 pub type ForeignReserveAssetInstanceToTokenId<T: Config> = StorageDoubleMap<
121 Hasher1 = Twox64Concat,161 Hasher1 = Blake2_128Concat,
122 Key1 = CollectionId,162 Key1 = CollectionId,
123 Hasher2 = Blake2_128Concat,163 Hasher2 = Blake2_128Concat,
124 // Key2 = staging_xcm::v3::AssetInstance,
125 Key2 = staging_xcm::v4::AssetInstance,164 Key2 = staging_xcm::v4::AssetInstance,
126 Value = TokenId,165 Value = TokenId,
127 QueryKind = OptionQuery,166 QueryKind = OptionQuery,
131 #[pallet::storage]170 #[pallet::storage]
132 #[pallet::getter(fn token_id_to_foreign_reserve_asset_instance)]171 #[pallet::getter(fn token_id_to_foreign_reserve_asset_instance)]
133 pub type TokenIdToForeignReserveAssetInstance<T: Config> = StorageDoubleMap<172 pub type TokenIdToForeignReserveAssetInstance<T: Config> = StorageDoubleMap<
134 Hasher1 = Twox64Concat,173 Hasher1 = Blake2_128Concat,
135 Key1 = CollectionId,174 Key1 = CollectionId,
136 Hasher2 = Blake2_128Concat,175 Hasher2 = Blake2_128Concat,
137 Key2 = TokenId,176 Key2 = TokenId,
138 // Value = staging_xcm::v3::AssetInstance,
139 Value = staging_xcm::v4::AssetInstance,177 Value = staging_xcm::v4::AssetInstance,
140 QueryKind = OptionQuery,178 QueryKind = OptionQuery,
141 >;179 >;
180
181 const STORAGE_VERSION: StorageVersion = StorageVersion::new(staging_xcm::v4::VERSION as u16);
142182
143 #[pallet::pallet]183 #[pallet::pallet]
184 #[pallet::storage_version(STORAGE_VERSION)]
144 pub struct Pallet<T>(_);185 pub struct Pallet<T>(_);
145186
146 #[pallet::call]187 #[pallet::call]
199 }240 }
200 }241 }
242
243 #[pallet::hooks]
244 impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
245 fn on_runtime_upgrade() -> Weight {
246 Self::migrate_v3_to_v4()
247 }
248 }
201}249}
250
251mod v3_storage {
252 use super::*;
253
254 #[storage_alias]
255 pub type ForeignAssetToCollection<T: Config> =
256 StorageMap<Pallet<T>, Twox64Concat, staging_xcm::v3::AssetId, CollectionId, OptionQuery>;
257
258 #[storage_alias]
259 pub type CollectionToForeignAsset<T: Config> =
260 StorageMap<Pallet<T>, Twox64Concat, CollectionId, staging_xcm::v3::AssetId, OptionQuery>;
261
262 #[storage_alias]
263 pub type ForeignReserveAssetInstanceToTokenId<T: Config> = StorageDoubleMap<
264 Pallet<T>,
265 Twox64Concat,
266 CollectionId,
267 Blake2_128Concat,
268 staging_xcm::v3::AssetInstance,
269 TokenId,
270 OptionQuery,
271 >;
272
273 #[storage_alias]
274 pub type TokenIdToForeignReserveAssetInstance<T: Config> = StorageDoubleMap<
275 Pallet<T>,
276 Twox64Concat,
277 CollectionId,
278 Blake2_128Concat,
279 TokenId,
280 staging_xcm::v3::AssetInstance,
281 OptionQuery,
282 >;
283}
202284
203impl<T: Config> Pallet<T> {285impl<T: Config> Pallet<T> {
286 fn migrate_v3_to_v4() -> Weight {
287 if Self::on_chain_storage_version() < staging_xcm::v4::VERSION as u16 {
288 let put_version_weight = T::DbWeight::get().writes(1);
289 let event_weight = T::DbWeight::get().writes(1);
290 let collection_migration_weight = Self::migrate_collections();
291
292 StorageVersion::new(staging_xcm::v4::VERSION as u16).put::<Self>();
293
294 Self::deposit_event(Event::<T>::MigrationStatus(MigrationStatus::V3ToV4(
295 MigrationStatusV3ToV4::Done,
296 )));
297
298 put_version_weight
299 .saturating_add(collection_migration_weight)
300 .saturating_add(event_weight)
301 } else {
302 Weight::zero()
303 }
304 }
305
306 fn migrate_collections() -> Weight {
307 use MigrationStatus::*;
308 use MigrationStatusV3ToV4::*;
309
310 let mut weight = Weight::zero();
311
312 for (fwd_asset_id, collection_id) in v3_storage::ForeignAssetToCollection::<T>::drain() {
313 let bwd_asset_id = v3_storage::CollectionToForeignAsset::<T>::take(collection_id);
314 weight = weight.saturating_add(T::DbWeight::get().reads(2));
315
316 let Some(bwd_asset_id) = bwd_asset_id else {
317 Self::deposit_event(Event::<T>::MigrationStatus(V3ToV4(
318 SkippedInconsistentAssetData(fwd_asset_id),
319 )));
320
321 weight = weight.saturating_add(T::DbWeight::get().writes(1));
322 continue;
323 };
324
325 if fwd_asset_id != bwd_asset_id {
326 Self::deposit_event(Event::<T>::MigrationStatus(V3ToV4(
327 SkippedInconsistentAssetData(fwd_asset_id),
328 )));
329
330 weight = weight.saturating_add(T::DbWeight::get().writes(1));
331 continue;
332 }
333
334 let Ok(asset_id) = staging_xcm::v4::AssetId::try_from(fwd_asset_id) else {
335 Self::deposit_event(Event::<T>::MigrationStatus(V3ToV4(
336 SkippedNotConvertibleAssetId(fwd_asset_id),
337 )));
338
339 weight = weight.saturating_add(T::DbWeight::get().writes(1));
340 continue;
341 };
342
343 <ForeignAssetToCollection<T>>::insert(&asset_id, collection_id);
344 <CollectionToForeignAsset<T>>::insert(collection_id, asset_id);
345 weight = weight.saturating_add(T::DbWeight::get().writes(2));
346
347 let migrate_tokens_weight = Self::migrate_tokens(&fwd_asset_id, collection_id);
348 weight = weight.saturating_add(migrate_tokens_weight);
349 }
350
351 weight
352 }
353
354 fn migrate_tokens(asset_id: &staging_xcm::v3::AssetId, collection_id: CollectionId) -> Weight {
355 use MigrationStatus::*;
356 use MigrationStatusV3ToV4::*;
357
358 let mut weight = Weight::zero();
359
360 for (fwd_asset_instance, token_id) in
361 v3_storage::ForeignReserveAssetInstanceToTokenId::<T>::drain_prefix(collection_id)
362 {
363 let bwd_asset_instance = v3_storage::TokenIdToForeignReserveAssetInstance::<T>::take(
364 collection_id,
365 token_id,
366 );
367 weight = weight.saturating_add(T::DbWeight::get().reads(2));
368
369 let Some(bwd_asset_instance) = bwd_asset_instance else {
370 Self::deposit_event(Event::<T>::MigrationStatus(V3ToV4(
371 SkippedInconsistentAssetInstanceData {
372 asset_id: *asset_id,
373 asset_instance: fwd_asset_instance,
374 },
375 )));
376
377 weight = weight.saturating_add(T::DbWeight::get().writes(1));
378 continue;
379 };
380
381 if fwd_asset_instance != bwd_asset_instance {
382 Self::deposit_event(Event::<T>::MigrationStatus(V3ToV4(
383 SkippedInconsistentAssetInstanceData {
384 asset_id: *asset_id,
385 asset_instance: fwd_asset_instance,
386 },
387 )));
388
389 weight = weight.saturating_add(T::DbWeight::get().writes(1));
390 continue;
391 }
392
393 let Ok(asset_instance) = staging_xcm::v4::AssetInstance::try_from(fwd_asset_instance)
394 else {
395 Self::deposit_event(Event::<T>::MigrationStatus(V3ToV4(
396 SkippedNotConvertibleAssetInstance {
397 asset_id: *asset_id,
398 asset_instance: fwd_asset_instance,
399 },
400 )));
401
402 weight = weight.saturating_add(T::DbWeight::get().writes(1));
403 continue;
404 };
405
406 <ForeignReserveAssetInstanceToTokenId<T>>::insert(
407 collection_id,
408 &asset_instance,
409 token_id,
410 );
411 <TokenIdToForeignReserveAssetInstance<T>>::insert(
412 collection_id,
413 token_id,
414 asset_instance,
415 );
416 weight = weight.saturating_add(T::DbWeight::get().writes(2));
417 }
418
419 weight
420 }
421
204 fn pallet_account() -> T::CrossAccountId {422 fn pallet_account() -> T::CrossAccountId {
205 let owner: T::AccountId = T::PalletId::get().into_account_truncating();423 let owner: T::AccountId = T::PalletId::get().into_account_truncating();