referrerpolicy=no-referrer-when-downgrade

pallet_contracts/migration/
v16.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//! Remove ED from storage base deposit.
19//! See <https://github.com/paritytech/polkadot-sdk/pull/3536>.
20
21use crate::{
22	migration::{IsFinished, MigrationStep},
23	weights::WeightInfo,
24	BalanceOf, CodeHash, Config, Pallet, TrieId, Weight, WeightMeter, LOG_TARGET,
25};
26use codec::{Decode, Encode};
27use frame_support::{pallet_prelude::*, storage_alias, DefaultNoBound};
28use sp_runtime::{BoundedBTreeMap, Saturating};
29
30#[cfg(feature = "runtime-benchmarks")]
31pub fn store_old_contract_info<T: Config>(
32	account: T::AccountId,
33	info: &crate::ContractInfo<T>,
34) -> BalanceOf<T> {
35	let storage_base_deposit = Pallet::<T>::min_balance() + 1u32.into();
36	ContractInfoOf::<T>::insert(
37		account,
38		ContractInfo {
39			trie_id: info.trie_id.clone(),
40			code_hash: info.code_hash,
41			storage_bytes: Default::default(),
42			storage_items: Default::default(),
43			storage_byte_deposit: Default::default(),
44			storage_item_deposit: Default::default(),
45			storage_base_deposit,
46			delegate_dependencies: Default::default(),
47		},
48	);
49
50	storage_base_deposit
51}
52
53#[storage_alias]
54pub type ContractInfoOf<T: Config> =
55	StorageMap<Pallet<T>, Twox64Concat, <T as frame_system::Config>::AccountId, ContractInfo<T>>;
56
57#[derive(Encode, Decode, CloneNoBound, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
58#[scale_info(skip_type_params(T))]
59pub struct ContractInfo<T: Config> {
60	trie_id: TrieId,
61	code_hash: CodeHash<T>,
62	storage_bytes: u32,
63	storage_items: u32,
64	storage_byte_deposit: BalanceOf<T>,
65	storage_item_deposit: BalanceOf<T>,
66	pub storage_base_deposit: BalanceOf<T>,
67	delegate_dependencies: BoundedBTreeMap<CodeHash<T>, BalanceOf<T>, T::MaxDelegateDependencies>,
68}
69
70#[derive(Encode, Decode, MaxEncodedLen, DefaultNoBound)]
71pub struct Migration<T: Config> {
72	last_account: Option<T::AccountId>,
73}
74
75impl<T: Config> MigrationStep for Migration<T> {
76	const VERSION: u16 = 16;
77
78	fn max_step_weight() -> Weight {
79		T::WeightInfo::v16_migration_step()
80	}
81
82	fn step(&mut self, meter: &mut WeightMeter) -> IsFinished {
83		let mut iter = if let Some(last_account) = self.last_account.take() {
84			ContractInfoOf::<T>::iter_keys_from(ContractInfoOf::<T>::hashed_key_for(last_account))
85		} else {
86			ContractInfoOf::<T>::iter_keys()
87		};
88
89		if let Some(key) = iter.next() {
90			log::debug!(target: LOG_TARGET, "Migrating contract {:?}", key);
91			ContractInfoOf::<T>::mutate(key.clone(), |info| {
92				let ed = Pallet::<T>::min_balance();
93				let mut updated_info = info.take().expect("Item exists; qed");
94				updated_info.storage_base_deposit.saturating_reduce(ed);
95				*info = Some(updated_info);
96			});
97			self.last_account = Some(key);
98			meter.consume(T::WeightInfo::v16_migration_step());
99			IsFinished::No
100		} else {
101			log::debug!(target: LOG_TARGET, "No more contracts to migrate");
102			meter.consume(T::WeightInfo::v16_migration_step());
103			IsFinished::Yes
104		}
105	}
106}