pallet_assets/
migration.rs1use super::*;
19use frame_support::traits::OnRuntimeUpgrade;
20use log;
21
22#[cfg(feature = "try-runtime")]
23use sp_runtime::TryRuntimeError;
24
25pub mod next_asset_id {
26 use super::*;
27 use sp_core::Get;
28
29 pub struct SetNextAssetId<ID, T: Config<I>, I: 'static = ()>(
31 core::marker::PhantomData<(ID, T, I)>,
32 );
33 impl<ID, T: Config<I>, I: 'static> OnRuntimeUpgrade for SetNextAssetId<ID, T, I>
34 where
35 T::AssetId: Incrementable,
36 ID: Get<T::AssetId>,
37 {
38 fn on_runtime_upgrade() -> frame_support::weights::Weight {
39 if !NextAssetId::<T, I>::exists() {
40 NextAssetId::<T, I>::put(ID::get());
41 T::DbWeight::get().reads_writes(1, 1)
42 } else {
43 T::DbWeight::get().reads(1)
44 }
45 }
46 }
47}
48
49pub mod v1 {
50 use frame_support::{pallet_prelude::*, weights::Weight};
51
52 use super::*;
53
54 #[derive(Decode)]
55 pub struct OldAssetDetails<Balance, AccountId, DepositBalance> {
56 pub owner: AccountId,
57 pub issuer: AccountId,
58 pub admin: AccountId,
59 pub freezer: AccountId,
60 pub supply: Balance,
61 pub deposit: DepositBalance,
62 pub min_balance: Balance,
63 pub is_sufficient: bool,
64 pub accounts: u32,
65 pub sufficients: u32,
66 pub approvals: u32,
67 pub is_frozen: bool,
68 }
69
70 impl<Balance, AccountId, DepositBalance> OldAssetDetails<Balance, AccountId, DepositBalance> {
71 fn migrate_to_v1(self) -> AssetDetails<Balance, AccountId, DepositBalance> {
72 let status = if self.is_frozen { AssetStatus::Frozen } else { AssetStatus::Live };
73
74 AssetDetails {
75 owner: self.owner,
76 issuer: self.issuer,
77 admin: self.admin,
78 freezer: self.freezer,
79 supply: self.supply,
80 deposit: self.deposit,
81 min_balance: self.min_balance,
82 is_sufficient: self.is_sufficient,
83 accounts: self.accounts,
84 sufficients: self.sufficients,
85 approvals: self.approvals,
86 status,
87 }
88 }
89 }
90
91 pub struct MigrateToV1<T>(core::marker::PhantomData<T>);
92 impl<T: Config> OnRuntimeUpgrade for MigrateToV1<T> {
93 fn on_runtime_upgrade() -> Weight {
94 let in_code_version = Pallet::<T>::in_code_storage_version();
95 let on_chain_version = Pallet::<T>::on_chain_storage_version();
96 if on_chain_version == 0 && in_code_version == 1 {
97 let mut translated = 0u64;
98 Asset::<T>::translate::<
99 OldAssetDetails<T::Balance, T::AccountId, DepositBalanceOf<T>>,
100 _,
101 >(|_key, old_value| {
102 translated.saturating_inc();
103 Some(old_value.migrate_to_v1())
104 });
105 in_code_version.put::<Pallet<T>>();
106 log::info!(
107 target: LOG_TARGET,
108 "Upgraded {} pools, storage to version {:?}",
109 translated,
110 in_code_version
111 );
112 T::DbWeight::get().reads_writes(translated + 1, translated + 1)
113 } else {
114 log::info!(
115 target: LOG_TARGET,
116 "Migration did not execute. This probably should be removed"
117 );
118 T::DbWeight::get().reads(1)
119 }
120 }
121
122 #[cfg(feature = "try-runtime")]
123 fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
124 frame_support::ensure!(
125 Pallet::<T>::on_chain_storage_version() == 0,
126 "must upgrade linearly"
127 );
128 let prev_count = Asset::<T>::iter().count();
129 Ok((prev_count as u32).encode())
130 }
131
132 #[cfg(feature = "try-runtime")]
133 fn post_upgrade(prev_count: Vec<u8>) -> Result<(), TryRuntimeError> {
134 let prev_count: u32 = Decode::decode(&mut prev_count.as_slice()).expect(
135 "the state parameter should be something that was generated by pre_upgrade",
136 );
137 let post_count = Asset::<T>::iter().count() as u32;
138 ensure!(
139 prev_count == post_count,
140 "the asset count before and after the migration should be the same"
141 );
142
143 let in_code_version = Pallet::<T>::in_code_storage_version();
144 let on_chain_version = Pallet::<T>::on_chain_storage_version();
145
146 frame_support::ensure!(in_code_version == 1, "must_upgrade");
147 ensure!(
148 in_code_version == on_chain_version,
149 "after migration, the in_code_version and on_chain_version should be the same"
150 );
151
152 Asset::<T>::iter().try_for_each(|(_id, asset)| -> Result<(), TryRuntimeError> {
153 ensure!(
154 asset.status == AssetStatus::Live || asset.status == AssetStatus::Frozen,
155 "assets should only be live or frozen. None should be in destroying status, or undefined state"
156 );
157 Ok(())
158 })?;
159 Ok(())
160 }
161 }
162}