pallet_contracts/migration/
v13.rs1use crate::{
22 migration::{IsFinished, MigrationStep},
23 weights::WeightInfo,
24 AccountIdOf, BalanceOf, CodeHash, Config, Pallet, TrieId, Weight, LOG_TARGET,
25};
26use codec::{Decode, Encode};
27use frame_support::{pallet_prelude::*, storage_alias, weights::WeightMeter, DefaultNoBound};
28use sp_runtime::BoundedBTreeMap;
29
30mod v12 {
31 use super::*;
32
33 #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
34 #[scale_info(skip_type_params(T))]
35 pub struct ContractInfo<T: Config> {
36 pub trie_id: TrieId,
37 pub deposit_account: AccountIdOf<T>,
38 pub code_hash: CodeHash<T>,
39 pub storage_bytes: u32,
40 pub storage_items: u32,
41 pub storage_byte_deposit: BalanceOf<T>,
42 pub storage_item_deposit: BalanceOf<T>,
43 pub storage_base_deposit: BalanceOf<T>,
44 }
45
46 #[storage_alias]
47 pub type ContractInfoOf<T: Config> = StorageMap<
48 Pallet<T>,
49 Twox64Concat,
50 <T as frame_system::Config>::AccountId,
51 ContractInfo<T>,
52 >;
53}
54
55#[cfg(feature = "runtime-benchmarks")]
56pub fn store_old_contract_info<T: Config>(account: T::AccountId, info: crate::ContractInfo<T>) {
57 use sp_runtime::traits::{Hash, TrailingZeroInput};
58 let entropy = (b"contract_depo_v1", account.clone()).using_encoded(T::Hashing::hash);
59 let deposit_account = Decode::decode(&mut TrailingZeroInput::new(entropy.as_ref()))
60 .expect("infinite length input; no invalid inputs for type; qed");
61 let info = v12::ContractInfo {
62 trie_id: info.trie_id.clone(),
63 deposit_account,
64 code_hash: info.code_hash,
65 storage_bytes: Default::default(),
66 storage_items: Default::default(),
67 storage_byte_deposit: Default::default(),
68 storage_item_deposit: Default::default(),
69 storage_base_deposit: Default::default(),
70 };
71 v12::ContractInfoOf::<T>::insert(account, info);
72}
73
74#[storage_alias]
75pub type ContractInfoOf<T: Config> =
76 StorageMap<Pallet<T>, Twox64Concat, <T as frame_system::Config>::AccountId, ContractInfo<T>>;
77
78#[derive(Encode, Decode, CloneNoBound, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
79#[scale_info(skip_type_params(T))]
80pub struct ContractInfo<T: Config> {
81 trie_id: TrieId,
82 deposit_account: AccountIdOf<T>,
83 code_hash: CodeHash<T>,
84 storage_bytes: u32,
85 storage_items: u32,
86 storage_byte_deposit: BalanceOf<T>,
87 storage_item_deposit: BalanceOf<T>,
88 storage_base_deposit: BalanceOf<T>,
89 delegate_dependencies: BoundedBTreeMap<CodeHash<T>, BalanceOf<T>, T::MaxDelegateDependencies>,
90}
91
92#[derive(Encode, Decode, MaxEncodedLen, DefaultNoBound)]
93pub struct Migration<T: Config> {
94 last_account: Option<T::AccountId>,
95}
96
97impl<T: Config> MigrationStep for Migration<T> {
98 const VERSION: u16 = 13;
99
100 fn max_step_weight() -> Weight {
101 T::WeightInfo::v13_migration_step()
102 }
103
104 fn step(&mut self, meter: &mut WeightMeter) -> IsFinished {
105 let mut iter = if let Some(last_account) = self.last_account.take() {
106 v12::ContractInfoOf::<T>::iter_from(v12::ContractInfoOf::<T>::hashed_key_for(
107 last_account,
108 ))
109 } else {
110 v12::ContractInfoOf::<T>::iter()
111 };
112
113 if let Some((key, old)) = iter.next() {
114 log::debug!(target: LOG_TARGET, "Migrating contract {:?}", key);
115 let info = ContractInfo {
116 trie_id: old.trie_id,
117 deposit_account: old.deposit_account,
118 code_hash: old.code_hash,
119 storage_bytes: old.storage_bytes,
120 storage_items: old.storage_items,
121 storage_byte_deposit: old.storage_byte_deposit,
122 storage_item_deposit: old.storage_item_deposit,
123 storage_base_deposit: old.storage_base_deposit,
124 delegate_dependencies: Default::default(),
125 };
126 ContractInfoOf::<T>::insert(key.clone(), info);
127 self.last_account = Some(key);
128 meter.consume(T::WeightInfo::v13_migration_step());
129 IsFinished::No
130 } else {
131 log::debug!(target: LOG_TARGET, "No more contracts to migrate");
132 meter.consume(T::WeightInfo::v13_migration_step());
133 IsFinished::Yes
134 }
135 }
136}