referrerpolicy=no-referrer-when-downgrade

pallet_contracts/migration/
v13.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Add `delegate_dependencies` to `ContractInfo`.
19//! See <https://github.com/paritytech/substrate/pull/14079>.
20
21use 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}