Skip to content

Commit

Permalink
Fix bug parent hash on BlockV2 upgrade (polkadot-evm#570)
Browse files Browse the repository at this point in the history
* Fix bug parent hash on `BlockV2` upgrade

* BlockV0 -> BlockV2 migration utility functions
  • Loading branch information
tgmichel committed Feb 23, 2022
1 parent a9813b1 commit 70ad1ed
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 2 deletions.
1 change: 1 addition & 0 deletions frame/ethereum/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@ std = [
"fp-storage/std",
"pallet-evm/std",
]
try-runtime = [ "frame-support/try-runtime" ]
73 changes: 71 additions & 2 deletions frame/ethereum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@ use evm::ExitReason;
use fp_consensus::{PostLog, PreLog, FRONTIER_ENGINE_ID};
use fp_evm::CallOrCreateInfo;
use fp_storage::{EthereumStorageSchema, PALLET_ETHEREUM_SCHEMA};
#[cfg(feature = "try-runtime")]
use frame_support::traits::OnRuntimeUpgradeHelpersExt;
use frame_support::{
codec::{Decode, Encode},
dispatch::DispatchResultWithPostInfo,
scale_info::TypeInfo,
traits::{EnsureOrigin, Get},
traits::{EnsureOrigin, Get, PalletInfoAccess},
weights::{Pays, PostDispatchInfo, Weight},
};
use frame_system::{pallet_prelude::OriginFor, WeightInfo};
Expand Down Expand Up @@ -427,7 +429,11 @@ impl<T: Config> Pallet<T> {
let receipts_root =
ethereum::util::ordered_trie_root(receipts.iter().map(|r| rlp::encode(r)));
let partial_header = ethereum::PartialHeader {
parent_hash: Self::current_block_hash().unwrap_or_default(),
parent_hash: if block_number > U256::zero() {
BlockHash::<T>::get(block_number - 1)
} else {
H256::default()
},
beneficiary: pallet_evm::Pallet::<T>::find_author(),
state_root: T::StateRoot::get(),
receipts_root,
Expand Down Expand Up @@ -848,6 +854,69 @@ impl<T: Config> Pallet<T> {
Ok(())
}
}

pub fn migrate_block_v0_to_v2() -> Weight {
let db_weights = T::DbWeight::get();
let mut weight: Weight = db_weights.read;
let item = b"CurrentBlock";
let block_v0 = frame_support::storage::migration::get_storage_value::<ethereum::BlockV0>(
Self::name().as_bytes(),
item,
&[],
);
if let Some(block_v0) = block_v0 {
weight = weight.saturating_add(db_weights.write);
let block_v2: ethereum::BlockV2 = block_v0.into();
frame_support::storage::migration::put_storage_value::<ethereum::BlockV2>(
Self::name().as_bytes(),
item,
&[],
block_v2,
);
}
weight
}

#[cfg(feature = "try-runtime")]
pub fn pre_migrate_block_v2() -> Result<(), &'static str> {
let item = b"CurrentBlock";
let block_v0 = frame_support::storage::migration::get_storage_value::<ethereum::BlockV0>(
Self::name().as_bytes(),
item,
&[],
);
if let Some(block_v0) = block_v0 {
Self::set_temp_storage(block_v0.header.number, "number");
Self::set_temp_storage(block_v0.header.parent_hash, "parent_hash");
Self::set_temp_storage(block_v0.transactions.len() as u64, "transaction_len");
}
Ok(())
}

#[cfg(feature = "try-runtime")]
pub fn post_migrate_block_v2() -> Result<(), &'static str> {
let v0_number =
Self::get_temp_storage("number").expect("We stored a number; it should be there; qed");
let v0_parent_hash = Self::get_temp_storage("parent_hash")
.expect("We stored a parent hash; it should be there; qed");
let v0_transaction_len: u64 = Self::get_temp_storage("transaction_len")
.expect("We stored a transaction count; it should be there; qed");

let item = b"CurrentBlock";
let block_v2 = frame_support::storage::migration::get_storage_value::<ethereum::BlockV2>(
Self::name().as_bytes(),
item,
&[],
);

assert!(block_v2.is_some());

let block_v2 = block_v2.unwrap();
assert_eq!(block_v2.header.number, v0_number);
assert_eq!(block_v2.header.parent_hash, v0_parent_hash);
assert_eq!(block_v2.transactions.len() as u64, v0_transaction_len);
Ok(())
}
}

#[derive(Eq, PartialEq, Clone, RuntimeDebug)]
Expand Down

0 comments on commit 70ad1ed

Please sign in to comment.