Skip to content

fix(contracts): migrate CodeInfoOf<T> from Twox64Concat hashing to Identity as defined in pallet-contracts #1200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion bin/collator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "astar-collator"
version = "5.33.0"
version = "5.33.1"
description = "Astar collator implementation in Rust."
build = "build.rs"
default-run = "astar-collator"
Expand Down
4 changes: 4 additions & 0 deletions primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ xcm-executor = { workspace = true }
# ORML dependencies
orml-traits = { workspace = true }

pallet-contracts = { workspace = true }

# Frontier dependencies
pallet-evm = { workspace = true }

Expand Down Expand Up @@ -67,8 +69,10 @@ std = [
"fp-evm/std",
"pallet-assets/std",
"pallet-evm/std",
"pallet-contracts/std",
"pallet-evm-precompile-assets-erc20/std",
"pallet-evm-precompile-dispatch/std",
"sp-arithmetic/std",
]
runtime-benchmarks = ["xcm-builder/runtime-benchmarks", "pallet-assets/runtime-benchmarks"]
try-runtime = ["pallet-contracts/try-runtime"]
3 changes: 3 additions & 0 deletions primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pub mod testing;
/// Oracle & price primitives.
pub mod oracle;

/// Common Migrations
pub mod migrations;

/// Benchmark primitives
#[cfg(feature = "runtime-benchmarks")]
pub mod benchmarks;
Expand Down
157 changes: 157 additions & 0 deletions primitives/src/migrations/contract_v12_fix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// This file is part of Astar.

// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later

// Astar is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Astar is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Astar. If not, see <http://www.gnu.org/licenses/>.

use frame_support::{
pallet_prelude::*, storage_alias, traits::fungible::Inspect, DefaultNoBound, Identity,
};
use pallet_contracts::{
migration::{IsFinished, MigrationStep},
weights::WeightInfo,
Config, Determinism, Pallet,
};
use parity_scale_codec::{Decode, Encode};
#[cfg(feature = "try-runtime")]
use sp_runtime::TryRuntimeError;
use sp_std::marker::PhantomData;

const LOG_TARGET: &str = "runtime::contracts";

type BalanceOf<T> =
<<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
type CodeHash<T> = <T as frame_system::Config>::Hash;
type CodeVec<T> = BoundedVec<u8, <T as Config>::MaxCodeLen>;

mod old {
use super::*;

#[storage_alias]
pub type CodeInfoOf<T: Config> = StorageMap<Pallet<T>, Twox64Concat, CodeHash<T>, CodeInfo<T>>;
}

#[derive(Encode, Decode, scale_info::TypeInfo, MaxEncodedLen)]
#[codec(mel_bound())]
#[scale_info(skip_type_params(T))]
pub struct CodeInfo<T: Config> {
owner: AccountIdOf<T>,
#[codec(compact)]
deposit: BalanceOf<T>,
#[codec(compact)]
refcount: u64,
determinism: Determinism,
code_len: u32,
}

#[storage_alias]
pub type CodeInfoOf<T: Config> = StorageMap<Pallet<T>, Identity, CodeHash<T>, CodeInfo<T>>;

#[storage_alias]
pub type PristineCode<T: Config> = StorageMap<Pallet<T>, Identity, CodeHash<T>, CodeVec<T>>;

#[derive(Encode, Decode, MaxEncodedLen, DefaultNoBound)]
pub struct Migration<T: Config> {
last_code_hash: Option<CodeHash<T>>,
_phantom: PhantomData<T>,
}

/// Logic as follows,
/// Since we need to modifiy `CodeInfoOf` mapping we cannot use `iter()` or `drain()` on it as
/// that will be undefined behaviour, so we are iterating over keys of `PristineCode` mappings
/// which are code hashes.
///
/// Migration Weights: Reusing v12 migration weights as most heavy operation which is moving
/// code info is same.
impl<T: Config> MigrationStep for Migration<T> {
const VERSION: u16 = 15;

fn max_step_weight() -> Weight {
T::WeightInfo::v12_migration_step(T::MaxCodeLen::get())
}

fn step(&mut self) -> (IsFinished, Weight) {
let mut iter = if let Some(last_key) = self.last_code_hash.take() {
PristineCode::<T>::iter_keys_from(PristineCode::<T>::hashed_key_for(last_key))
} else {
PristineCode::<T>::iter_keys()
};

if let Some(code_hash) = iter.next() {
if let Some(code_info) = old::CodeInfoOf::<T>::take(code_hash) {
log::debug!(
target: LOG_TARGET,
"Migrating CodeInfoOf for code_hash {:?}",
code_hash
);

let code_len = code_info.code_len;

CodeInfoOf::<T>::insert(code_hash, code_info);

self.last_code_hash = Some(code_hash);
(IsFinished::No, T::WeightInfo::v12_migration_step(code_len))
} else {
log::warn!(
target: LOG_TARGET,
"No CodeInfo found for code_hash {:?}, maybe new contract?",
code_hash
);
// old CodeInfo not found, it's newly deployed contract
self.last_code_hash = Some(code_hash);
(IsFinished::No, T::WeightInfo::v12_migration_step(0))
}
} else {
log::debug!(target: LOG_TARGET, "No more CodeInfo to migrate");
(IsFinished::Yes, T::WeightInfo::v12_migration_step(0))
}
}

#[cfg(feature = "try-runtime")]
fn pre_upgrade_step() -> Result<sp_std::vec::Vec<u8>, TryRuntimeError> {
let len = 100;
let sample: sp_std::vec::Vec<_> = old::CodeInfoOf::<T>::iter_keys().take(len).collect();
log::debug!(
target: LOG_TARGET,
"Taking sample of {} CodeInfoOf(s)",
sample.len()
);

Ok(sample.encode())
}

#[cfg(feature = "try-runtime")]
fn post_upgrade_step(state: sp_std::vec::Vec<u8>) -> Result<(), TryRuntimeError> {
let state = <sp_std::vec::Vec<CodeHash<T>> as Decode>::decode(&mut &state[..]).unwrap();

log::debug!(
target: LOG_TARGET,
"Validating state of {} Codeinfo(s)",
state.len()
);
for hash in state {
ensure!(
old::CodeInfoOf::<T>::get(&hash).is_none(),
"Old CodeInfoFor is not none!"
);
let _ = CodeInfoOf::<T>::get(&hash).expect(
scale_info::prelude::format!("CodeInfo for code_hash {:?} not found!", hash)
.as_str(),
);
}
Ok(())
}
}
35 changes: 35 additions & 0 deletions primitives/src/migrations/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// This file is part of Astar.

// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later

// Astar is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Astar is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Astar. If not, see <http://www.gnu.org/licenses/>.

use frame_support::traits::{OnRuntimeUpgrade, StorageVersion};
use frame_support::weights::Weight;
use sp_core::Get;
use sp_std::marker::PhantomData;

pub mod contract_v12_fix;

pub struct ForceContractsVersion<T: pallet_contracts::Config, const V: u16> {
_phantom: PhantomData<T>,
}

impl<T: pallet_contracts::Config, const V: u16> OnRuntimeUpgrade for ForceContractsVersion<T, V> {
fn on_runtime_upgrade() -> Weight {
StorageVersion::new(V).put::<pallet_contracts::Pallet<T>>();
<T as frame_system::Config>::DbWeight::get().reads_writes(1, 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a big deal, but isn't this a single write only?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right, I'l change this

}
}
2 changes: 1 addition & 1 deletion runtime/astar/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "astar-runtime"
version = "5.33.0"
version = "5.33.1"
build = "build.rs"
authors.workspace = true
edition.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion runtime/astar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("astar"),
impl_name: create_runtime_str!("astar"),
authoring_version: 1,
spec_version: 81,
spec_version: 82,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 2,
Expand Down
2 changes: 1 addition & 1 deletion runtime/local/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "local-runtime"
version = "5.33.0"
version = "5.33.1"
build = "build.rs"
authors.workspace = true
edition.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion runtime/shibuya/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "shibuya-runtime"
version = "5.33.0"
version = "5.33.1"
build = "build.rs"
authors.workspace = true
edition.workspace = true
Expand Down
14 changes: 6 additions & 8 deletions runtime/shibuya/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("shibuya"),
impl_name: create_runtime_str!("shibuya"),
authoring_version: 1,
spec_version: 123,
spec_version: 124,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 2,
Expand Down Expand Up @@ -713,12 +713,7 @@ impl pallet_contracts::Config for Runtime {
type CodeHashLockupDepositPercent = CodeHashLockupDepositPercent;
type Debug = ();
type Environment = ();
type Migrations = (
pallet_contracts::migration::v12::Migration<Runtime, Balances>,
pallet_contracts::migration::v13::Migration<Runtime>,
pallet_contracts::migration::v14::Migration<Runtime, Balances>,
pallet_contracts::migration::v15::Migration<Runtime>,
);
type Migrations = (astar_primitives::migrations::contract_v12_fix::Migration<Runtime>,);
}

// These values are based on the Astar 2.0 Tokenomics Modeling report.
Expand Down Expand Up @@ -1371,7 +1366,10 @@ pub type Executive = frame_executive::Executive<
/// All migrations that will run on the next runtime upgrade.
///
/// Once done, migrations should be removed from the tuple.
pub type Migrations = (pallet_contracts::Migration<Runtime>,);
pub type Migrations = (
astar_primitives::migrations::ForceContractsVersion<Runtime, 14>,
pallet_contracts::Migration<Runtime>,
);

type EventRecord = frame_system::EventRecord<
<Runtime as frame_system::Config>::RuntimeEvent,
Expand Down
3 changes: 2 additions & 1 deletion runtime/shiden/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "shiden-runtime"
version = "5.33.0"
version = "5.33.1"
build = "build.rs"
authors.workspace = true
edition.workspace = true
Expand Down Expand Up @@ -239,6 +239,7 @@ runtime-benchmarks = [
"pallet-dynamic-evm-base-fee/runtime-benchmarks",
]
try-runtime = [
"astar-primitives/try-runtime",
"fp-self-contained/try-runtime",
"log",
"frame-try-runtime/try-runtime",
Expand Down
Loading
Loading