From f490f558c1e7c538f1b6ea4fb78ea6e34c61c1f0 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Thu, 7 Sep 2023 08:25:39 -0400 Subject: [PATCH] fix(primitives): set cancun header fields if active at genesis (#4500) --- crates/primitives/src/chain/spec.rs | 74 ++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 7 deletions(-) diff --git a/crates/primitives/src/chain/spec.rs b/crates/primitives/src/chain/spec.rs index f73bcc9830..15bc96bf26 100644 --- a/crates/primitives/src/chain/spec.rs +++ b/crates/primitives/src/chain/spec.rs @@ -1,13 +1,13 @@ use crate::{ constants::{ EIP1559_DEFAULT_BASE_FEE_MAX_CHANGE_DENOMINATOR, EIP1559_DEFAULT_ELASTICITY_MULTIPLIER, - EIP1559_INITIAL_BASE_FEE, EMPTY_WITHDRAWALS, + EIP1559_INITIAL_BASE_FEE, EMPTY_RECEIPTS, EMPTY_TRANSACTIONS, EMPTY_WITHDRAWALS, }, forkid::ForkFilterKey, header::Head, proofs::genesis_state_root, Address, BlockNumber, Chain, ForkFilter, ForkHash, ForkId, Genesis, Hardfork, Header, - PruneBatchSizes, SealedHeader, H160, H256, U256, + PruneBatchSizes, SealedHeader, EMPTY_OMMER_ROOT, H160, H256, U256, }; use hex_literal::hex; use once_cell::sync::Lazy; @@ -304,7 +304,24 @@ impl ChainSpec { (self.fork(Hardfork::Shanghai).active_at_timestamp(self.genesis.timestamp)) .then_some(EMPTY_WITHDRAWALS); + // If Cancun is activated at genesis, we set: + // * parent beacon block root to 0x0 + // * blob gas used to 0x0 + // * excess blob gas to 0x0 + let (parent_beacon_block_root, blob_gas_used, excess_blob_gas) = + if self.fork(Hardfork::Cancun).active_at_timestamp(self.genesis.timestamp) { + (Some(H256::zero()), Some(0), Some(0)) + } else { + (None, None, None) + }; + Header { + parent_hash: H256::zero(), + number: 0, + transactions_root: EMPTY_TRANSACTIONS, + ommers_hash: EMPTY_OMMER_ROOT, + receipts_root: EMPTY_RECEIPTS, + logs_bloom: Default::default(), gas_limit: self.genesis.gas_limit, difficulty: self.genesis.difficulty, nonce: self.genesis.nonce, @@ -313,9 +330,12 @@ impl ChainSpec { timestamp: self.genesis.timestamp, mix_hash: self.genesis.mix_hash, beneficiary: self.genesis.coinbase, + gas_used: Default::default(), base_fee_per_gas, withdrawals_root, - ..Default::default() + parent_beacon_block_root, + blob_gas_used, + excess_blob_gas, } } @@ -728,7 +748,7 @@ impl ChainSpecBuilder { /// Enable Cancun at genesis. pub fn cancun_activated(mut self) -> Self { - self = self.paris_activated(); + self = self.shanghai_activated(); self.hardforks.insert(Hardfork::Cancun, ForkCondition::Timestamp(0)); self } @@ -1061,13 +1081,15 @@ impl DepositContract { #[cfg(test)] mod tests { use crate::{ - Address, AllGenesisFormats, Chain, ChainSpec, ChainSpecBuilder, DisplayHardforks, - ForkCondition, ForkHash, ForkId, Genesis, Hardfork, Head, DEV, GOERLI, H256, MAINNET, - SEPOLIA, U256, + constants::EMPTY_WITHDRAWALS, Address, AllGenesisFormats, Chain, ChainSpec, + ChainSpecBuilder, DisplayHardforks, ForkCondition, ForkHash, ForkId, Genesis, Hardfork, + Head, DEV, GOERLI, H256, MAINNET, SEPOLIA, U256, }; use bytes::BytesMut; use ethers_core::types as EtherType; use reth_rlp::Encodable; + use std::str::FromStr; + fn test_fork_ids(spec: &ChainSpec, cases: &[(Head, ForkId)]) { for (block, expected_id) in cases { let computed_id = spec.fork_id(block); @@ -1832,4 +1854,42 @@ Post-merge hard forks (timestamp based): // assert that the cancun time was picked up assert_eq!(genesis.config.cancun_time, Some(4661)); } + + #[test] + fn test_default_cancun_header_forkhash() { + // set the gas limit from the hive test genesis according to the hash + let genesis = Genesis { gas_limit: 0x2fefd8u64, ..Default::default() }; + let default_chainspec = ChainSpecBuilder::default() + .chain(Chain::Id(1337)) + .genesis(genesis) + .cancun_activated() + .build(); + let mut header = default_chainspec.genesis_header(); + + // set the state root to the same as in the hive test the hash was pulled from + header.state_root = + H256::from_str("0x62e2595e017f0ca23e08d17221010721a71c3ae932f4ea3cb12117786bb392d4") + .unwrap(); + + // shanghai is activated so we should have a withdrawals root + assert_eq!(header.withdrawals_root, Some(EMPTY_WITHDRAWALS)); + + // cancun is activated so we should have a zero parent beacon block root, zero blob gas + // used, and zero excess blob gas + assert_eq!(header.parent_beacon_block_root, Some(H256::zero())); + assert_eq!(header.blob_gas_used, Some(0)); + assert_eq!(header.excess_blob_gas, Some(0)); + println!("header: {:?}", header); + + // check the genesis hash + let genesis_hash = header.hash_slow(); + let expected_hash = H256::from(hex_literal::hex!( + "16bb7c59613a5bad3f7c04a852fd056545ade2483968d9a25a1abb05af0c4d37" + )); + assert_eq!(genesis_hash, expected_hash); + + // check that the forkhash is correct + let expected_forkhash = ForkHash(hex_literal::hex!("8062457a")); + assert_eq!(ForkHash::from(genesis_hash), expected_forkhash); + } }