// This file is part of Substrate. // Copyright (C) 2018-2022 Parity Technologies (UK) Ltd. // SPDX-License-Identifier: Apache-2.0 // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use crate::{BalanceOf, CodeHash, Config, Pallet, TrieId, Weight}; use codec::{Decode, Encode}; use frame_support::{ codec, generate_storage_alias, storage::migration, traits::{Get, PalletInfoAccess}, Identity, Twox64Concat, }; use sp_std::{marker::PhantomData, prelude::*}; pub fn migrate() -> Weight { use frame_support::traits::StorageVersion; let version = StorageVersion::get::>(); let mut weight: Weight = 0; if version < 4 { weight = weight.saturating_add(v4::migrate::()); StorageVersion::new(4).put::>(); } if version < 5 { weight = weight.saturating_add(v5::migrate::()); StorageVersion::new(5).put::>(); } if version < 6 { weight = weight.saturating_add(v6::migrate::()); StorageVersion::new(6).put::>(); } weight } /// V4: `Schedule` is changed to be a config item rather than an in-storage value. mod v4 { use super::*; pub fn migrate() -> Weight { migration::remove_storage_prefix(>::name().as_bytes(), b"CurrentSchedule", b""); T::DbWeight::get().writes(1) } } /// V5: State rent is removed which obsoletes some fields in `ContractInfo`. mod v5 { use super::*; type AliveContractInfo = RawAliveContractInfo, BalanceOf, ::BlockNumber>; type TombstoneContractInfo = RawTombstoneContractInfo< ::Hash, ::Hashing, >; #[derive(Decode)] enum OldContractInfo { Alive(AliveContractInfo), Tombstone(TombstoneContractInfo), } #[derive(Decode)] struct RawAliveContractInfo { trie_id: TrieId, _storage_size: u32, _pair_count: u32, code_hash: CodeHash, _rent_allowance: Balance, _rent_paid: Balance, _deduct_block: BlockNumber, _last_write: Option, _reserved: Option<()>, } #[derive(Decode)] struct RawTombstoneContractInfo(H, PhantomData); #[derive(Decode)] struct OldDeletedContract { _pair_count: u32, trie_id: TrieId, } pub type ContractInfo = RawContractInfo>; #[derive(Encode, Decode)] pub struct RawContractInfo { pub trie_id: TrieId, pub code_hash: CodeHash, pub _reserved: Option<()>, } #[derive(Encode, Decode)] struct DeletedContract { trie_id: TrieId, } generate_storage_alias!( Contracts, ContractInfoOf => Map<(Twox64Concat, T::AccountId), ContractInfo> ); generate_storage_alias!( Contracts, DeletionQueue => Value> ); pub fn migrate() -> Weight { let mut weight: Weight = 0; >::translate(|_key, old: OldContractInfo| { weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); match old { OldContractInfo::Alive(old) => Some(ContractInfo:: { trie_id: old.trie_id, code_hash: old.code_hash, _reserved: old._reserved, }), OldContractInfo::Tombstone(_) => None, } }); DeletionQueue::translate(|old: Option>| { weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); old.map(|old| old.into_iter().map(|o| DeletedContract { trie_id: o.trie_id }).collect()) }) .ok(); weight } } /// V6: Added storage deposits mod v6 { use super::*; #[derive(Encode, Decode)] struct OldPrefabWasmModule { #[codec(compact)] instruction_weights_version: u32, #[codec(compact)] initial: u32, #[codec(compact)] maximum: u32, #[codec(compact)] refcount: u64, _reserved: Option<()>, code: Vec, original_code_len: u32, } #[derive(Encode, Decode)] struct PrefabWasmModule { #[codec(compact)] instruction_weights_version: u32, #[codec(compact)] initial: u32, #[codec(compact)] maximum: u32, code: Vec, } use v5::ContractInfo as OldContractInfo; #[derive(Encode, Decode)] pub struct RawContractInfo { trie_id: TrieId, code_hash: CodeHash, storage_deposit: Balance, } #[derive(Encode, Decode)] pub struct OwnerInfo { owner: T::AccountId, #[codec(compact)] deposit: BalanceOf, #[codec(compact)] refcount: u64, } type ContractInfo = RawContractInfo, BalanceOf>; generate_storage_alias!( Contracts, ContractInfoOf => Map<(Twox64Concat, T::AccountId), ContractInfo> ); generate_storage_alias!( Contracts, CodeStorage => Map<(Identity, CodeHash), PrefabWasmModule> ); generate_storage_alias!( Contracts, OwnerInfoOf => Map<(Identity, CodeHash), OwnerInfo> ); pub fn migrate() -> Weight { let mut weight: Weight = 0; >::translate(|_key, old: OldContractInfo| { weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 1)); Some(ContractInfo:: { trie_id: old.trie_id, code_hash: old.code_hash, storage_deposit: Default::default(), }) }); let nobody = T::AccountId::decode(&mut sp_runtime::traits::TrailingZeroInput::zeroes()) .expect("Infinite input; no dead input space; qed"); >::translate(|key, old: OldPrefabWasmModule| { weight = weight.saturating_add(T::DbWeight::get().reads_writes(1, 2)); >::insert( key, OwnerInfo { refcount: old.refcount, owner: nobody.clone(), deposit: Default::default(), }, ); Some(PrefabWasmModule { instruction_weights_version: old.instruction_weights_version, initial: old.initial, maximum: old.maximum, code: old.code, }) }); weight } }