pallet_msa/migration/
v2.rs1#[allow(deprecated)]
2use crate::ProviderToRegistryEntry;
3use crate::{migration::v1, Config, Pallet, ProviderToRegistryEntryV2};
4pub use alloc::vec;
5use common_primitives::msa::{ProviderId, ProviderRegistryEntry};
6use frame_support::{pallet_prelude::*, storage_alias, weights::Weight};
7pub use frame_system::pallet_prelude::BlockNumberFor;
8#[cfg(feature = "try-runtime")]
9pub use sp_runtime::TryRuntimeError;
10const LOG_TARGET: &str = "runtime::provider";
11pub const MAX_ITEMS_PER_BLOCK: u32 = 50; #[derive(Default, Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
15pub struct MigrationStatus {
16 pub migrated_count: u32,
18 pub completed: bool,
20 pub last_raw_key: Option<vec::Vec<u8>>,
22}
23
24#[storage_alias]
26pub type MigrationProgressV2<T: Config> = StorageValue<Pallet<T>, MigrationStatus, ValueQuery>;
27
28#[allow(deprecated)]
30pub fn migrate_provider_entries_batch<T: Config>(
31 batch_size: usize,
32 start_after_raw_key: Option<vec::Vec<u8>>,
33) -> (Weight, u32, Option<vec::Vec<u8>>) {
34 let mut reads = 0u64;
35 let mut writes = 0u64;
36 let mut bytes = 0u64;
37 let mut migrated_count = 0u32;
38 let mut last_raw_key = None;
39
40 let iter = match start_after_raw_key {
41 Some(raw_key) => ProviderToRegistryEntry::<T>::iter_from(raw_key),
42 None => ProviderToRegistryEntry::<T>::iter(),
43 };
44
45 let entries: vec::Vec<(
46 ProviderId,
47 v1::ProviderRegistryEntry<<T as Config>::MaxProviderNameSize>,
48 )> = iter.take(batch_size).collect();
49
50 for (provider_id, old_entry) in entries {
51 if ProviderToRegistryEntryV2::<T>::contains_key(provider_id) {
53 reads += 1;
54 continue;
55 }
56 let migrated_provider_entry = ProviderRegistryEntry {
58 default_name: old_entry.provider_name.clone(),
59 default_logo_250_100_png_cid: BoundedVec::default(),
60 localized_logo_250_100_png_cids: BoundedBTreeMap::default(),
61 localized_names: BoundedBTreeMap::default(),
62 };
63 ProviderToRegistryEntryV2::<T>::insert(provider_id, migrated_provider_entry);
65 reads += 2;
66 writes += 1;
67 bytes += old_entry.encoded_size() as u64;
68 migrated_count += 1;
69 last_raw_key = Some(ProviderToRegistryEntry::<T>::hashed_key_for(provider_id));
70 }
71
72 let weight = T::DbWeight::get().reads_writes(reads, writes).add_proof_size(bytes);
73 (weight, migrated_count, last_raw_key)
74}
75
76pub fn on_initialize_migration<T: Config>() -> Weight {
79 let onchain_version = Pallet::<T>::on_chain_storage_version();
81 if onchain_version >= 2 {
82 if MigrationProgressV2::<T>::exists() {
84 MigrationProgressV2::<T>::kill();
85 return T::DbWeight::get().reads_writes(1, 1)
86 }
87 return T::DbWeight::get().reads(1)
88 }
89
90 let migration_status = MigrationProgressV2::<T>::get();
91 let mut reads = 1u64;
92 let mut writes = 0u64;
93
94 if !migration_status.completed {
96 let (batch_weight, migrated_in_this_block, last_key) = migrate_provider_entries_batch::<T>(
97 MAX_ITEMS_PER_BLOCK as usize,
98 migration_status.last_raw_key.clone(),
99 );
100
101 let mut updated_status = migration_status;
102 updated_status.migrated_count += migrated_in_this_block;
103 updated_status.completed = migrated_in_this_block == 0;
104 updated_status.last_raw_key = last_key;
105 reads += 1;
106 if updated_status.completed {
108 StorageVersion::new(2).put::<Pallet<T>>();
109 MigrationProgressV2::<T>::kill();
110 writes += 2;
111 log::info!(target: LOG_TARGET, "Hook-based migration completed! Total migrated: {}", updated_status.migrated_count);
112 } else {
113 MigrationProgressV2::<T>::put(&updated_status);
114 writes += 1;
115 }
116 return T::DbWeight::get().reads_writes(reads, writes).saturating_add(batch_weight);
117 }
118 log::info!(target: LOG_TARGET, "Provider Registry Migration already completed.");
119 T::DbWeight::get().reads(1)
120}