diff --git a/cmd/ethrex/networks/holesky/genesis.json b/cmd/ethrex/networks/holesky/genesis.json index eda73b0a2eb..8e111229e48 100644 --- a/cmd/ethrex/networks/holesky/genesis.json +++ b/cmd/ethrex/networks/holesky/genesis.json @@ -17,6 +17,36 @@ "shanghaiTime": 1696000704, "pragueTime": 1740434112, "cancunTime": 1707305664, + "osakaTime": 1759308480, + "bpo1Time": 1759800000, + "bpo2Time": 1760389824, + "blobSchedule": { + "cancun": { + "target": 3, + "max": 6, + "baseFeeUpdateFraction": 3338477 + }, + "prague": { + "target": 6, + "max": 9, + "baseFeeUpdateFraction": 5007716 + }, + "osaka": { + "target": 6, + "max": 9, + "baseFeeUpdateFraction": 5007716 + }, + "bpo1": { + "target": 10, + "max": 15, + "baseFeeUpdateFraction": 8346193 + }, + "bpo2": { + "target": 14, + "max": 21, + "baseFeeUpdateFraction": 11684671 + } + }, "depositContractAddress": "0x4242424242424242424242424242424242424242" }, "alloc": { diff --git a/cmd/ethrex/networks/hoodi/genesis.json b/cmd/ethrex/networks/hoodi/genesis.json index 4b6b5713490..d72801306e6 100644 --- a/cmd/ethrex/networks/hoodi/genesis.json +++ b/cmd/ethrex/networks/hoodi/genesis.json @@ -16,6 +16,10 @@ "terminalTotalDifficultyPassed": true, "shanghaiTime": 0, "cancunTime": 0, + "pragueTime": 1742999832, + "osakaTime": 1761677592, + "bpo1Time": 1762365720, + "bpo2Time": 1762955544, "blobSchedule": { "cancun": { "target": 3, @@ -26,10 +30,24 @@ "target": 6, "max": 9, "baseFeeUpdateFraction": 5007716 + }, + "osaka": { + "target": 6, + "max": 9, + "baseFeeUpdateFraction": 5007716 + }, + "bpo1": { + "target": 10, + "max": 15, + "baseFeeUpdateFraction": 8346193 + }, + "bpo2": { + "target": 14, + "max": 21, + "baseFeeUpdateFraction": 11684671 } }, - "depositContractAddress": "0x00000000219ab540356cBB839Cbe05303d7705Fa", - "pragueTime": 1742999832 + "depositContractAddress": "0x00000000219ab540356cBB839Cbe05303d7705Fa" }, "alloc": { "0x0000000000000000000000000000000000000000": { diff --git a/cmd/ethrex/networks/mainnet/genesis.json b/cmd/ethrex/networks/mainnet/genesis.json index 2c2d06e0989..899f40dd47d 100644 --- a/cmd/ethrex/networks/mainnet/genesis.json +++ b/cmd/ethrex/networks/mainnet/genesis.json @@ -22,6 +22,9 @@ "shanghaiTime": 1681338455, "cancunTime": 1710338135, "pragueTime": 1746612311, + "osakaTime": 1764798551, + "bpo1Time": 1765978199, + "bpo2Time": 1767747671, "ethash": {}, "depositContractAddress": "0x00000000219ab540356cBB839Cbe05303d7705Fa", "blobSchedule": { @@ -34,6 +37,21 @@ "target": 6, "max": 9, "baseFeeUpdateFraction": 5007716 + }, + "osaka": { + "target": 6, + "max": 9, + "baseFeeUpdateFraction": 5007716 + }, + "bpo1": { + "target": 10, + "max": 15, + "baseFeeUpdateFraction": 8346193 + }, + "bpo2": { + "target": 14, + "max": 21, + "baseFeeUpdateFraction": 11684671 } } }, diff --git a/cmd/ethrex/networks/sepolia/genesis.json b/cmd/ethrex/networks/sepolia/genesis.json index c8c74d82623..e56fa5a1cd8 100644 --- a/cmd/ethrex/networks/sepolia/genesis.json +++ b/cmd/ethrex/networks/sepolia/genesis.json @@ -17,6 +17,36 @@ "shanghaiTime": 1677557088, "cancunTime": 1706655072, "pragueTime": 1741159776, + "osakaTime": 1760427360, + "bpo1Time": 1761017184, + "bpo2Time": 1761607008, + "blobSchedule": { + "cancun": { + "target": 3, + "max": 6, + "baseFeeUpdateFraction": 3338477 + }, + "prague": { + "target": 6, + "max": 9, + "baseFeeUpdateFraction": 5007716 + }, + "osaka": { + "target": 6, + "max": 9, + "baseFeeUpdateFraction": 5007716 + }, + "bpo1": { + "target": 10, + "max": 15, + "baseFeeUpdateFraction": 8346193 + }, + "bpo2": { + "target": 14, + "max": 21, + "baseFeeUpdateFraction": 11684671 + } + }, "depositContractAddress": "0x7f02C3E3c98b133055B8B348B2Ac625669Ed295D" }, "alloc": { diff --git a/crates/common/types/fork_id.rs b/crates/common/types/fork_id.rs index ba7e294fc79..2272972d576 100644 --- a/crates/common/types/fork_id.rs +++ b/crates/common/types/fork_id.rs @@ -316,6 +316,60 @@ mod tests { time: 1740434112, fork_id: ForkId { fork_hash: H32::from_str("0xdfbd9bed").unwrap(), + fork_next: 1759308480, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1759308479, + fork_id: ForkId { + fork_hash: H32::from_str("0xdfbd9bed").unwrap(), + fork_next: 1759308480, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1759308480, + fork_id: ForkId { + fork_hash: H32::from_str("0x783def52").unwrap(), + fork_next: 1759800000, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1759799999, + fork_id: ForkId { + fork_hash: H32::from_str("0x783def52").unwrap(), + fork_next: 1759800000, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1759800000, + fork_id: ForkId { + fork_hash: H32::from_str("0xa280a45c").unwrap(), + fork_next: 1760389824, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1760389823, + fork_id: ForkId { + fork_hash: H32::from_str("0xa280a45c").unwrap(), + fork_next: 1760389824, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1760389824, + fork_id: ForkId { + fork_hash: H32::from_str("0x9bc6cb31").unwrap(), fork_next: 0, }, is_valid: true, @@ -324,7 +378,111 @@ mod tests { head: 123, time: 2740434112, fork_id: ForkId { - fork_hash: H32::from_str("0xdfbd9bed").unwrap(), + fork_hash: H32::from_str("0x9bc6cb31").unwrap(), + fork_next: 0, + }, + is_valid: true, + }, + ]; + assert_test_cases(test_cases, genesis.config, genesis_header); + } + + #[test] + fn hoodi_test_cases() { + let genesis_file = std::fs::File::open("../../cmd/ethrex/networks/hoodi/genesis.json") + .expect("Failed to open genesis file"); + let genesis_reader = BufReader::new(genesis_file); + let genesis: Genesis = + serde_json::from_reader(genesis_reader).expect("Failed to read genesis file"); + let genesis_header = genesis.get_block().header; + // See https://github.com/ethereum/go-ethereum/blob/444a6d007a08bddcec0b68b60ab507ea8bc1d078/core/forkid/forkid_test.go#L100 + let test_cases: Vec = vec![ + TestCase { + head: 123, + time: 0, + fork_id: ForkId { + fork_hash: H32::from_str("0xbef71d30").unwrap(), + fork_next: 1742999832, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1742999831, + fork_id: ForkId { + fork_hash: H32::from_str("0xbef71d30").unwrap(), + fork_next: 1742999832, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1742999832, + fork_id: ForkId { + fork_hash: H32::from_str("0x0929e24e").unwrap(), + fork_next: 1761677592, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1761677591, + fork_id: ForkId { + fork_hash: H32::from_str("0x0929e24e").unwrap(), + fork_next: 1761677592, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1761677592, + fork_id: ForkId { + fork_hash: H32::from_str("0xe7e0e7ff").unwrap(), + fork_next: 1762365720, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1762365719, + fork_id: ForkId { + fork_hash: H32::from_str("0xe7e0e7ff").unwrap(), + fork_next: 1762365720, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1762365720, + fork_id: ForkId { + fork_hash: H32::from_str("0x3893353e").unwrap(), + fork_next: 1762955544, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1762955543, + fork_id: ForkId { + fork_hash: H32::from_str("0x3893353e").unwrap(), + fork_next: 1762955544, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 1762955544, + fork_id: ForkId { + fork_hash: H32::from_str("0x23aa1351").unwrap(), + fork_next: 0, + }, + is_valid: true, + }, + TestCase { + head: 123, + time: 2740434112, + fork_id: ForkId { + fork_hash: H32::from_str("0x23aa1351").unwrap(), fork_next: 0, }, is_valid: true, @@ -424,6 +582,60 @@ mod tests { time: 1741159776, fork_id: ForkId { fork_hash: H32::from_str("0xed88b5fd").unwrap(), + fork_next: 1760427360, + }, + is_valid: true, + }, + TestCase { + head: 1735372, + time: 1760427359, + fork_id: ForkId { + fork_hash: H32::from_str("0xed88b5fd").unwrap(), + fork_next: 1760427360, + }, + is_valid: true, + }, + TestCase { + head: 1735372, + time: 1760427360, + fork_id: ForkId { + fork_hash: H32::from_str("0xe2ae4999").unwrap(), + fork_next: 1761017184, + }, + is_valid: true, + }, + TestCase { + head: 1735372, + time: 1761017183, + fork_id: ForkId { + fork_hash: H32::from_str("0xe2ae4999").unwrap(), + fork_next: 1761017184, + }, + is_valid: true, + }, + TestCase { + head: 1735372, + time: 1761017184, + fork_id: ForkId { + fork_hash: H32::from_str("0x56078a1e").unwrap(), + fork_next: 1761607008, + }, + is_valid: true, + }, + TestCase { + head: 1735372, + time: 1761607007, + fork_id: ForkId { + fork_hash: H32::from_str("0x56078a1e").unwrap(), + fork_next: 1761607008, + }, + is_valid: true, + }, + TestCase { + head: 1735372, + time: 1761607008, + fork_id: ForkId { + fork_hash: H32::from_str("0x268956b6").unwrap(), fork_next: 0, }, is_valid: true, @@ -432,13 +644,13 @@ mod tests { head: 1735372, time: 2741159776, fork_id: ForkId { - fork_hash: H32::from_str("0xed88b5fd").unwrap(), + fork_hash: H32::from_str("0x268956b6").unwrap(), fork_next: 0, }, is_valid: true, }, ]; - assert_test_cases(test_cases, genesis.config, genesis_hash); + assert_test_cases(test_cases, genesis.config, genesis_hash.clone()); } #[test] diff --git a/crates/common/types/genesis.rs b/crates/common/types/genesis.rs index 8ab36bf5b77..af082071f96 100644 --- a/crates/common/types/genesis.rs +++ b/crates/common/types/genesis.rs @@ -85,9 +85,7 @@ impl TryFrom<&Path> for Genesis { warn!("Invalid fork, only post-merge networks are supported."); } - if genesis.config.bpo1_time.is_some() && genesis.config.blob_schedule.bpo1.is_none() - || genesis.config.bpo2_time.is_some() && genesis.config.blob_schedule.bpo2.is_none() - || genesis.config.bpo3_time.is_some() && genesis.config.blob_schedule.bpo3.is_none() + if genesis.config.bpo3_time.is_some() && genesis.config.blob_schedule.bpo3.is_none() || genesis.config.bpo4_time.is_some() && genesis.config.blob_schedule.bpo4.is_none() || genesis.config.bpo5_time.is_some() && genesis.config.blob_schedule.bpo5.is_none() { @@ -130,10 +128,10 @@ pub struct BlobSchedule { pub prague: ForkBlobSchedule, #[serde(default = "default_osaka_schedule")] pub osaka: ForkBlobSchedule, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub bpo1: Option, - #[serde(default, skip_serializing_if = "Option::is_none")] - pub bpo2: Option, + #[serde(default = "default_bpo1_schedule")] + pub bpo1: ForkBlobSchedule, + #[serde(default = "default_bpo2_schedule")] + pub bpo2: ForkBlobSchedule, #[serde(default, skip_serializing_if = "Option::is_none")] pub bpo3: Option, #[serde(default, skip_serializing_if = "Option::is_none")] @@ -148,8 +146,8 @@ impl Default for BlobSchedule { cancun: default_cancun_schedule(), prague: default_prague_schedule(), osaka: default_osaka_schedule(), - bpo1: None, - bpo2: None, + bpo1: default_bpo1_schedule(), + bpo2: default_bpo2_schedule(), bpo3: None, bpo4: None, bpo5: None, @@ -181,6 +179,21 @@ fn default_osaka_schedule() -> ForkBlobSchedule { } } +fn default_bpo1_schedule() -> ForkBlobSchedule { + ForkBlobSchedule { + target: 10, + max: 15, + base_fee_update_fraction: 8346193, + } +} + +fn default_bpo2_schedule() -> ForkBlobSchedule { + ForkBlobSchedule { + target: 14, + max: 21, + base_fee_update_fraction: 11684671, + } +} /// Blockchain settings defined per block #[allow(unused)] #[derive( @@ -290,6 +303,11 @@ pub enum Fork { Cancun = 17, Prague = 18, Osaka = 19, + BPO1 = 20, + BPO2 = 21, + BPO3 = 22, + BPO4 = 23, + BPO5 = 24, } impl From for &str { @@ -315,6 +333,11 @@ impl From for &str { Fork::Cancun => "Cancun", Fork::Prague => "Prague", Fork::Osaka => "Osaka", + Fork::BPO1 => "BPO1", + Fork::BPO2 => "BPO2", + Fork::BPO3 => "BPO3", + Fork::BPO4 => "BPO4", + Fork::BPO5 => "BPO5", } } } @@ -419,9 +442,9 @@ impl ChainConfig { } else if self.is_bpo3_activated(block_timestamp) { Some(self.blob_schedule.bpo3.unwrap_or_default()) } else if self.is_bpo2_activated(block_timestamp) { - Some(self.blob_schedule.bpo2.unwrap_or_default()) + Some(self.blob_schedule.bpo2) } else if self.is_bpo1_activated(block_timestamp) { - Some(self.blob_schedule.bpo1.unwrap_or_default()) + Some(self.blob_schedule.bpo1) } else if self.is_osaka_activated(block_timestamp) { Some(self.blob_schedule.osaka) } else if self.is_prague_activated(block_timestamp) { @@ -471,6 +494,12 @@ impl ChainConfig { self.shanghai_time, self.cancun_time, self.prague_time, + self.osaka_time, + self.bpo1_time, + self.bpo2_time, + self.bpo3_time, + self.bpo4_time, + self.bpo5_time, self.verkle_time, ] .into_iter() diff --git a/crates/networking/rpc/rpc.rs b/crates/networking/rpc/rpc.rs index 9588c99f6ac..3ca3e641ab3 100644 --- a/crates/networking/rpc/rpc.rs +++ b/crates/networking/rpc/rpc.rs @@ -563,6 +563,8 @@ mod tests { "cancun": { "target": 3, "max": 6, "baseFeeUpdateFraction": 3338477 }, "prague": { "target": 6, "max": 9, "baseFeeUpdateFraction": 5007716 }, "osaka": { "target": 6, "max": 9, "baseFeeUpdateFraction": 5007716 }, + "bpo1": { "target": 10, "max": 15, "baseFeeUpdateFraction": 8346193 }, + "bpo2": { "target": 14, "max": 21, "baseFeeUpdateFraction": 11684671 }, }); let json = serde_json::json!({ "jsonrpc": "2.0", diff --git a/crates/vm/backends/revm/helpers.rs b/crates/vm/backends/revm/helpers.rs index a4f87673881..f2091acb419 100644 --- a/crates/vm/backends/revm/helpers.rs +++ b/crates/vm/backends/revm/helpers.rs @@ -122,5 +122,10 @@ pub fn fork_to_spec_id(fork: Fork) -> SpecId { Fork::Cancun => SpecId::CANCUN, Fork::Prague => SpecId::PRAGUE, Fork::Osaka => SpecId::OSAKA, + Fork::BPO1 => SpecId::OSAKA, + Fork::BPO2 => SpecId::OSAKA, + Fork::BPO3 => SpecId::OSAKA, + Fork::BPO4 => SpecId::OSAKA, + Fork::BPO5 => SpecId::OSAKA, } } diff --git a/tooling/ef_tests/blockchain/types.rs b/tooling/ef_tests/blockchain/types.rs index 856e68e0f99..8afef9f9738 100644 --- a/tooling/ef_tests/blockchain/types.rs +++ b/tooling/ef_tests/blockchain/types.rs @@ -115,10 +115,10 @@ impl From for ethrex_common::types::BlobSchedule { blob_schedule.osaka = osaka_schedule.into() } if let Some(bpo1_schedule) = val.bpo1 { - blob_schedule.bpo1 = Some(bpo1_schedule.into()) + blob_schedule.bpo1 = bpo1_schedule.into() } if let Some(bpo2_schedule) = val.bpo2 { - blob_schedule.bpo2 = Some(bpo2_schedule.into()) + blob_schedule.bpo2 = bpo2_schedule.into() } if let Some(bpo3_schedule) = val.bpo3 { blob_schedule.bpo3 = Some(bpo3_schedule.into())