diff --git a/Cargo.lock b/Cargo.lock index 3956b012f64d4..ae446c1f38fdd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13320,6 +13320,7 @@ dependencies = [ "sp-io", "sp-keystore", "sp-runtime", + "sp-state-machine", "sp-tracing 16.0.0", "sp-version", "substrate-bn", diff --git a/prdoc/pr_10297.prdoc b/prdoc/pr_10297.prdoc new file mode 100644 index 0000000000000..18f5206493f5d --- /dev/null +++ b/prdoc/pr_10297.prdoc @@ -0,0 +1,10 @@ +title: "pallet_revive: use real storage for block number when building the eth genesis block" +doc: +- audience: Runtime Dev + description: |- + When building the eth genesis block, query the real storage item that stores the block number instead of using zero. + If the chainspec does not customise it, it will remain zeroed. Was previously fixed in https://github.com/paritytech/polkadot-sdk/pull/10225 + and regression introduced in https://github.com/paritytech/polkadot-sdk/pull/10271. Adds a unit test and comment to prevent further regressions. +crates: +- name: pallet-revive + bump: patch diff --git a/substrate/frame/revive/Cargo.toml b/substrate/frame/revive/Cargo.toml index 3c655612e490c..d51d6db753546 100644 --- a/substrate/frame/revive/Cargo.toml +++ b/substrate/frame/revive/Cargo.toml @@ -82,6 +82,7 @@ pallet-timestamp = { workspace = true, default-features = true } pallet-utility = { workspace = true, default-features = true } proptest = { workspace = true } sp-keystore = { workspace = true, default-features = true } +sp-state-machine = { workspace = true } sp-tracing = { workspace = true, default-features = true } [features] @@ -127,6 +128,7 @@ std = [ "sp-io/std", "sp-keystore/std", "sp-runtime/std", + "sp-state-machine/std", "sp-version/std", "subxt-signer", ] diff --git a/substrate/frame/revive/src/lib.rs b/substrate/frame/revive/src/lib.rs index e8c9c638bc59c..3b6f884711f7a 100644 --- a/substrate/frame/revive/src/lib.rs +++ b/substrate/frame/revive/src/lib.rs @@ -829,7 +829,11 @@ pub mod pallet { } // Build genesis block - block_storage::on_finalize_build_eth_block::(0u32.into()); + block_storage::on_finalize_build_eth_block::( + // Make sure to use the block number from storage instead of the hardcoded 0. + // This enables testing tools like anvil to customise the genesis block number. + frame_system::Pallet::::block_number(), + ); // Set debug settings. if let Some(settings) = self.debug_settings.as_ref() { diff --git a/substrate/frame/revive/src/tests.rs b/substrate/frame/revive/src/tests.rs index f09afd070789a..6b992919600f0 100644 --- a/substrate/frame/revive/src/tests.rs +++ b/substrate/frame/revive/src/tests.rs @@ -50,7 +50,7 @@ use sp_keystore::{testing::MemoryKeystore, KeystoreExt}; use sp_runtime::{ generic::Header, traits::{BlakeTwo256, Convert, IdentityLookup, One}, - AccountId32, BuildStorage, MultiAddress, MultiSignature, Perbill, + AccountId32, BuildStorage, MultiAddress, MultiSignature, Perbill, Storage, }; pub type Address = MultiAddress; @@ -439,6 +439,7 @@ pub struct ExtBuilder { storage_version: Option, code_hashes: Vec, genesis_config: Option>, + genesis_state_overrides: Option, } impl Default for ExtBuilder { @@ -448,6 +449,7 @@ impl Default for ExtBuilder { storage_version: None, code_hashes: vec![], genesis_config: Some(crate::GenesisConfig::::default()), + genesis_state_overrides: None, } } } @@ -469,10 +471,19 @@ impl ExtBuilder { pub fn set_associated_consts(&self) { EXISTENTIAL_DEPOSIT.with(|v| *v.borrow_mut() = self.existential_deposit); } + pub fn with_genesis_state_overrides(mut self, storage: Storage) -> Self { + self.genesis_state_overrides = Some(storage); + self + } pub fn build(self) -> sp_io::TestExternalities { sp_tracing::try_init_simple(); self.set_associated_consts(); - let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + let mut t = self.genesis_state_overrides.unwrap_or_default(); + + frame_system::GenesisConfig::::default() + .assimilate_storage(&mut t) + .unwrap(); + let checking_account = Pallet::::checking_account(); pallet_balances::GenesisConfig:: { diff --git a/substrate/frame/revive/src/tests/block_hash.rs b/substrate/frame/revive/src/tests/block_hash.rs index 68685481c6b5e..d83b55916e9be 100644 --- a/substrate/frame/revive/src/tests/block_hash.rs +++ b/substrate/frame/revive/src/tests/block_hash.rs @@ -20,7 +20,7 @@ use crate::{ evm::{block_hash::EthereumBlockBuilder, fees::InfoT, Block, TransactionSigned}, test_utils::{builder::Contract, deposit_limit, ALICE}, - tests::{assert_ok, builder, Contracts, ExtBuilder, RuntimeOrigin, Test}, + tests::{assert_ok, builder, Contracts, ExtBuilder, RuntimeOrigin, System, Test, Timestamp}, BalanceWithDust, Code, Config, EthBlock, EthBlockBuilderFirstValues, EthBlockBuilderIR, EthereumBlock, Pallet, ReceiptGasInfo, ReceiptInfoData, }; @@ -31,6 +31,7 @@ use frame_support::traits::{ Hooks, }; use pallet_revive_fixtures::compile_module; +use sp_state_machine::BasicExternalities; #[test] fn on_initialize_clears_storage() { @@ -52,6 +53,26 @@ fn on_initialize_clears_storage() { }); } +#[test] +fn genesis_block_number_and_timestamp_fetched_from_storage() { + let mut ext = BasicExternalities::new_empty(); + ext.execute_with(|| { + System::set_block_number(10); + Timestamp::set_timestamp(10000000); + }); + let storage = ext.into_storages(); + + ExtBuilder::default() + .with_genesis_state_overrides(storage) + .build() + .execute_with(|| { + let block = EthereumBlock::::get(); + // The timestamp is divided by 1000 (converted to seconds) + assert_eq!(block.timestamp, 10000.into()); + assert_eq!(block.number, 10.into()); + }); +} + #[test] fn transactions_are_captured() { let (binary, _) = compile_module("dummy").unwrap();