mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 19:21:13 +00:00
Update contract multi-block migration (#14313)
* move migrate sequence to config * remove commented out code * Update frame/contracts/src/lib.rs Co-authored-by: PG Herveou <pgherveou@gmail.com> * remove Migrations generic * make runtime use noop migrations * restrict is_upgrade_supported * Update contract multi-block migration Ensure that we do as many steps as possible given the weight limit passed to on_idle * undo is_upgrade_supported change * Update bin/node/runtime/src/lib.rs Co-authored-by: PG Herveou <pgherveou@gmail.com> * wip * fix comment (#14316) * fix test * fix * Update frame/contracts/src/migration.rs Co-authored-by: Juan <juangirini@gmail.com> * fix test doc * Apply suggestions from code review Co-authored-by: Sasha Gryaznov <hi@agryaznov.com> * Fix compilation with feature runtime-benchmarks * fix example * fix cargo doc --document-private-items * private links * Remove dup comment * add doc for MigrationInProgress * PR review remove duplicate asserts * simplify upper bound * fix link * typo * typo * no unwrap() * correct log message * missing * fix typo * PR comment * Add example with single element tuple * Improve migration message * Update frame/contracts/src/benchmarking/mod.rs Co-authored-by: Sasha Gryaznov <hi@agryaznov.com> * Update frame/contracts/src/migration.rs Co-authored-by: Sasha Gryaznov <hi@agryaznov.com> * Update frame/contracts/src/migration.rs Co-authored-by: Sasha Gryaznov <hi@agryaznov.com> * use saturating_accrue instead of += * add more doc * Contracts: Better migration types (#14418) * Add explicit error, if try-runtime runs a noop migration * use mut remaining_weight --------- Co-authored-by: Juan Girini <juangirini@gmail.com> Co-authored-by: Sasha Gryaznov <hi@agryaznov.com>
This commit is contained in:
@@ -16,12 +16,12 @@
|
||||
// limitations under the License.
|
||||
|
||||
//! Don't rely on reserved balances keeping an account alive
|
||||
//! See <https://github.com/paritytech/substrate/pull/13370>.
|
||||
//! See <https://github.com/paritytech/substrate/pull/13369>.
|
||||
|
||||
use crate::{
|
||||
address::AddressGenerator,
|
||||
exec::AccountIdOf,
|
||||
migration::{IsFinished, Migrate},
|
||||
migration::{IsFinished, MigrationStep},
|
||||
weights::WeightInfo,
|
||||
BalanceOf, CodeHash, Config, Pallet, TrieId, Weight, LOG_TARGET,
|
||||
};
|
||||
@@ -42,7 +42,7 @@ use sp_core::hexdisplay::HexDisplay;
|
||||
#[cfg(feature = "try-runtime")]
|
||||
use sp_runtime::TryRuntimeError;
|
||||
use sp_runtime::{traits::Zero, Perbill, Saturating};
|
||||
use sp_std::{marker::PhantomData, ops::Deref, prelude::*};
|
||||
use sp_std::{ops::Deref, prelude::*};
|
||||
|
||||
mod old {
|
||||
use super::*;
|
||||
@@ -69,7 +69,7 @@ mod old {
|
||||
}
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
pub fn store_old_contrat_info<T: Config>(account: T::AccountId, info: crate::ContractInfo<T>) {
|
||||
pub fn store_old_contract_info<T: Config>(account: T::AccountId, info: crate::ContractInfo<T>) {
|
||||
let info = old::ContractInfo {
|
||||
trie_id: info.trie_id,
|
||||
code_hash: info.code_hash,
|
||||
@@ -109,15 +109,14 @@ pub struct ContractInfo<T: Config> {
|
||||
|
||||
#[derive(Encode, Decode, MaxEncodedLen, DefaultNoBound)]
|
||||
pub struct Migration<T: Config> {
|
||||
last_key: Option<BoundedVec<u8, ConstU32<256>>>,
|
||||
_phantom: PhantomData<T>,
|
||||
last_account: Option<T::AccountId>,
|
||||
}
|
||||
|
||||
#[storage_alias]
|
||||
type ContractInfoOf<T: Config> =
|
||||
StorageMap<Pallet<T>, Twox64Concat, <T as frame_system::Config>::AccountId, ContractInfo<T>>;
|
||||
|
||||
impl<T: Config> Migrate for Migration<T> {
|
||||
impl<T: Config> MigrationStep for Migration<T> {
|
||||
const VERSION: u16 = 10;
|
||||
|
||||
fn max_step_weight() -> Weight {
|
||||
@@ -125,8 +124,10 @@ impl<T: Config> Migrate for Migration<T> {
|
||||
}
|
||||
|
||||
fn step(&mut self) -> (IsFinished, Weight) {
|
||||
let mut iter = if let Some(last_key) = self.last_key.take() {
|
||||
old::ContractInfoOf::<T>::iter_from(last_key.to_vec())
|
||||
let mut iter = if let Some(last_account) = self.last_account.take() {
|
||||
old::ContractInfoOf::<T>::iter_from(old::ContractInfoOf::<T>::hashed_key_for(
|
||||
last_account,
|
||||
))
|
||||
} else {
|
||||
old::ContractInfoOf::<T>::iter()
|
||||
};
|
||||
@@ -135,9 +136,6 @@ impl<T: Config> Migrate for Migration<T> {
|
||||
let min_balance = Pallet::<T>::min_balance();
|
||||
log::debug!(target: LOG_TARGET, "Account: 0x{} ", HexDisplay::from(&account.encode()));
|
||||
|
||||
// Store last key for next migration step
|
||||
self.last_key = Some(iter.last_raw_key().to_vec().try_into().unwrap());
|
||||
|
||||
// Get the new deposit account address
|
||||
let deposit_account: DepositAccount<T> =
|
||||
DepositAccount(T::AddressGenerator::deposit_address(&account));
|
||||
@@ -181,14 +179,14 @@ impl<T: Config> Migrate for Migration<T> {
|
||||
})
|
||||
// If it fails we fallback to minting the ED.
|
||||
.unwrap_or_else(|err| {
|
||||
log::error!(target: LOG_TARGET, "Failed to transfer ED, reason: {:?}", err);
|
||||
log::error!(target: LOG_TARGET, "Failed to transfer the base deposit, reason: {:?}", err);
|
||||
T::Currency::deposit_creating(&deposit_account, min_balance);
|
||||
min_balance
|
||||
});
|
||||
|
||||
// Calculate the new base_deposit to store in the contract:
|
||||
// Ideally: it should be the same as the old one
|
||||
// Ideally, it should be at least 2xED (for the contract and deposit account).
|
||||
// Ideally, it should be the same as the old one
|
||||
// Ideally, it should be at least 2xED (for the contract and deposit accounts).
|
||||
// It can't be more than the `new_deposit`.
|
||||
let new_base_deposit = min(
|
||||
max(contract.storage_base_deposit, min_balance.saturating_add(min_balance)),
|
||||
@@ -223,6 +221,10 @@ impl<T: Config> Migrate for Migration<T> {
|
||||
};
|
||||
|
||||
ContractInfoOf::<T>::insert(&account, new_contract_info);
|
||||
|
||||
// Store last key for next migration step
|
||||
self.last_account = Some(account);
|
||||
|
||||
(IsFinished::No, T::WeightInfo::v10_migration_step())
|
||||
} else {
|
||||
log::debug!(target: LOG_TARGET, "Done Migrating contract info");
|
||||
@@ -240,8 +242,8 @@ impl<T: Config> Migrate for Migration<T> {
|
||||
|
||||
#[cfg(feature = "try-runtime")]
|
||||
fn post_upgrade_step(state: Vec<u8>) -> Result<(), TryRuntimeError> {
|
||||
let sample =
|
||||
<Vec<(T::AccountId, old::ContractInfo<T>)> as Decode>::decode(&mut &state[..]).unwrap();
|
||||
let sample = <Vec<(T::AccountId, old::ContractInfo<T>)> as Decode>::decode(&mut &state[..])
|
||||
.expect("pre_upgrade_step provides a valid state; qed");
|
||||
|
||||
log::debug!(target: LOG_TARGET, "Validating sample of {} contracts", sample.len());
|
||||
for (account, old_contract) in sample {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
//! See <https://github.com/paritytech/substrate/pull/13702>.
|
||||
|
||||
use crate::{
|
||||
migration::{IsFinished, Migrate},
|
||||
migration::{IsFinished, MigrationStep},
|
||||
weights::WeightInfo,
|
||||
Config, Pallet, TrieId, Weight, LOG_TARGET,
|
||||
};
|
||||
@@ -69,7 +69,7 @@ pub struct Migration<T: Config> {
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: Config> Migrate for Migration<T> {
|
||||
impl<T: Config> MigrationStep for Migration<T> {
|
||||
const VERSION: u16 = 11;
|
||||
|
||||
// It would be more correct to make our use the now removed [DeletionQueueDepth](https://github.com/paritytech/substrate/pull/13702/files#diff-70e9723e9db62816e35f6f885b6770a8449c75a6c2733e9fa7a245fe52c4656c)
|
||||
@@ -121,7 +121,8 @@ impl<T: Config> Migrate for Migration<T> {
|
||||
|
||||
#[cfg(feature = "try-runtime")]
|
||||
fn post_upgrade_step(state: Vec<u8>) -> Result<(), TryRuntimeError> {
|
||||
let len = <u32 as Decode>::decode(&mut &state[..]).unwrap();
|
||||
let len = <u32 as Decode>::decode(&mut &state[..])
|
||||
.expect("pre_upgrade_step provides a valid state; qed");
|
||||
let counter = <DeletionQueueCounter<T>>::get();
|
||||
ensure!(counter.insert_counter == len, "invalid insert counter");
|
||||
ensure!(counter.delete_counter == 0, "invalid delete counter");
|
||||
|
||||
@@ -18,17 +18,15 @@
|
||||
//! Update `CodeStorage` with the new `determinism` field.
|
||||
|
||||
use crate::{
|
||||
migration::{IsFinished, Migrate},
|
||||
migration::{IsFinished, MigrationStep},
|
||||
weights::WeightInfo,
|
||||
CodeHash, Config, Determinism, Pallet, Weight, LOG_TARGET,
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
use frame_support::{
|
||||
codec, pallet_prelude::*, storage_alias, BoundedVec, DefaultNoBound, Identity,
|
||||
};
|
||||
use frame_support::{codec, pallet_prelude::*, storage_alias, DefaultNoBound, Identity};
|
||||
#[cfg(feature = "try-runtime")]
|
||||
use sp_runtime::TryRuntimeError;
|
||||
use sp_std::{marker::PhantomData, prelude::*};
|
||||
use sp_std::prelude::*;
|
||||
|
||||
mod old {
|
||||
use super::*;
|
||||
@@ -79,11 +77,10 @@ type CodeStorage<T: Config> = StorageMap<Pallet<T>, Identity, CodeHash<T>, Prefa
|
||||
|
||||
#[derive(Encode, Decode, MaxEncodedLen, DefaultNoBound)]
|
||||
pub struct Migration<T: Config> {
|
||||
last_key: Option<BoundedVec<u8, ConstU32<256>>>,
|
||||
_phantom: PhantomData<T>,
|
||||
last_code_hash: Option<CodeHash<T>>,
|
||||
}
|
||||
|
||||
impl<T: Config> Migrate for Migration<T> {
|
||||
impl<T: Config> MigrationStep for Migration<T> {
|
||||
const VERSION: u16 = 9;
|
||||
|
||||
fn max_step_weight() -> Weight {
|
||||
@@ -91,8 +88,8 @@ impl<T: Config> Migrate for Migration<T> {
|
||||
}
|
||||
|
||||
fn step(&mut self) -> (IsFinished, Weight) {
|
||||
let mut iter = if let Some(last_key) = self.last_key.take() {
|
||||
old::CodeStorage::<T>::iter_from(last_key.to_vec())
|
||||
let mut iter = if let Some(last_key) = self.last_code_hash.take() {
|
||||
old::CodeStorage::<T>::iter_from(old::CodeStorage::<T>::hashed_key_for(last_key))
|
||||
} else {
|
||||
old::CodeStorage::<T>::iter()
|
||||
};
|
||||
@@ -108,7 +105,7 @@ impl<T: Config> Migrate for Migration<T> {
|
||||
determinism: Determinism::Enforced,
|
||||
};
|
||||
CodeStorage::<T>::insert(key, module);
|
||||
self.last_key = Some(iter.last_raw_key().to_vec().try_into().unwrap());
|
||||
self.last_code_hash = Some(key);
|
||||
(IsFinished::No, T::WeightInfo::v9_migration_step(len))
|
||||
} else {
|
||||
log::debug!(target: LOG_TARGET, "No more contracts code to migrate");
|
||||
@@ -126,8 +123,8 @@ impl<T: Config> Migrate for Migration<T> {
|
||||
|
||||
#[cfg(feature = "try-runtime")]
|
||||
fn post_upgrade_step(state: Vec<u8>) -> Result<(), TryRuntimeError> {
|
||||
let sample =
|
||||
<Vec<(CodeHash<T>, old::PrefabWasmModule)> as Decode>::decode(&mut &state[..]).unwrap();
|
||||
let sample = <Vec<(CodeHash<T>, old::PrefabWasmModule)> as Decode>::decode(&mut &state[..])
|
||||
.expect("pre_upgrade_step provides a valid state; qed");
|
||||
|
||||
log::debug!(target: LOG_TARGET, "Validating sample of {} contract codes", sample.len());
|
||||
for (code_hash, old) in sample {
|
||||
@@ -140,8 +137,6 @@ impl<T: Config> Migrate for Migration<T> {
|
||||
ensure!(module.initial == old.initial, "invalid initial");
|
||||
ensure!(module.maximum == old.maximum, "invalid maximum");
|
||||
ensure!(module.code == old.code, "invalid code");
|
||||
ensure!(module.maximum == old.maximum, "invalid maximum");
|
||||
ensure!(module.code == old.code, "invalid code");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user