mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-24 01:38:32 +00:00
chore: ♻️ Remove executed runtime migrations (#318)
## Summary Removes old runtime migrations that have already been executed on Stagenet and Testnet environments, reducing code complexity and maintenance burden. ## Changes ### Migration Cleanup - **Removed `evm_alias::EvmAliasMigration`** (~532 lines) - Multi-block migration that renamed the Frontier EVM pallet alias from `Evm` to `EVM` - Migrated AccountCodes, AccountCodesMetadata, and AccountStorages - **Removed `evm_chain_id::EvmChainIdMigration`** - Single-step migration that updated stored EVM chain IDs to match new configuration - Applied to testnet (55931) and stagenet (55932) ### Runtime Updates - **Simplified `MultiBlockMigrationList`** to empty tuple `()` in `runtime/common/src/migrations.rs` - **Updated all runtime configs** to use simplified migration list: - `runtime/mainnet/src/configs/mod.rs` - `runtime/stagenet/src/configs/mod.rs` - `runtime/testnet/src/configs/mod.rs` - Removed `Runtime` type parameter from migration configurations ### What Remains - `pallet_migrations` infrastructure stays in place for future migrations - Migration test file (`mainnet/tests/migrations.rs`) preserved for testing pallet administrative functions - Configuration types and constants (cursor/identifier lengths, handlers) ## Impact - **Code reduction**: 532 lines removed - **No functional change**: These migrations have already executed successfully - **Future-ready**: Migration infrastructure remains for new migrations when needed Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
This commit is contained in:
parent
72c3457183
commit
92d3c42f79
4 changed files with 40 additions and 532 deletions
|
|
@ -18,6 +18,42 @@
|
|||
//!
|
||||
//! The types and constants defined here keep the pallet configuration consistent between
|
||||
//! networks while leaving each runtime free to decide which migrations should actually run.
|
||||
//!
|
||||
//! ## Migration History
|
||||
//!
|
||||
//! This section documents migrations that have been executed and subsequently removed from the
|
||||
//! codebase. The migration framework tracks completed migrations on-chain, preventing re-execution.
|
||||
//!
|
||||
//! ### Executed Migrations (Code Removed)
|
||||
//!
|
||||
//! #### 1. EVM Pallet Alias Migration
|
||||
//! - **Migration ID**: `datahaven-evm-mbm` (version 0 → 1)
|
||||
//! - **Type**: Multi-block stepped migration
|
||||
//! - **Original PR**: [#213](https://github.com/datahaven-xyz/datahaven/pull/213)
|
||||
//! - **Intent**: Fixed `eth_getCode` and other Ethereum RPC calls by renaming the pallet_evm
|
||||
//! FRAME alias from `Evm` to `EVM`. Frontier's `StorageOverrideHandler` hardcodes the storage
|
||||
//! prefix as `twox_128("EVM")`, but our runtimes used `Evm`, causing all contract bytecode
|
||||
//! lookups to fail. This migration realigned the storage prefix with Frontier's expectations.
|
||||
//! - **Storage Migrated**:
|
||||
//! - `Evm::AccountCodes` → `EVM::AccountCodes`
|
||||
//! - `Evm::AccountCodesMetadata` → `EVM::AccountCodesMetadata`
|
||||
//! - `Evm::AccountStorages` → `EVM::AccountStorages`
|
||||
//! - **Execution**: Successfully executed on Testnet and Stagenet (39 keys migrated, <0.1% block weight)
|
||||
//! - **Removed**: 2025-01 ([PR #318](https://github.com/datahaven-xyz/datahaven/pull/318))
|
||||
//!
|
||||
//! #### 2. EVM Chain ID Migration
|
||||
//! - **Migration ID**: `dh-evm-chain-id-v1` (version 0 → 1)
|
||||
//! - **Type**: Single-step migration
|
||||
//! - **Original PR**: [#280](https://github.com/datahaven-xyz/datahaven/pull/280)
|
||||
//! - **Intent**: Updated chain IDs for all three DataHaven environments to their final assigned
|
||||
//! values. The stored EVM chain ID in `pallet_evm_chain_id::ChainId` was migrated to match
|
||||
//! the configured constants after chain ID assignments were finalized.
|
||||
//! - **Networks**:
|
||||
//! - Mainnet: Chain ID 55930 (no migration needed, set at genesis)
|
||||
//! - Testnet: Migrated to chain ID 55931
|
||||
//! - Stagenet: Migrated to chain ID 55932
|
||||
//! - **Execution**: Successfully executed on Testnet and Stagenet
|
||||
//! - **Removed**: 2025-01 ([PR #318](https://github.com/datahaven-xyz/datahaven/pull/318))
|
||||
|
||||
use frame_support::pallet_prelude::*;
|
||||
|
||||
|
|
@ -36,7 +72,7 @@ pub type MigrationIdentifierMaxLen = ConstU32<MIGRATION_IDENTIFIER_MAX_LEN>;
|
|||
/// The tuple starts empty and can be extended with concrete migrations over time. Keeping it in a
|
||||
/// shared module reduces duplication once we coordinate migrations across networks.
|
||||
#[cfg(not(feature = "runtime-benchmarks"))]
|
||||
pub type MultiBlockMigrationList<T> = (evm_alias::EvmAliasMigration<T>,);
|
||||
pub type MultiBlockMigrationList = ();
|
||||
|
||||
/// During benchmarking we switch to the pallet-provided mocked migrations to guarantee success.
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
|
|
@ -58,519 +94,3 @@ pub type FailedMigrationHandler<SafeMode> =
|
|||
SafeMode,
|
||||
frame_support::migrations::FreezeChainOnFailedMigration,
|
||||
>;
|
||||
|
||||
/// Multi-block migration for updating the EVM chain ID to the new value.
|
||||
pub mod evm_chain_id {
|
||||
use core::marker::PhantomData;
|
||||
use frame_support::{
|
||||
migrations::{MigrationId, SteppedMigration, SteppedMigrationError},
|
||||
pallet_prelude::*,
|
||||
weights::WeightMeter,
|
||||
};
|
||||
|
||||
#[cfg(feature = "try-runtime")]
|
||||
use codec::Encode;
|
||||
|
||||
/// Multi-block migration that updates the stored EVM chain ID to match the new configuration.
|
||||
pub struct EvmChainIdMigration<T, const NEW_CHAIN_ID: u64>(PhantomData<T>);
|
||||
|
||||
impl<T, const NEW_CHAIN_ID: u64> SteppedMigration for EvmChainIdMigration<T, NEW_CHAIN_ID>
|
||||
where
|
||||
T: pallet_evm_chain_id::Config,
|
||||
{
|
||||
type Cursor = ();
|
||||
type Identifier = MigrationId<20>;
|
||||
|
||||
fn id() -> Self::Identifier {
|
||||
MigrationId {
|
||||
pallet_id: *b"dh-evm-chain-id-v1 ",
|
||||
version_from: 0,
|
||||
version_to: 1,
|
||||
}
|
||||
}
|
||||
|
||||
fn step(
|
||||
cursor: Option<Self::Cursor>,
|
||||
meter: &mut WeightMeter,
|
||||
) -> Result<Option<Self::Cursor>, SteppedMigrationError> {
|
||||
// This migration completes in a single step
|
||||
if cursor.is_some() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let required = T::DbWeight::get().reads_writes(1, 1);
|
||||
if meter.try_consume(required).is_err() {
|
||||
return Err(SteppedMigrationError::InsufficientWeight { required });
|
||||
}
|
||||
|
||||
log::info!(
|
||||
"🔄 [EVM Chain ID Migration] Updating chain ID to {}",
|
||||
NEW_CHAIN_ID
|
||||
);
|
||||
|
||||
// Update the chain ID storage
|
||||
pallet_evm_chain_id::ChainId::<T>::put(NEW_CHAIN_ID);
|
||||
|
||||
log::info!(
|
||||
"✅ [EVM Chain ID Migration] Successfully updated chain ID to {}",
|
||||
NEW_CHAIN_ID
|
||||
);
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[cfg(feature = "try-runtime")]
|
||||
fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
|
||||
let old_chain_id = pallet_evm_chain_id::ChainId::<T>::get();
|
||||
log::info!(
|
||||
"📋 [EVM Chain ID Migration] Current chain ID: {}",
|
||||
old_chain_id
|
||||
);
|
||||
Ok(old_chain_id.encode())
|
||||
}
|
||||
|
||||
#[cfg(feature = "try-runtime")]
|
||||
fn post_upgrade(state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
|
||||
use codec::Decode;
|
||||
|
||||
let old_chain_id =
|
||||
u64::decode(&mut &state[..]).map_err(|_| "Failed to decode old chain ID")?;
|
||||
let new_chain_id = pallet_evm_chain_id::ChainId::<T>::get();
|
||||
|
||||
log::info!(
|
||||
"🔍 [EVM Chain ID Migration] Chain ID updated from {} to {}",
|
||||
old_chain_id,
|
||||
new_chain_id
|
||||
);
|
||||
|
||||
if new_chain_id != NEW_CHAIN_ID {
|
||||
return Err(sp_runtime::TryRuntimeError::Other(
|
||||
"Chain ID was not updated correctly",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Multi-block migration for renaming the EVM pallet alias.
|
||||
pub mod evm_alias {
|
||||
use core::marker::PhantomData;
|
||||
use frame_support::{
|
||||
migrations::{MigrationId, SteppedMigration, SteppedMigrationError},
|
||||
pallet_prelude::*,
|
||||
weights::WeightMeter,
|
||||
BoundedVec, StorageHasher,
|
||||
};
|
||||
use sp_io::storage;
|
||||
use sp_std::{convert::TryFrom, vec::Vec};
|
||||
|
||||
#[cfg(feature = "try-runtime")]
|
||||
use sp_std::collections::btree_map::BTreeMap;
|
||||
|
||||
/// Multi-block migration that renames the Frontier EVM pallet alias from `Evm` to `EVM`.
|
||||
pub struct EvmAliasMigration<T>(PhantomData<T>);
|
||||
|
||||
impl<T> SteppedMigration for EvmAliasMigration<T>
|
||||
where
|
||||
T: pallet_evm::Config,
|
||||
{
|
||||
type Cursor = BoundedVec<u8, ConstU32<128>>;
|
||||
type Identifier = MigrationId<17>;
|
||||
|
||||
fn id() -> Self::Identifier {
|
||||
MigrationId {
|
||||
pallet_id: *b"datahaven-evm-mbm",
|
||||
version_from: 0,
|
||||
version_to: 1,
|
||||
}
|
||||
}
|
||||
|
||||
fn step(
|
||||
cursor: Option<Self::Cursor>,
|
||||
meter: &mut WeightMeter,
|
||||
) -> Result<Option<Self::Cursor>, SteppedMigrationError> {
|
||||
if cursor.is_none() {
|
||||
log::info!(
|
||||
"🚀 [EVM Migration] Starting pallet alias migration from 'Evm' to 'EVM'"
|
||||
);
|
||||
}
|
||||
|
||||
let old_prefix = Twox128::hash(b"Evm");
|
||||
let new_prefix = Twox128::hash(b"EVM");
|
||||
let mut current_key: Vec<u8> = cursor
|
||||
.map(Into::into)
|
||||
.unwrap_or_else(|| old_prefix.to_vec());
|
||||
let mut processed = 0u32;
|
||||
let required = T::DbWeight::get().reads_writes(1, 2);
|
||||
|
||||
loop {
|
||||
let next_key = match storage::next_key(¤t_key) {
|
||||
Some(next) if next.starts_with(&old_prefix) => next,
|
||||
_ => {
|
||||
log::info!(
|
||||
"✅ [EVM Migration] Completed! Processed {} keys in this step",
|
||||
processed
|
||||
);
|
||||
return Ok(None);
|
||||
}
|
||||
};
|
||||
|
||||
if meter.try_consume(required).is_err() {
|
||||
if processed == 0 {
|
||||
log::warn!(
|
||||
"⚠️ [EVM Migration] Insufficient weight for even one key migration"
|
||||
);
|
||||
return Err(SteppedMigrationError::InsufficientWeight { required });
|
||||
}
|
||||
log::info!(
|
||||
"⏸️ [EVM Migration] Pausing after migrating {} keys (weight limit reached)",
|
||||
processed
|
||||
);
|
||||
return BoundedVec::try_from(current_key)
|
||||
.map(Some)
|
||||
.map_err(|_| SteppedMigrationError::Failed);
|
||||
}
|
||||
|
||||
if let Some(value) = storage::get(&next_key) {
|
||||
let mut new_key = Vec::with_capacity(next_key.len());
|
||||
new_key.extend_from_slice(&new_prefix);
|
||||
new_key.extend_from_slice(&next_key[16..]);
|
||||
storage::set(&new_key, &value);
|
||||
}
|
||||
storage::clear(&next_key);
|
||||
|
||||
processed = processed.saturating_add(1);
|
||||
current_key = next_key;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "try-runtime")]
|
||||
fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
|
||||
use codec::Encode;
|
||||
|
||||
let storage_prefix = |item: &[u8]| {
|
||||
let mut key = [0u8; 32];
|
||||
key[0..16].copy_from_slice(&Twox128::hash(b"Evm"));
|
||||
key[16..32].copy_from_slice(&Twox128::hash(item));
|
||||
key
|
||||
};
|
||||
|
||||
let mut counts = BTreeMap::new();
|
||||
|
||||
for name in [
|
||||
b"AccountCodes" as &[u8],
|
||||
b"AccountCodesMetadata",
|
||||
b"AccountStorages",
|
||||
] {
|
||||
let count = count_keys(&storage_prefix(name));
|
||||
counts.insert(name.to_vec(), count.encode());
|
||||
}
|
||||
|
||||
Ok(counts.encode())
|
||||
}
|
||||
|
||||
#[cfg(feature = "try-runtime")]
|
||||
fn post_upgrade(state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
|
||||
use codec::Decode;
|
||||
|
||||
let snapshot: BTreeMap<Vec<u8>, Vec<u8>> =
|
||||
Decode::decode(&mut &state[..]).expect("Failed to decode snapshot");
|
||||
|
||||
let old_storage = |item: &[u8]| {
|
||||
let mut key = [0u8; 32];
|
||||
key[0..16].copy_from_slice(&Twox128::hash(b"Evm"));
|
||||
key[16..32].copy_from_slice(&Twox128::hash(item));
|
||||
key
|
||||
};
|
||||
|
||||
let new_storage = |item: &[u8]| {
|
||||
let mut key = [0u8; 32];
|
||||
key[0..16].copy_from_slice(&Twox128::hash(b"EVM"));
|
||||
key[16..32].copy_from_slice(&Twox128::hash(item));
|
||||
key
|
||||
};
|
||||
|
||||
for name in [
|
||||
b"AccountCodes" as &[u8],
|
||||
b"AccountCodesMetadata",
|
||||
b"AccountStorages",
|
||||
] {
|
||||
let old_count = count_keys(&old_storage(name));
|
||||
assert_eq!(old_count, 0, "Old Evm prefix still present after migration");
|
||||
|
||||
let expected = snapshot
|
||||
.get(name)
|
||||
.and_then(|v| u32::decode(&mut &v[..]).ok())
|
||||
.unwrap_or(0);
|
||||
let actual = count_keys(&new_storage(name));
|
||||
|
||||
assert_eq!(expected, actual, "Migrated entry count mismatch");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to count storage keys with a given prefix.
|
||||
#[cfg(any(feature = "try-runtime", test))]
|
||||
pub(crate) fn count_keys(prefix: &[u8]) -> u32 {
|
||||
let mut count = 0u32;
|
||||
let mut cursor = prefix.to_vec();
|
||||
loop {
|
||||
match storage::next_key(&cursor) {
|
||||
Some(next) if next.starts_with(prefix) => {
|
||||
count = count.saturating_add(1);
|
||||
cursor = next;
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
count
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::evm_alias::{count_keys, EvmAliasMigration};
|
||||
use codec::Encode;
|
||||
use frame_support::{
|
||||
derive_impl,
|
||||
migrations::SteppedMigration,
|
||||
parameter_types,
|
||||
weights::{constants::RocksDbWeight, Weight, WeightMeter},
|
||||
StorageHasher, Twox128,
|
||||
};
|
||||
use pallet_evm::AccountCodes;
|
||||
use sp_core::{H160, H256, U256};
|
||||
use sp_io::storage;
|
||||
use sp_runtime::BuildStorage;
|
||||
use sp_std::vec;
|
||||
|
||||
frame_support::construct_runtime!(
|
||||
pub enum TestRuntime {
|
||||
System: frame_system::{Pallet, Call, Config<T>, Storage, Event<T>},
|
||||
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
|
||||
Timestamp: pallet_timestamp::{Pallet, Call, Storage},
|
||||
EVM: pallet_evm::{Pallet, Call, Storage, Config<T>, Event<T>},
|
||||
EvmChainId: pallet_evm_chain_id::{Pallet, Storage},
|
||||
}
|
||||
);
|
||||
|
||||
parameter_types! {
|
||||
pub const BlockHashCount: u64 = 250;
|
||||
pub BlockWeights: frame_system::limits::BlockWeights =
|
||||
frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, 0));
|
||||
}
|
||||
|
||||
#[derive_impl(frame_system::config_preludes::SolochainDefaultConfig as frame_system::DefaultConfig)]
|
||||
impl frame_system::Config for TestRuntime {
|
||||
type Nonce = u64;
|
||||
type Block = frame_system::mocking::MockBlock<Self>;
|
||||
type BlockHashCount = BlockHashCount;
|
||||
type AccountData = pallet_balances::AccountData<u64>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ExistentialDeposit: u64 = 0;
|
||||
}
|
||||
|
||||
#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)]
|
||||
impl pallet_balances::Config for TestRuntime {
|
||||
type RuntimeHoldReason = ();
|
||||
type Balance = u64;
|
||||
type ExistentialDeposit = ExistentialDeposit;
|
||||
type AccountStore = System;
|
||||
}
|
||||
|
||||
#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig)]
|
||||
impl pallet_timestamp::Config for TestRuntime {}
|
||||
|
||||
parameter_types! {
|
||||
pub MockPrecompiles: MockPrecompileSet = MockPrecompileSet;
|
||||
}
|
||||
|
||||
#[derive_impl(pallet_evm::config_preludes::TestDefaultConfig)]
|
||||
impl pallet_evm::Config for TestRuntime {
|
||||
type AccountProvider = pallet_evm::FrameSystemAccountProvider<Self>;
|
||||
type FeeCalculator = FixedGasPrice;
|
||||
type BlockHashMapping = pallet_evm::SubstrateBlockHashMapping<Self>;
|
||||
type Currency = Balances;
|
||||
type Runner = pallet_evm::runner::stack::Runner<Self>;
|
||||
type Timestamp = Timestamp;
|
||||
type PrecompilesType = MockPrecompileSet;
|
||||
type PrecompilesValue = MockPrecompiles;
|
||||
}
|
||||
|
||||
impl pallet_evm_chain_id::Config for TestRuntime {}
|
||||
|
||||
pub struct FixedGasPrice;
|
||||
impl pallet_evm::FeeCalculator for FixedGasPrice {
|
||||
fn min_gas_price() -> (U256, Weight) {
|
||||
(1_000_000_000u128.into(), Weight::from_parts(1_000, 0))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MockPrecompileSet;
|
||||
impl pallet_evm::PrecompileSet for MockPrecompileSet {
|
||||
fn execute(
|
||||
&self,
|
||||
_handle: &mut impl pallet_evm::PrecompileHandle,
|
||||
) -> Option<pallet_evm::PrecompileResult> {
|
||||
None
|
||||
}
|
||||
|
||||
fn is_precompile(&self, _address: H160, _gas: u64) -> pallet_evm::IsPrecompileResult {
|
||||
pallet_evm::IsPrecompileResult::Answer {
|
||||
is_precompile: false,
|
||||
extra_cost: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn old_storage_prefix(item: &[u8]) -> [u8; 32] {
|
||||
let mut key = [0u8; 32];
|
||||
key[0..16].copy_from_slice(&Twox128::hash(b"Evm"));
|
||||
key[16..32].copy_from_slice(&Twox128::hash(item));
|
||||
key
|
||||
}
|
||||
|
||||
fn raw_key(storage_name: &[u8], address: H160, index: Option<H256>) -> Vec<u8> {
|
||||
let mut key = old_storage_prefix(storage_name).to_vec();
|
||||
key.extend_from_slice(&sp_io::hashing::blake2_128(&address.encode()));
|
||||
key.extend_from_slice(address.as_bytes());
|
||||
if let Some(idx) = index {
|
||||
key.extend_from_slice(&sp_io::hashing::blake2_128(&idx.encode()));
|
||||
key.extend_from_slice(idx.as_bytes());
|
||||
}
|
||||
key
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multi_block_evm_alias_migration_moves_all_entries() {
|
||||
let mut storage = frame_system::GenesisConfig::<TestRuntime>::default()
|
||||
.build_storage()
|
||||
.unwrap();
|
||||
pallet_balances::GenesisConfig::<TestRuntime>::default()
|
||||
.assimilate_storage(&mut storage)
|
||||
.unwrap();
|
||||
let mut ext = sp_io::TestExternalities::new(storage);
|
||||
ext.execute_with(|| {
|
||||
let addresses: Vec<H160> = (1u64..=3).map(H160::from_low_u64_be).collect();
|
||||
|
||||
for (idx, &address) in addresses.iter().enumerate() {
|
||||
storage::set(
|
||||
&raw_key(b"AccountCodes", address, None),
|
||||
&vec![idx as u8; 3].encode(),
|
||||
);
|
||||
storage::set(
|
||||
&raw_key(b"AccountCodesMetadata", address, None),
|
||||
&(42u64 + idx as u64, H256::repeat_byte(idx as u8)).encode(),
|
||||
);
|
||||
storage::set(
|
||||
&raw_key(
|
||||
b"AccountStorages",
|
||||
address,
|
||||
Some(H256::repeat_byte(0xAA + idx as u8)),
|
||||
),
|
||||
&H256::repeat_byte(idx as u8).encode(),
|
||||
);
|
||||
}
|
||||
|
||||
let mut cursor = None;
|
||||
loop {
|
||||
let mut meter = WeightMeter::with_limit(RocksDbWeight::get().reads_writes(1, 2));
|
||||
match EvmAliasMigration::<TestRuntime>::step(cursor, &mut meter) {
|
||||
Ok(None) => break,
|
||||
Ok(Some(next)) => cursor = Some(next),
|
||||
Err(err) => panic!("migration failed: {:?}", err),
|
||||
}
|
||||
}
|
||||
|
||||
for address in addresses {
|
||||
assert!(!AccountCodes::<TestRuntime>::get(address).is_empty());
|
||||
}
|
||||
|
||||
assert_eq!(count_keys(&old_storage_prefix(b"AccountCodes")[..]), 0);
|
||||
assert_eq!(
|
||||
count_keys(&old_storage_prefix(b"AccountCodesMetadata")[..]),
|
||||
0
|
||||
);
|
||||
assert_eq!(count_keys(&old_storage_prefix(b"AccountStorages")[..]), 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evm_chain_id_migration_updates_storage() {
|
||||
use super::evm_chain_id::EvmChainIdMigration;
|
||||
|
||||
let mut storage = frame_system::GenesisConfig::<TestRuntime>::default()
|
||||
.build_storage()
|
||||
.unwrap();
|
||||
pallet_balances::GenesisConfig::<TestRuntime>::default()
|
||||
.assimilate_storage(&mut storage)
|
||||
.unwrap();
|
||||
let mut ext = sp_io::TestExternalities::new(storage);
|
||||
|
||||
ext.execute_with(|| {
|
||||
// Set an old chain ID value
|
||||
const OLD_CHAIN_ID: u64 = 12345;
|
||||
const NEW_CHAIN_ID: u64 = 55931;
|
||||
|
||||
pallet_evm_chain_id::ChainId::<TestRuntime>::put(OLD_CHAIN_ID);
|
||||
assert_eq!(
|
||||
pallet_evm_chain_id::ChainId::<TestRuntime>::get(),
|
||||
OLD_CHAIN_ID
|
||||
);
|
||||
|
||||
// Run the migration
|
||||
let mut meter = WeightMeter::with_limit(Weight::MAX);
|
||||
let result = EvmChainIdMigration::<TestRuntime, NEW_CHAIN_ID>::step(None, &mut meter);
|
||||
|
||||
// Verify migration succeeded and completed in one step
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(result.unwrap(), None);
|
||||
|
||||
// Verify the chain ID was updated
|
||||
assert_eq!(
|
||||
pallet_evm_chain_id::ChainId::<TestRuntime>::get(),
|
||||
NEW_CHAIN_ID
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn evm_chain_id_migration_is_idempotent() {
|
||||
use super::evm_chain_id::EvmChainIdMigration;
|
||||
|
||||
let mut storage = frame_system::GenesisConfig::<TestRuntime>::default()
|
||||
.build_storage()
|
||||
.unwrap();
|
||||
pallet_balances::GenesisConfig::<TestRuntime>::default()
|
||||
.assimilate_storage(&mut storage)
|
||||
.unwrap();
|
||||
let mut ext = sp_io::TestExternalities::new(storage);
|
||||
|
||||
ext.execute_with(|| {
|
||||
const NEW_CHAIN_ID: u64 = 55932;
|
||||
|
||||
// Run the migration twice
|
||||
let mut meter = WeightMeter::with_limit(Weight::MAX);
|
||||
let result1 = EvmChainIdMigration::<TestRuntime, NEW_CHAIN_ID>::step(None, &mut meter);
|
||||
|
||||
let mut meter = WeightMeter::with_limit(Weight::MAX);
|
||||
let result2 = EvmChainIdMigration::<TestRuntime, NEW_CHAIN_ID>::step(None, &mut meter);
|
||||
|
||||
// Both should succeed
|
||||
assert!(result1.is_ok());
|
||||
assert!(result2.is_ok());
|
||||
|
||||
// Chain ID should be set correctly
|
||||
assert_eq!(
|
||||
pallet_evm_chain_id::ChainId::<TestRuntime>::get(),
|
||||
NEW_CHAIN_ID
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -848,7 +848,7 @@ impl pallet_parameters::Config for Runtime {
|
|||
impl pallet_migrations::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
#[cfg(not(feature = "runtime-benchmarks"))]
|
||||
type Migrations = datahaven_runtime_common::migrations::MultiBlockMigrationList<Runtime>;
|
||||
type Migrations = datahaven_runtime_common::migrations::MultiBlockMigrationList;
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
type Migrations = datahaven_runtime_common::migrations::MultiBlockMigrationList;
|
||||
type CursorMaxLen = MigrationCursorMaxLen;
|
||||
|
|
|
|||
|
|
@ -845,13 +845,7 @@ impl pallet_parameters::Config for Runtime {
|
|||
impl pallet_migrations::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
#[cfg(not(feature = "runtime-benchmarks"))]
|
||||
type Migrations = (
|
||||
datahaven_runtime_common::migrations::MultiBlockMigrationList<Runtime>,
|
||||
datahaven_runtime_common::migrations::evm_chain_id::EvmChainIdMigration<
|
||||
Runtime,
|
||||
EVM_CHAIN_ID,
|
||||
>,
|
||||
);
|
||||
type Migrations = datahaven_runtime_common::migrations::MultiBlockMigrationList;
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
type Migrations = datahaven_runtime_common::migrations::MultiBlockMigrationList;
|
||||
type CursorMaxLen = MigrationCursorMaxLen;
|
||||
|
|
|
|||
|
|
@ -848,13 +848,7 @@ impl pallet_parameters::Config for Runtime {
|
|||
impl pallet_migrations::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
#[cfg(not(feature = "runtime-benchmarks"))]
|
||||
type Migrations = (
|
||||
datahaven_runtime_common::migrations::MultiBlockMigrationList<Runtime>,
|
||||
datahaven_runtime_common::migrations::evm_chain_id::EvmChainIdMigration<
|
||||
Runtime,
|
||||
EVM_CHAIN_ID,
|
||||
>,
|
||||
);
|
||||
type Migrations = datahaven_runtime_common::migrations::MultiBlockMigrationList;
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
type Migrations = datahaven_runtime_common::migrations::MultiBlockMigrationList;
|
||||
type CursorMaxLen = MigrationCursorMaxLen;
|
||||
|
|
|
|||
Loading…
Reference in a new issue