From 3cb25a4223c0ecb968a69aa5da1ef3f7da38da66 Mon Sep 17 00:00:00 2001 From: clabby Date: Sat, 18 Nov 2023 11:17:23 -0500 Subject: [PATCH 01/14] Add `Canyon` Hardfork (optimism) tests --- crates/primitives/src/chain/spec.rs | 69 +++++++++++++++++++++++----- crates/primitives/src/hardfork.rs | 9 +++- crates/primitives/src/revm/config.rs | 21 ++++++--- 3 files changed, 80 insertions(+), 19 deletions(-) diff --git a/crates/primitives/src/chain/spec.rs b/crates/primitives/src/chain/spec.rs index 4f5e4f6374c4..a69f7214bc9e 100644 --- a/crates/primitives/src/chain/spec.rs +++ b/crates/primitives/src/chain/spec.rs @@ -274,6 +274,7 @@ pub static OP_GOERLI: Lazy> = Lazy::new(|| { ), (Hardfork::Bedrock, ForkCondition::Block(4061224)), (Hardfork::Regolith, ForkCondition::Timestamp(1679079600)), + (Hardfork::Canyon, ForkCondition::Timestamp(1699981200)), ]), base_fee_params: BaseFeeParams::optimism(), prune_delete_limit: 1700, @@ -315,6 +316,7 @@ pub static BASE_GOERLI: Lazy> = Lazy::new(|| { ), (Hardfork::Bedrock, ForkCondition::Block(0)), (Hardfork::Regolith, ForkCondition::Timestamp(1683219600)), + (Hardfork::Canyon, ForkCondition::Timestamp(1699981200)), ]), base_fee_params: BaseFeeParams::optimism_goerli(), prune_delete_limit: 1700, @@ -668,7 +670,7 @@ impl ChainSpec { } else { // we can return here because this block fork is not active, so we set the // `next` value - return ForkId { hash: forkhash, next: block } + return ForkId { hash: forkhash, next: block }; } } } @@ -689,7 +691,7 @@ impl ChainSpec { // can safely return here because we have already handled all block forks and // have handled all active timestamp forks, and set the next value to the // timestamp that is known but not active yet - return ForkId { hash: forkhash, next: timestamp } + return ForkId { hash: forkhash, next: timestamp }; } } @@ -704,7 +706,7 @@ impl ChainSpec { // to satisfy every timestamp ForkCondition, we find the last ForkCondition::Block // if one exists, and include its block_num in the returned Head if let Some(last_block_num) = self.last_block_fork_before_merge_or_timestamp() { - return Head { timestamp, number: last_block_num, ..Default::default() } + return Head { timestamp, number: last_block_num, ..Default::default() }; } Head { timestamp, ..Default::default() } } @@ -732,17 +734,17 @@ impl ChainSpec { ForkCondition::TTD { fork_block, .. } => { // handle Sepolia merge netsplit case if fork_block.is_some() { - return *fork_block + return *fork_block; } // ensure curr_cond is indeed ForkCondition::Block and return block_num if let ForkCondition::Block(block_num) = curr_cond { - return Some(block_num) + return Some(block_num); } } ForkCondition::Timestamp(_) => { // ensure curr_cond is indeed ForkCondition::Block and return block_num if let ForkCondition::Block(block_num) = curr_cond { - return Some(block_num) + return Some(block_num); } } ForkCondition::Block(_) | ForkCondition::Never => continue, @@ -1032,9 +1034,7 @@ impl ChainSpecBuilder { self } - /// Enable Regolith at the timestamp of activation. - /// For post-bedrock op-stack chains, this will be at genesis. - /// For pre-bedrock op-stack chains, this will be at the timestamp of regolith activation. + /// Enable Regolith at genesis #[cfg(feature = "optimism")] pub fn regolith_activated(mut self) -> Self { self = self.bedrock_activated(); @@ -1042,6 +1042,15 @@ impl ChainSpecBuilder { self } + /// Enable Canyon at genesis + #[cfg(feature = "optimism")] + pub fn canyon_activated(mut self) -> Self { + self = self.regolith_activated(); + self.hardforks.insert(Hardfork::Shanghai, ForkCondition::Timestamp(0)); + self.hardforks.insert(Hardfork::Canyon, ForkCondition::Timestamp(0)); + self + } + /// Build the resulting [`ChainSpec`]. /// /// # Panics @@ -1989,8 +1998,46 @@ Post-merge hard forks (timestamp based): ForkId { hash: ForkHash([0x03, 0x47, 0x85, 0x69]), next: 1679079600 }, ), ( - Head { number: 4061224, timestamp: 1679079600, ..Default::default() }, - ForkId { hash: ForkHash([0x6d, 0x43, 0x1d, 0x6c]), next: 0 }, + Head { number: 4061225, timestamp: 1679079600, ..Default::default() }, + ForkId { hash: ForkHash([0x6d, 0x43, 0x1d, 0x6c]), next: 1699981200 }, + ), + ( + Head { number: 4061226, timestamp: 1699981199, ..Default::default() }, + ForkId { hash: ForkHash([0x6d, 0x43, 0x1d, 0x6c]), next: 1699981200 }, + ), + ( + Head { number: 4061227, timestamp: 1699981200, ..Default::default() }, + ForkId { hash: ForkHash([0x7f, 0x4a, 0x72, 0x1f]), next: 0 }, + ), + ], + ); + } + + #[cfg(feature = "optimism")] + #[test] + fn base_goerli_forkids() { + test_fork_ids( + &BASE_GOERLI, + &[ + ( + Head { number: 0, ..Default::default() }, + ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1683219600 }, + ), + ( + Head { number: 1, timestamp: 1683219599, ..Default::default() }, + ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1683219600 }, + ), + ( + Head { number: 2, timestamp: 1683219600, ..Default::default() }, + ForkId { hash: ForkHash([0xd5, 0x45, 0x43, 0x5d]), next: 1699981200 }, + ), + ( + Head { number: 3, timestamp: 1699981199, ..Default::default() }, + ForkId { hash: ForkHash([0xd5, 0x45, 0x43, 0x5d]), next: 1699981200 }, + ), + ( + Head { number: 4, timestamp: 1699981200, ..Default::default() }, + ForkId { hash: ForkHash([0xb3, 0x29, 0x13, 0xde]), next: 0 }, ), ], ); diff --git a/crates/primitives/src/hardfork.rs b/crates/primitives/src/hardfork.rs index e1e29fc3673c..e94e86f07d01 100644 --- a/crates/primitives/src/hardfork.rs +++ b/crates/primitives/src/hardfork.rs @@ -47,6 +47,9 @@ pub enum Hardfork { /// Regolith #[cfg(feature = "optimism")] Regolith, + /// Canyon + #[cfg(feature = "optimism")] + Canyon, } impl Hardfork { @@ -95,6 +98,8 @@ impl FromStr for Hardfork { "bedrock" => Hardfork::Bedrock, #[cfg(feature = "optimism")] "regolith" => Hardfork::Regolith, + #[cfg(feature = "optimism")] + "canyon" => Hardfork::Canyon, _ => return Err(format!("Unknown hardfork: {s}")), }; Ok(hardfork) @@ -163,8 +168,8 @@ mod tests { #[test] #[cfg(feature = "optimism")] fn check_op_hardfork_from_str() { - let hardfork_str = ["beDrOck", "rEgOlITH"]; - let expected_hardforks = [Hardfork::Bedrock, Hardfork::Regolith]; + let hardfork_str = ["beDrOck", "rEgOlITH", "cAnYoN"]; + let expected_hardforks = [Hardfork::Bedrock, Hardfork::Regolith, Hardfork::Canyon]; let hardforks: Vec = hardfork_str.iter().map(|h| Hardfork::from_str(h).unwrap()).collect(); diff --git a/crates/primitives/src/revm/config.rs b/crates/primitives/src/revm/config.rs index 33848a844298..c12250275ec9 100644 --- a/crates/primitives/src/revm/config.rs +++ b/crates/primitives/src/revm/config.rs @@ -10,10 +10,12 @@ pub fn revm_spec_by_timestamp_after_merge( ) -> revm_primitives::SpecId { #[cfg(feature = "optimism")] if chain_spec.is_optimism() { - if chain_spec.fork(Hardfork::Regolith).active_at_timestamp(timestamp) { - return revm_primitives::REGOLITH + if chain_spec.fork(Hardfork::Canyon).active_at_timestamp(timestamp) { + unimplemented!() + } else if chain_spec.fork(Hardfork::Regolith).active_at_timestamp(timestamp) { + return revm_primitives::REGOLITH; } else { - return revm_primitives::BEDROCK + return revm_primitives::BEDROCK; } } @@ -30,10 +32,12 @@ pub fn revm_spec_by_timestamp_after_merge( pub fn revm_spec(chain_spec: &ChainSpec, block: Head) -> revm_primitives::SpecId { #[cfg(feature = "optimism")] if chain_spec.is_optimism() { - if chain_spec.fork(Hardfork::Regolith).active_at_head(&block) { - return revm_primitives::REGOLITH + if chain_spec.fork(Hardfork::Canyon).active_at_head(&block) { + unimplemented!() + } else if chain_spec.fork(Hardfork::Regolith).active_at_head(&block) { + return revm_primitives::REGOLITH; } else if chain_spec.fork(Hardfork::Bedrock).active_at_head(&block) { - return revm_primitives::BEDROCK + return revm_primitives::BEDROCK; } } @@ -138,6 +142,11 @@ mod tests { f(cs).build() } + // TODO: Enable once `reth` has been updated to a revm version that knows about Canyon. + // assert_eq!( + // revm_spec(&op_cs(|cs| cs.canyon_activated()), Head::default()), + // revm_primitives::CANYON + // ); assert_eq!( revm_spec(&op_cs(|cs| cs.bedrock_activated()), Head::default()), revm_primitives::BEDROCK From c5b6b11967a7cbeeef895d6f205db2a9c28c7b28 Mon Sep 17 00:00:00 2001 From: clabby Date: Mon, 20 Nov 2023 13:18:30 -0500 Subject: [PATCH 02/14] `revm` PR merged; Add in `CANYON` HF to revm config --- crates/primitives/src/revm/config.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/primitives/src/revm/config.rs b/crates/primitives/src/revm/config.rs index c12250275ec9..3786f618efe4 100644 --- a/crates/primitives/src/revm/config.rs +++ b/crates/primitives/src/revm/config.rs @@ -11,7 +11,7 @@ pub fn revm_spec_by_timestamp_after_merge( #[cfg(feature = "optimism")] if chain_spec.is_optimism() { if chain_spec.fork(Hardfork::Canyon).active_at_timestamp(timestamp) { - unimplemented!() + return revm_primitives::CANYON; } else if chain_spec.fork(Hardfork::Regolith).active_at_timestamp(timestamp) { return revm_primitives::REGOLITH; } else { @@ -33,7 +33,7 @@ pub fn revm_spec(chain_spec: &ChainSpec, block: Head) -> revm_primitives::SpecId #[cfg(feature = "optimism")] if chain_spec.is_optimism() { if chain_spec.fork(Hardfork::Canyon).active_at_head(&block) { - unimplemented!() + return revm_primitives::CANYON; } else if chain_spec.fork(Hardfork::Regolith).active_at_head(&block) { return revm_primitives::REGOLITH; } else if chain_spec.fork(Hardfork::Bedrock).active_at_head(&block) { @@ -143,10 +143,10 @@ mod tests { } // TODO: Enable once `reth` has been updated to a revm version that knows about Canyon. - // assert_eq!( - // revm_spec(&op_cs(|cs| cs.canyon_activated()), Head::default()), - // revm_primitives::CANYON - // ); + assert_eq!( + revm_spec(&op_cs(|cs| cs.canyon_activated()), Head::default()), + revm_primitives::CANYON + ); assert_eq!( revm_spec(&op_cs(|cs| cs.bedrock_activated()), Head::default()), revm_primitives::BEDROCK From 6dc35855769a2c48170fe2f796f35bb11751c8fa Mon Sep 17 00:00:00 2001 From: clabby Date: Mon, 20 Nov 2023 18:12:45 -0500 Subject: [PATCH 03/14] Add `reth-auto-seal-consensus` feature toggle --- bin/reth/Cargo.toml | 1 + crates/primitives/src/chain/spec.rs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml index 273466aa145c..aad259ed067e 100644 --- a/bin/reth/Cargo.toml +++ b/bin/reth/Cargo.toml @@ -127,6 +127,7 @@ optimism = [ "reth-transaction-pool/optimism", "reth-provider/optimism", "reth-beacon-consensus/optimism", + "reth-auto-seal-consensus/optimism", "reth-basic-payload-builder/optimism", "reth-network/optimism", "reth-network-api/optimism", diff --git a/crates/primitives/src/chain/spec.rs b/crates/primitives/src/chain/spec.rs index a69f7214bc9e..62c90aa974df 100644 --- a/crates/primitives/src/chain/spec.rs +++ b/crates/primitives/src/chain/spec.rs @@ -274,6 +274,7 @@ pub static OP_GOERLI: Lazy> = Lazy::new(|| { ), (Hardfork::Bedrock, ForkCondition::Block(4061224)), (Hardfork::Regolith, ForkCondition::Timestamp(1679079600)), + (Hardfork::Shanghai, ForkCondition::Timestamp(1699981200)), (Hardfork::Canyon, ForkCondition::Timestamp(1699981200)), ]), base_fee_params: BaseFeeParams::optimism(), @@ -316,6 +317,7 @@ pub static BASE_GOERLI: Lazy> = Lazy::new(|| { ), (Hardfork::Bedrock, ForkCondition::Block(0)), (Hardfork::Regolith, ForkCondition::Timestamp(1683219600)), + (Hardfork::Shanghai, ForkCondition::Timestamp(1699981200)), (Hardfork::Canyon, ForkCondition::Timestamp(1699981200)), ]), base_fee_params: BaseFeeParams::optimism_goerli(), From a221405f7d461d5d4e44e1fba73e4f0192c7035e Mon Sep 17 00:00:00 2001 From: clabby Date: Mon, 20 Nov 2023 20:20:40 -0500 Subject: [PATCH 04/14] Semicolon nuke --- crates/primitives/src/chain/spec.rs | 12 +++++++----- crates/primitives/src/revm/config.rs | 12 ++++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/crates/primitives/src/chain/spec.rs b/crates/primitives/src/chain/spec.rs index 62c90aa974df..47de1109443c 100644 --- a/crates/primitives/src/chain/spec.rs +++ b/crates/primitives/src/chain/spec.rs @@ -661,8 +661,8 @@ impl ChainSpec { for (_, cond) in self.forks_iter() { // handle block based forks and the sepolia merge netsplit block edge case (TTD // ForkCondition with Some(block)) - if let ForkCondition::Block(block) | - ForkCondition::TTD { fork_block: Some(block), .. } = cond + if let ForkCondition::Block(block) + | ForkCondition::TTD { fork_block: Some(block), .. } = cond { if cond.active_at_head(head) { if block != current_applied { @@ -1172,9 +1172,9 @@ impl ForkCondition { /// - The condition is satisfied by the timestamp; /// - or the condition is satisfied by the total difficulty pub fn active_at_head(&self, head: &Head) -> bool { - self.active_at_block(head.number) || - self.active_at_timestamp(head.timestamp) || - self.active_at_ttd(head.total_difficulty, head.difficulty) + self.active_at_block(head.number) + || self.active_at_timestamp(head.timestamp) + || self.active_at_ttd(head.total_difficulty, head.difficulty) } /// Get the total terminal difficulty for this fork condition. @@ -1987,6 +1987,7 @@ Post-merge hard forks (timestamp based): #[cfg(feature = "optimism")] #[test] + #[ignore] fn optimism_goerli_forkids() { test_fork_ids( &OP_GOERLI, @@ -2017,6 +2018,7 @@ Post-merge hard forks (timestamp based): #[cfg(feature = "optimism")] #[test] + #[ignore] fn base_goerli_forkids() { test_fork_ids( &BASE_GOERLI, diff --git a/crates/primitives/src/revm/config.rs b/crates/primitives/src/revm/config.rs index 3786f618efe4..41c3857fa386 100644 --- a/crates/primitives/src/revm/config.rs +++ b/crates/primitives/src/revm/config.rs @@ -11,11 +11,11 @@ pub fn revm_spec_by_timestamp_after_merge( #[cfg(feature = "optimism")] if chain_spec.is_optimism() { if chain_spec.fork(Hardfork::Canyon).active_at_timestamp(timestamp) { - return revm_primitives::CANYON; + return revm_primitives::CANYON } else if chain_spec.fork(Hardfork::Regolith).active_at_timestamp(timestamp) { - return revm_primitives::REGOLITH; + return revm_primitives::REGOLITH } else { - return revm_primitives::BEDROCK; + return revm_primitives::BEDROCK } } @@ -33,11 +33,11 @@ pub fn revm_spec(chain_spec: &ChainSpec, block: Head) -> revm_primitives::SpecId #[cfg(feature = "optimism")] if chain_spec.is_optimism() { if chain_spec.fork(Hardfork::Canyon).active_at_head(&block) { - return revm_primitives::CANYON; + return revm_primitives::CANYON } else if chain_spec.fork(Hardfork::Regolith).active_at_head(&block) { - return revm_primitives::REGOLITH; + return revm_primitives::REGOLITH } else if chain_spec.fork(Hardfork::Bedrock).active_at_head(&block) { - return revm_primitives::BEDROCK; + return revm_primitives::BEDROCK } } From 5da0a35490db3761984993148c406072c3addb16 Mon Sep 17 00:00:00 2001 From: clabby Date: Tue, 21 Nov 2023 19:51:31 -0500 Subject: [PATCH 05/14] fmt --- .../src/test_utils/bodies_client.rs | 2 +- crates/net/eth-wire/src/capability.rs | 2 +- crates/primitives/src/chain/spec.rs | 22 +++++++++---------- crates/primitives/src/revm/config.rs | 1 - crates/primitives/src/snapshot/segment.rs | 4 ++-- .../rpc-types/src/serde_helpers/json_u256.rs | 4 ++-- crates/transaction-pool/src/pool/blob.rs | 2 +- 7 files changed, 18 insertions(+), 19 deletions(-) diff --git a/crates/net/downloaders/src/test_utils/bodies_client.rs b/crates/net/downloaders/src/test_utils/bodies_client.rs index ac791742d009..2f3cf2f293fb 100644 --- a/crates/net/downloaders/src/test_utils/bodies_client.rs +++ b/crates/net/downloaders/src/test_utils/bodies_client.rs @@ -92,7 +92,7 @@ impl BodiesClient for TestBodiesClient { Box::pin(async move { if should_respond_empty { - return Ok((PeerId::default(), vec![]).into()); + return Ok((PeerId::default(), vec![]).into()) } if should_delay { diff --git a/crates/net/eth-wire/src/capability.rs b/crates/net/eth-wire/src/capability.rs index 9bd4afa82e0c..8f090c72a2e4 100644 --- a/crates/net/eth-wire/src/capability.rs +++ b/crates/net/eth-wire/src/capability.rs @@ -252,7 +252,7 @@ impl SharedCapability { /// Returns an error if the offset is equal or less than [`MAX_RESERVED_MESSAGE_ID`]. pub(crate) fn new(name: &str, version: u8, offset: u8) -> Result { if offset <= MAX_RESERVED_MESSAGE_ID { - return Err(SharedCapabilityError::ReservedMessageIdOffset(offset)); + return Err(SharedCapabilityError::ReservedMessageIdOffset(offset)) } match name { diff --git a/crates/primitives/src/chain/spec.rs b/crates/primitives/src/chain/spec.rs index 47de1109443c..37d242bff072 100644 --- a/crates/primitives/src/chain/spec.rs +++ b/crates/primitives/src/chain/spec.rs @@ -661,8 +661,8 @@ impl ChainSpec { for (_, cond) in self.forks_iter() { // handle block based forks and the sepolia merge netsplit block edge case (TTD // ForkCondition with Some(block)) - if let ForkCondition::Block(block) - | ForkCondition::TTD { fork_block: Some(block), .. } = cond + if let ForkCondition::Block(block) | + ForkCondition::TTD { fork_block: Some(block), .. } = cond { if cond.active_at_head(head) { if block != current_applied { @@ -672,7 +672,7 @@ impl ChainSpec { } else { // we can return here because this block fork is not active, so we set the // `next` value - return ForkId { hash: forkhash, next: block }; + return ForkId { hash: forkhash, next: block } } } } @@ -693,7 +693,7 @@ impl ChainSpec { // can safely return here because we have already handled all block forks and // have handled all active timestamp forks, and set the next value to the // timestamp that is known but not active yet - return ForkId { hash: forkhash, next: timestamp }; + return ForkId { hash: forkhash, next: timestamp } } } @@ -708,7 +708,7 @@ impl ChainSpec { // to satisfy every timestamp ForkCondition, we find the last ForkCondition::Block // if one exists, and include its block_num in the returned Head if let Some(last_block_num) = self.last_block_fork_before_merge_or_timestamp() { - return Head { timestamp, number: last_block_num, ..Default::default() }; + return Head { timestamp, number: last_block_num, ..Default::default() } } Head { timestamp, ..Default::default() } } @@ -736,17 +736,17 @@ impl ChainSpec { ForkCondition::TTD { fork_block, .. } => { // handle Sepolia merge netsplit case if fork_block.is_some() { - return *fork_block; + return *fork_block } // ensure curr_cond is indeed ForkCondition::Block and return block_num if let ForkCondition::Block(block_num) = curr_cond { - return Some(block_num); + return Some(block_num) } } ForkCondition::Timestamp(_) => { // ensure curr_cond is indeed ForkCondition::Block and return block_num if let ForkCondition::Block(block_num) = curr_cond { - return Some(block_num); + return Some(block_num) } } ForkCondition::Block(_) | ForkCondition::Never => continue, @@ -1172,9 +1172,9 @@ impl ForkCondition { /// - The condition is satisfied by the timestamp; /// - or the condition is satisfied by the total difficulty pub fn active_at_head(&self, head: &Head) -> bool { - self.active_at_block(head.number) - || self.active_at_timestamp(head.timestamp) - || self.active_at_ttd(head.total_difficulty, head.difficulty) + self.active_at_block(head.number) || + self.active_at_timestamp(head.timestamp) || + self.active_at_ttd(head.total_difficulty, head.difficulty) } /// Get the total terminal difficulty for this fork condition. diff --git a/crates/primitives/src/revm/config.rs b/crates/primitives/src/revm/config.rs index 41c3857fa386..8e9619be40b7 100644 --- a/crates/primitives/src/revm/config.rs +++ b/crates/primitives/src/revm/config.rs @@ -142,7 +142,6 @@ mod tests { f(cs).build() } - // TODO: Enable once `reth` has been updated to a revm version that knows about Canyon. assert_eq!( revm_spec(&op_cs(|cs| cs.canyon_activated()), Head::default()), revm_primitives::CANYON diff --git a/crates/primitives/src/snapshot/segment.rs b/crates/primitives/src/snapshot/segment.rs index 90145f14fef6..879255fa6acf 100644 --- a/crates/primitives/src/snapshot/segment.rs +++ b/crates/primitives/src/snapshot/segment.rs @@ -117,7 +117,7 @@ impl SnapshotSegment { ) -> Option<(Self, RangeInclusive, RangeInclusive)> { let mut parts = name.to_str()?.split('_'); if parts.next() != Some("snapshot") { - return None; + return None } let segment = Self::from_str(parts.next()?).ok()?; @@ -125,7 +125,7 @@ impl SnapshotSegment { let (tx_start, tx_end) = (parts.next()?.parse().ok()?, parts.next()?.parse().ok()?); if block_start >= block_end || tx_start > tx_end { - return None; + return None } Some((segment, block_start..=block_end, tx_start..=tx_end)) diff --git a/crates/rpc/rpc-types/src/serde_helpers/json_u256.rs b/crates/rpc/rpc-types/src/serde_helpers/json_u256.rs index 3ed3859a2c84..a22280e8a884 100644 --- a/crates/rpc/rpc-types/src/serde_helpers/json_u256.rs +++ b/crates/rpc/rpc-types/src/serde_helpers/json_u256.rs @@ -162,11 +162,11 @@ where } else { // We could try to convert to a u128 here but there would probably be loss of // precision, so we just return an error. - return Err(Error::custom("Deserializing a large non-mainnet TTD is not supported")); + return Err(Error::custom("Deserializing a large non-mainnet TTD is not supported")) } } else { // must be i64 - negative numbers are not supported - return Err(Error::custom("Negative TTD values are invalid and will not be deserialized")); + return Err(Error::custom("Negative TTD values are invalid and will not be deserialized")) }; Ok(num) diff --git a/crates/transaction-pool/src/pool/blob.rs b/crates/transaction-pool/src/pool/blob.rs index 24c1fa6cade4..e7f6fa8f2448 100644 --- a/crates/transaction-pool/src/pool/blob.rs +++ b/crates/transaction-pool/src/pool/blob.rs @@ -290,7 +290,7 @@ const LOG_2_1_125: f64 = 0.16992500144231237; pub fn fee_delta(max_tx_fee: u128, current_fee: u128) -> i64 { if max_tx_fee == current_fee { // if these are equal, then there's no fee jump - return 0; + return 0 } let max_tx_fee_jumps = if max_tx_fee == 0 { From b713caded232de5dbf63919ee9f6335a6acd25d4 Mon Sep 17 00:00:00 2001 From: clabby Date: Thu, 23 Nov 2023 18:19:30 -0500 Subject: [PATCH 06/14] @rkrasiuk review --- crates/primitives/src/chain/spec.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/crates/primitives/src/chain/spec.rs b/crates/primitives/src/chain/spec.rs index 37d242bff072..e953b079875f 100644 --- a/crates/primitives/src/chain/spec.rs +++ b/crates/primitives/src/chain/spec.rs @@ -1048,6 +1048,7 @@ impl ChainSpecBuilder { #[cfg(feature = "optimism")] pub fn canyon_activated(mut self) -> Self { self = self.regolith_activated(); + // Canyon also activates changes from L1's Shanghai hardfork self.hardforks.insert(Hardfork::Shanghai, ForkCondition::Timestamp(0)); self.hardforks.insert(Hardfork::Canyon, ForkCondition::Timestamp(0)); self @@ -1987,7 +1988,6 @@ Post-merge hard forks (timestamp based): #[cfg(feature = "optimism")] #[test] - #[ignore] fn optimism_goerli_forkids() { test_fork_ids( &OP_GOERLI, @@ -1998,19 +1998,19 @@ Post-merge hard forks (timestamp based): ), ( Head { number: 4061224, timestamp: 1679079599, ..Default::default() }, - ForkId { hash: ForkHash([0x03, 0x47, 0x85, 0x69]), next: 1679079600 }, + ForkId { hash: ForkHash([0x03, 0x47, 0x85, 0x69]), next: 1699981200 }, ), ( Head { number: 4061225, timestamp: 1679079600, ..Default::default() }, - ForkId { hash: ForkHash([0x6d, 0x43, 0x1d, 0x6c]), next: 1699981200 }, + ForkId { hash: ForkHash([0x03, 0x47, 0x85, 0x69]), next: 1699981200 }, ), ( Head { number: 4061226, timestamp: 1699981199, ..Default::default() }, - ForkId { hash: ForkHash([0x6d, 0x43, 0x1d, 0x6c]), next: 1699981200 }, + ForkId { hash: ForkHash([0x03, 0x47, 0x85, 0x69]), next: 1699981200 }, ), ( Head { number: 4061227, timestamp: 1699981200, ..Default::default() }, - ForkId { hash: ForkHash([0x7f, 0x4a, 0x72, 0x1f]), next: 0 }, + ForkId { hash: ForkHash([0xb9, 0xe8, 0xc3, 0x20]), next: 0 }, ), ], ); @@ -2018,30 +2018,29 @@ Post-merge hard forks (timestamp based): #[cfg(feature = "optimism")] #[test] - #[ignore] fn base_goerli_forkids() { test_fork_ids( &BASE_GOERLI, &[ ( Head { number: 0, ..Default::default() }, - ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1683219600 }, + ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1699981200 }, ), ( Head { number: 1, timestamp: 1683219599, ..Default::default() }, - ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1683219600 }, + ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1699981200 }, ), ( Head { number: 2, timestamp: 1683219600, ..Default::default() }, - ForkId { hash: ForkHash([0xd5, 0x45, 0x43, 0x5d]), next: 1699981200 }, + ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1699981200 }, ), ( Head { number: 3, timestamp: 1699981199, ..Default::default() }, - ForkId { hash: ForkHash([0xd5, 0x45, 0x43, 0x5d]), next: 1699981200 }, + ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1699981200 }, ), ( Head { number: 4, timestamp: 1699981200, ..Default::default() }, - ForkId { hash: ForkHash([0xb3, 0x29, 0x13, 0xde]), next: 0 }, + ForkId { hash: ForkHash([0xff, 0x48, 0x53, 0x14]), next: 0 }, ), ], ); From b2f042b15eb2f12fd4f61848b90377b645a6c6ed Mon Sep 17 00:00:00 2001 From: clabby Date: Thu, 23 Nov 2023 19:47:17 -0500 Subject: [PATCH 07/14] Reorder hardforks --- crates/net/eth-wire/src/multiplex.rs | 2 +- crates/primitives/src/chain/spec.rs | 22 +++++++++++++--------- crates/primitives/src/hardfork.rs | 8 ++++---- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/crates/net/eth-wire/src/multiplex.rs b/crates/net/eth-wire/src/multiplex.rs index e3bb92ecad3a..f76be4fbe826 100644 --- a/crates/net/eth-wire/src/multiplex.rs +++ b/crates/net/eth-wire/src/multiplex.rs @@ -278,7 +278,7 @@ where return Poll::Ready(Some(Err(err.into()))) } } else { - break; + break } } Poll::Pending => { diff --git a/crates/primitives/src/chain/spec.rs b/crates/primitives/src/chain/spec.rs index e953b079875f..1e3917fef5f7 100644 --- a/crates/primitives/src/chain/spec.rs +++ b/crates/primitives/src/chain/spec.rs @@ -1996,21 +1996,25 @@ Post-merge hard forks (timestamp based): Head { number: 0, ..Default::default() }, ForkId { hash: ForkHash([0x6d, 0x63, 0x76, 0xbe]), next: 4061224 }, ), + ( + Head { number: 4061223, ..Default::default() }, + ForkId { hash: ForkHash([0x6d, 0x63, 0x76, 0xbe]), next: 4061224 }, + ), ( Head { number: 4061224, timestamp: 1679079599, ..Default::default() }, - ForkId { hash: ForkHash([0x03, 0x47, 0x85, 0x69]), next: 1699981200 }, + ForkId { hash: ForkHash([0x03, 0x47, 0x85, 0x69]), next: 1679079600 }, ), ( Head { number: 4061225, timestamp: 1679079600, ..Default::default() }, - ForkId { hash: ForkHash([0x03, 0x47, 0x85, 0x69]), next: 1699981200 }, + ForkId { hash: ForkHash([0x6d, 0x43, 0x1d, 0x6c]), next: 1699981200 }, ), ( Head { number: 4061226, timestamp: 1699981199, ..Default::default() }, - ForkId { hash: ForkHash([0x03, 0x47, 0x85, 0x69]), next: 1699981200 }, + ForkId { hash: ForkHash([0x6d, 0x43, 0x1d, 0x6c]), next: 1699981200 }, ), ( Head { number: 4061227, timestamp: 1699981200, ..Default::default() }, - ForkId { hash: ForkHash([0xb9, 0xe8, 0xc3, 0x20]), next: 0 }, + ForkId { hash: ForkHash([0x7f, 0x4a, 0x72, 0x1f]), next: 0 }, ), ], ); @@ -2024,23 +2028,23 @@ Post-merge hard forks (timestamp based): &[ ( Head { number: 0, ..Default::default() }, - ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1699981200 }, + ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1683219600 }, ), ( Head { number: 1, timestamp: 1683219599, ..Default::default() }, - ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1699981200 }, + ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1683219600 }, ), ( Head { number: 2, timestamp: 1683219600, ..Default::default() }, - ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1699981200 }, + ForkId { hash: ForkHash([0xd5, 0x45, 0x43, 0x5d]), next: 1699981200 }, ), ( Head { number: 3, timestamp: 1699981199, ..Default::default() }, - ForkId { hash: ForkHash([0xd4, 0x0c, 0x23, 0x50]), next: 1699981200 }, + ForkId { hash: ForkHash([0xd5, 0x45, 0x43, 0x5d]), next: 1699981200 }, ), ( Head { number: 4, timestamp: 1699981200, ..Default::default() }, - ForkId { hash: ForkHash([0xff, 0x48, 0x53, 0x14]), next: 0 }, + ForkId { hash: ForkHash([0xb3, 0x29, 0x13, 0xde]), next: 0 }, ), ], ); diff --git a/crates/primitives/src/hardfork.rs b/crates/primitives/src/hardfork.rs index e94e86f07d01..793499610187 100644 --- a/crates/primitives/src/hardfork.rs +++ b/crates/primitives/src/hardfork.rs @@ -37,19 +37,19 @@ pub enum Hardfork { GrayGlacier, /// Paris. Paris, - /// Shanghai. - Shanghai, - /// Cancun. - Cancun, /// Bedrock. #[cfg(feature = "optimism")] Bedrock, /// Regolith #[cfg(feature = "optimism")] Regolith, + /// Shanghai. + Shanghai, /// Canyon #[cfg(feature = "optimism")] Canyon, + /// Cancun. + Cancun, } impl Hardfork { From d70264e92c35b645892aaf9a305483d32d955859 Mon Sep 17 00:00:00 2001 From: clabby Date: Mon, 20 Nov 2023 14:10:45 -0500 Subject: [PATCH 08/14] (op-reth) Fix receipts root hashing bug in the Canyon hardfork --- crates/consensus/auto-seal/src/lib.rs | 20 +- crates/payload/basic/src/lib.rs | 42 +- crates/payload/basic/src/optimism.rs | 20 +- crates/primitives/src/proofs.rs | 502 ++++++++++-------- crates/primitives/src/receipt.rs | 17 +- crates/revm/src/optimism/processor.rs | 20 +- crates/revm/src/processor.rs | 30 +- crates/rpc/rpc/src/eth/api/pending_block.rs | 18 +- .../bundle_state_with_receipts.rs | 21 +- 9 files changed, 400 insertions(+), 290 deletions(-) diff --git a/crates/consensus/auto-seal/src/lib.rs b/crates/consensus/auto-seal/src/lib.rs index 2065f2e188f9..3f2c40d0b163 100644 --- a/crates/consensus/auto-seal/src/lib.rs +++ b/crates/consensus/auto-seal/src/lib.rs @@ -333,6 +333,7 @@ impl StorageInner { bundle_state: &BundleStateWithReceipts, client: &S, gas_used: u64, + #[cfg(feature = "optimism")] chain_spec: Arc, ) -> Result { let receipts = bundle_state.receipts_by_block(header.number); header.receipts_root = if receipts.is_empty() { @@ -344,7 +345,13 @@ impl StorageInner { .collect::>(); header.logs_bloom = receipts_with_bloom.iter().fold(Bloom::ZERO, |bloom, r| bloom | r.bloom); - proofs::calculate_receipt_root(&receipts_with_bloom) + proofs::calculate_receipt_root( + &receipts_with_bloom, + #[cfg(feature = "optimism")] + chain_spec, + #[cfg(feature = "optimism")] + header.timestamp, + ) }; header.gas_used = gas_used; @@ -382,7 +389,7 @@ impl StorageInner { .with_database_boxed(Box::new(StateProviderDatabase::new(client.latest().unwrap()))) .with_bundle_update() .build(); - let mut executor = EVMProcessor::new_with_state(chain_spec, db); + let mut executor = EVMProcessor::new_with_state(chain_spec.clone(), db); let (bundle_state, gas_used) = self.execute(&block, &mut executor, senders)?; @@ -392,7 +399,14 @@ impl StorageInner { trace!(target: "consensus::auto", ?bundle_state, ?header, ?body, "executed block, calculating state root and completing header"); // fill in the rest of the fields - let header = self.complete_header(header, &bundle_state, client, gas_used)?; + let header = self.complete_header( + header, + &bundle_state, + client, + gas_used, + #[cfg(feature = "optimism")] + chain_spec, + )?; trace!(target: "consensus::auto", root=?header.state_root, ?body, "calculated root"); diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 0bc30049f5ab..3cca9873784a 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -341,7 +341,7 @@ where // check if the deadline is reached if this.deadline.as_mut().poll(cx).is_ready() { trace!(target: "payload_builder", "payload building deadline reached"); - return Poll::Ready(Ok(())) + return Poll::Ready(Ok(())); } // check if the interval is reached @@ -426,7 +426,7 @@ where fn best_payload(&self) -> Result, PayloadBuilderError> { if let Some(ref payload) = self.best_payload { - return Ok(payload.clone()) + return Ok(payload.clone()); } // No payload has been built yet, but we need to return something that the CL then can // deliver, so we need to return an empty payload. @@ -464,8 +464,8 @@ where // upfront with the list of transactions sent in the attributes without caring about // the results of the polling job, if a best payload has not already been built. #[cfg(feature = "optimism")] - if self.config.chain_spec.is_optimism() && - self.config.attributes.optimism_payload_attributes.no_tx_pool + if self.config.chain_spec.is_optimism() + && self.config.attributes.optimism_payload_attributes.no_tx_pool { let args = BuildArguments { client: self.client.clone(), @@ -488,7 +488,7 @@ where empty_payload, }, KeepPayloadJobAlive::Yes, - ) + ); } } @@ -531,13 +531,13 @@ impl Future for ResolveBestPayload { if let Poll::Ready(res) = fut.poll(cx) { this.maybe_better = None; if let Ok(BuildOutcome::Better { payload, .. }) = res { - return Poll::Ready(Ok(Arc::new(payload))) + return Poll::Ready(Ok(Arc::new(payload))); } } } if let Some(best) = this.best_payload.take() { - return Poll::Ready(Ok(best)) + return Poll::Ready(Ok(best)); } let mut empty_payload = this.empty_payload.take().expect("polled after completion"); @@ -618,7 +618,7 @@ impl PayloadConfig { pub(crate) fn extra_data(&self) -> reth_primitives::Bytes { #[cfg(feature = "optimism")] if self.chain_spec.is_optimism() { - return Default::default() + return Default::default(); } self.extra_data.clone() } @@ -801,12 +801,12 @@ where // which also removes all dependent transaction from the iterator before we can // continue best_txs.mark_invalid(&pool_tx); - continue + continue; } // check if the job was cancelled, if so we can exit early if cancel.is_cancelled() { - return Ok(BuildOutcome::Cancelled) + return Ok(BuildOutcome::Cancelled); } // convert tx to a signed transaction @@ -822,7 +822,7 @@ where // the gas limit condition for regular transactions above. trace!(target: "payload_builder", tx=?tx.hash, ?sum_blob_gas_used, ?tx_blob_gas, "skipping blob transaction because it would exceed the max data gas per block"); best_txs.mark_invalid(&pool_tx); - continue + continue; } } @@ -851,11 +851,11 @@ where best_txs.mark_invalid(&pool_tx); } - continue + continue; } err => { // this is an error that we should treat as fatal for this attempt - return Err(PayloadBuilderError::EvmExecutionError(err)) + return Err(PayloadBuilderError::EvmExecutionError(err)); } } } @@ -903,7 +903,7 @@ where // check if we have a better block if !is_better_payload(best_payload.as_deref(), total_fees) { // can skip building the block - return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }) + return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }); } let WithdrawalsOutcome { withdrawals_root, withdrawals } = @@ -918,7 +918,15 @@ where Receipts::from_vec(vec![receipts]), block_number, ); - let receipts_root = bundle.receipts_root_slow(block_number).expect("Number is in range"); + let receipts_root = bundle + .receipts_root_slow( + block_number, + #[cfg(feature = "optimism")] + chain_spec.clone(), + #[cfg(feature = "optimism")] + attributes.timestamp, + ) + .expect("Number is in range"); let logs_bloom = bundle.block_logs_bloom(block_number).expect("Number is in range"); // calculate the state root @@ -1101,11 +1109,11 @@ fn commit_withdrawals>( withdrawals: Vec, ) -> RethResult { if !chain_spec.is_shanghai_active_at_timestamp(timestamp) { - return Ok(WithdrawalsOutcome::pre_shanghai()) + return Ok(WithdrawalsOutcome::pre_shanghai()); } if withdrawals.is_empty() { - return Ok(WithdrawalsOutcome::empty()) + return Ok(WithdrawalsOutcome::empty()); } let balance_increments = diff --git a/crates/payload/basic/src/optimism.rs b/crates/payload/basic/src/optimism.rs index 19f62db1dedd..06511ffec1bb 100644 --- a/crates/payload/basic/src/optimism.rs +++ b/crates/payload/basic/src/optimism.rs @@ -58,7 +58,7 @@ where for sequencer_tx in attributes.optimism_payload_attributes.transactions { // Check if the job was cancelled, if so we can exit early. if cancel.is_cancelled() { - return Ok(BuildOutcome::Cancelled) + return Ok(BuildOutcome::Cancelled); } // Convert the transaction to a [TransactionSignedEcRecovered]. This is @@ -102,11 +102,11 @@ where match err { EVMError::Transaction(err) => { trace!(target: "optimism_payload_builder", ?err, ?sequencer_tx, "Error in sequencer transaction, skipping."); - continue + continue; } err => { // this is an error that we should treat as fatal for this attempt - return Err(PayloadBuilderError::EvmExecutionError(err)) + return Err(PayloadBuilderError::EvmExecutionError(err)); } } } @@ -142,12 +142,12 @@ where // which also removes all dependent transaction from the iterator before we can // continue best_txs.mark_invalid(&pool_tx); - continue + continue; } // check if the job was cancelled, if so we can exit early if cancel.is_cancelled() { - return Ok(BuildOutcome::Cancelled) + return Ok(BuildOutcome::Cancelled); } // convert tx to a signed transaction @@ -178,11 +178,11 @@ where best_txs.mark_invalid(&pool_tx); } - continue + continue; } err => { // this is an error that we should treat as fatal for this attempt - return Err(PayloadBuilderError::EvmExecutionError(err)) + return Err(PayloadBuilderError::EvmExecutionError(err)); } } } @@ -220,7 +220,7 @@ where // check if we have a better block if !is_better_payload(best_payload.as_deref(), total_fees) { // can skip building the block - return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }) + return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }); } let WithdrawalsOutcome { withdrawals_root, withdrawals } = @@ -235,7 +235,9 @@ where Receipts::from_vec(vec![receipts]), block_number, ); - let receipts_root = bundle.receipts_root_slow(block_number).expect("Number is in range"); + let receipts_root = bundle + .receipts_root_slow(block_number, chain_spec.clone(), attributes.timestamp) + .expect("Number is in range"); let logs_bloom = bundle.block_logs_bloom(block_number).expect("Number is in range"); // calculate the state root diff --git a/crates/primitives/src/proofs.rs b/crates/primitives/src/proofs.rs index 6bf4ab8f0eac..3cda3a3c63cf 100644 --- a/crates/primitives/src/proofs.rs +++ b/crates/primitives/src/proofs.rs @@ -69,13 +69,20 @@ pub fn calculate_withdrawals_root(withdrawals: &[Withdrawal]) -> B256 { } /// Calculates the receipt root for a header. -pub fn calculate_receipt_root(receipts: &[ReceiptWithBloom]) -> B256 { +pub fn calculate_receipt_root( + receipts: &[ReceiptWithBloom], + #[cfg(feature = "optimism")] chain_spec: std::sync::Arc, + #[cfg(feature = "optimism")] timestamp: u64, +) -> B256 { + // There is a minor bug in op-geth and op-erigon where in the Regolith hardfork, + // the receipt root calculation does not include the deposit nonce in the receipt + // encoding. In the Regolith Hardfork, we must strip the deposit nonce from the + // receipts before calculating the receipt root. This was corrected in the Canyon + // hardfork. #[cfg(feature = "optimism")] + if chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Regolith, timestamp) + && !chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Canyon, timestamp) { - // There is a minor bug in op-geth and op-erigon where in the Regolith hardfork, - // the receipt root calculation does not include the deposit nonce in the receipt - // encoding. This will be fixd in the next hardfork, however for now, we must strip - // the deposit nonce from the receipts before calculating the receipt root. let receipts = receipts .iter() .cloned() @@ -85,23 +92,31 @@ pub fn calculate_receipt_root(receipts: &[ReceiptWithBloom]) -> B256 { }) .collect::>(); - ordered_trie_root_with_encoder(receipts.as_slice(), |r, buf| r.encode_inner(buf, false)) + return ordered_trie_root_with_encoder(receipts.as_slice(), |r, buf| { + r.encode_inner(buf, false) + }); } - #[cfg(not(feature = "optimism"))] ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_inner(buf, false)) } /// Calculates the receipt root for a header for the reference type of [Receipt]. /// /// NOTE: Prefer [calculate_receipt_root] if you have log blooms memoized. -pub fn calculate_receipt_root_ref(receipts: &[&Receipt]) -> B256 { +pub fn calculate_receipt_root_ref( + receipts: &[&Receipt], + #[cfg(feature = "optimism")] chain_spec: std::sync::Arc, + #[cfg(feature = "optimism")] timestamp: u64, +) -> B256 { + // There is a minor bug in op-geth and op-erigon where in the Regolith hardfork, + // the receipt root calculation does not include the deposit nonce in the receipt + // encoding. In the Regolith Hardfork, we must strip the deposit nonce from the + // receipts before calculating the receipt root. This was corrected in the Canyon + // hardfork. #[cfg(feature = "optimism")] + if chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Regolith, timestamp) + && !chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Canyon, timestamp) { - // There is a minor bug in op-geth and op-erigon where in the Regolith hardfork, - // the receipt root calculation does not include the deposit nonce in the receipt - // encoding. This will be fixd in the next hardfork, however for now, we must strip - // the deposit nonce from the receipts before calculating the receipt root. let receipts = receipts .iter() .map(|r| { @@ -111,12 +126,11 @@ pub fn calculate_receipt_root_ref(receipts: &[&Receipt]) -> B256 { }) .collect::>(); - ordered_trie_root_with_encoder(&receipts, |r, buf| { + return ordered_trie_root_with_encoder(&receipts, |r, buf| { ReceiptWithBloomRef::from(r).encode_inner(buf, false) - }) + }); } - #[cfg(not(feature = "optimism"))] ordered_trie_root_with_encoder(receipts, |r, buf| { ReceiptWithBloomRef::from(*r).encode_inner(buf, false) }) @@ -126,7 +140,7 @@ pub fn calculate_receipt_root_ref(receipts: &[&Receipt]) -> B256 { pub fn calculate_ommers_root(ommers: &[Header]) -> B256 { // Check if `ommers` list is empty if ommers.is_empty() { - return EMPTY_OMMER_ROOT_HASH + return EMPTY_OMMER_ROOT_HASH; } // RLP Encode let mut ommers_rlp = Vec::new(); @@ -212,222 +226,248 @@ mod tests { #[cfg(feature = "optimism")] #[test] fn check_optimism_receipt_root() { - use crate::{Bloom, Bytes}; - - let receipts = vec![ - // 0xb0d6ee650637911394396d81172bd1c637d568ed1fbddab0daddfca399c58b53 - ReceiptWithBloom { - receipt: Receipt { - tx_type: TxType::DEPOSIT, - success: true, - cumulative_gas_used: 46913, - logs: vec![], - #[cfg(feature = "optimism")] - deposit_nonce: Some(4012991u64), + use crate::{Bloom, Bytes, OP_GOERLI}; + + let cases = [ + // Deposit nonces didn't exist in Bedrock; No need to strip. For the purposes of this + // test, we do have them, so we should get the same root as Canyon. + ( + "bedrock", + 1679079599, + b256!("6eefbb5efb95235476654a8bfbf8cb64a4f5f0b0c80b700b0c5964550beee6d7"), + ), + // Deposit nonces introduced in Regolith. They weren't included in the receipt RLP, + // so we need to strip them - the receipt root will differ. + ( + "regolith", + 1679079600, + b256!("e255fed45eae7ede0556fe4fabc77b0d294d18781a5a581cab09127bc4cd9ffb"), + ), + // Receipt root hashing bug fixed in Canyon. Back to including the deposit nonce + // in the receipt RLP when computing the receipt root. + ( + "canyon", + 1699981200, + b256!("6eefbb5efb95235476654a8bfbf8cb64a4f5f0b0c80b700b0c5964550beee6d7"), + ), + ]; + + for case in cases { + let receipts = vec![ + // 0xb0d6ee650637911394396d81172bd1c637d568ed1fbddab0daddfca399c58b53 + ReceiptWithBloom { + receipt: Receipt { + tx_type: TxType::DEPOSIT, + success: true, + cumulative_gas_used: 46913, + logs: vec![], + #[cfg(feature = "optimism")] + deposit_nonce: Some(4012991u64), + }, + bloom: Bloom(hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into()), }, - bloom: Bloom(hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into()), - }, - // 0x2f433586bae30573c393adfa02bc81d2a1888a3d6c9869f473fb57245166bd9a - ReceiptWithBloom { - receipt: Receipt { - tx_type: TxType::EIP1559, - success: true, - cumulative_gas_used: 118083, - logs: vec![ - Log { - address: hex!("ddb6dcce6b794415145eb5caa6cd335aeda9c272").into(), - topics: vec![ -b256!("c3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62"), -b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"), -b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"), -b256!("0000000000000000000000000000000000000000000000000000000000000000"), - ], - data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001")), - }, - Log { - address: hex!("ddb6dcce6b794415145eb5caa6cd335aeda9c272").into(), - topics: vec![ -b256!("c3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62"), -b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"), -b256!("0000000000000000000000000000000000000000000000000000000000000000"), -b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"), - ], - data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001")), - }, - Log { - address: hex!("ddb6dcce6b794415145eb5caa6cd335aeda9c272").into(), - topics: vec![ -b256!("0eb774bb9698a73583fe07b6972cf2dcc08d1d97581a22861f45feb86b395820"), -b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"), -b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"), - ], -data: Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000000000000000003")), - }, - ], - #[cfg(feature = "optimism")] - deposit_nonce: None, + // 0x2f433586bae30573c393adfa02bc81d2a1888a3d6c9869f473fb57245166bd9a + ReceiptWithBloom { + receipt: Receipt { + tx_type: TxType::EIP1559, + success: true, + cumulative_gas_used: 118083, + logs: vec![ + Log { + address: hex!("ddb6dcce6b794415145eb5caa6cd335aeda9c272").into(), + topics: vec![ + b256!("c3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62"), + b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"), + b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"), + b256!("0000000000000000000000000000000000000000000000000000000000000000"), + ], + data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001")), + }, + Log { + address: hex!("ddb6dcce6b794415145eb5caa6cd335aeda9c272").into(), + topics: vec![ + b256!("c3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62"), + b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"), + b256!("0000000000000000000000000000000000000000000000000000000000000000"), + b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"), + ], + data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001")), + }, + Log { + address: hex!("ddb6dcce6b794415145eb5caa6cd335aeda9c272").into(), + topics: vec![ + b256!("0eb774bb9698a73583fe07b6972cf2dcc08d1d97581a22861f45feb86b395820"), + b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"), + b256!("000000000000000000000000c498902843af527e674846bb7edefa8ad62b8fb9"), + ], + data: Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000000000000000003")), + }, + ], + #[cfg(feature = "optimism")] + deposit_nonce: None, + }, + bloom: Bloom(hex!("00001000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000040000000000004000000000080000000000000000000000000000000000000000000000000000008000000000000080020000000000000000000000000002000000000000000000000000000080000010000").into()), }, - bloom: Bloom(hex!("00001000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000040000000000004000000000080000000000000000000000000000000000000000000000000000008000000000000080020000000000000000000000000002000000000000000000000000000080000010000").into()), - }, - // 0x6c33676e8f6077f46a62eabab70bc6d1b1b18a624b0739086d77093a1ecf8266 - ReceiptWithBloom { - receipt: Receipt { - tx_type: TxType::EIP1559, - success: true, - cumulative_gas_used: 189253, - logs: vec![ - Log { - address: hex!("ddb6dcce6b794415145eb5caa6cd335aeda9c272").into(), - topics: vec![ -b256!("c3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62"), -b256!("0000000000000000000000009d521a04bee134ff8136d2ec957e5bc8c50394ec"), -b256!("0000000000000000000000009d521a04bee134ff8136d2ec957e5bc8c50394ec"), -b256!("0000000000000000000000000000000000000000000000000000000000000000"), - ], - data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001")), - }, - Log { - address: hex!("ddb6dcce6b794415145eb5caa6cd335aeda9c272").into(), - topics: vec![ -b256!("c3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62"), -b256!("0000000000000000000000009d521a04bee134ff8136d2ec957e5bc8c50394ec"), -b256!("0000000000000000000000000000000000000000000000000000000000000000"), -b256!("0000000000000000000000009d521a04bee134ff8136d2ec957e5bc8c50394ec"), - ], - data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001")), - }, - Log { - address: hex!("ddb6dcce6b794415145eb5caa6cd335aeda9c272").into(), - topics: vec![ -b256!("0eb774bb9698a73583fe07b6972cf2dcc08d1d97581a22861f45feb86b395820"), -b256!("0000000000000000000000009d521a04bee134ff8136d2ec957e5bc8c50394ec"), -b256!("0000000000000000000000009d521a04bee134ff8136d2ec957e5bc8c50394ec"), - ], -data: Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000000000000000003")), - }, - ], - #[cfg(feature = "optimism")] - deposit_nonce: None, + // 0x6c33676e8f6077f46a62eabab70bc6d1b1b18a624b0739086d77093a1ecf8266 + ReceiptWithBloom { + receipt: Receipt { + tx_type: TxType::EIP1559, + success: true, + cumulative_gas_used: 189253, + logs: vec![ + Log { + address: hex!("ddb6dcce6b794415145eb5caa6cd335aeda9c272").into(), + topics: vec![ + b256!("c3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62"), + b256!("0000000000000000000000009d521a04bee134ff8136d2ec957e5bc8c50394ec"), + b256!("0000000000000000000000009d521a04bee134ff8136d2ec957e5bc8c50394ec"), + b256!("0000000000000000000000000000000000000000000000000000000000000000"), + ], + data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001")), + }, + Log { + address: hex!("ddb6dcce6b794415145eb5caa6cd335aeda9c272").into(), + topics: vec![ + b256!("c3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62"), + b256!("0000000000000000000000009d521a04bee134ff8136d2ec957e5bc8c50394ec"), + b256!("0000000000000000000000000000000000000000000000000000000000000000"), + b256!("0000000000000000000000009d521a04bee134ff8136d2ec957e5bc8c50394ec"), + ], + data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001")), + }, + Log { + address: hex!("ddb6dcce6b794415145eb5caa6cd335aeda9c272").into(), + topics: vec![ + b256!("0eb774bb9698a73583fe07b6972cf2dcc08d1d97581a22861f45feb86b395820"), + b256!("0000000000000000000000009d521a04bee134ff8136d2ec957e5bc8c50394ec"), + b256!("0000000000000000000000009d521a04bee134ff8136d2ec957e5bc8c50394ec"), + ], + data: Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000000000000000003")), + }, + ], + #[cfg(feature = "optimism")] + deposit_nonce: None, + }, + bloom: Bloom(hex!("00000000000000000000200000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000002000000000020000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000040000000000004000000000080000000000000000000000000000000000000000000000000000008000000000000080020000000000000000000000000002000000000000000000000000000080000000000").into()), }, - bloom: Bloom(hex!("00000000000000000000200000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000002000000000020000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000040000000000004000000000080000000000000000000000000000000000000000000000000000008000000000000080020000000000000000000000000002000000000000000000000000000080000000000").into()), - }, - // 0x4d3ecbef04ba7ce7f5ab55be0c61978ca97c117d7da448ed9771d4ff0c720a3f - ReceiptWithBloom { - receipt: Receipt { - tx_type: TxType::EIP1559, - success: true, - cumulative_gas_used: 346969, - logs: vec![ - Log { - address: hex!("4200000000000000000000000000000000000006").into(), - topics: vec![ -b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), -b256!("000000000000000000000000c3feb4ef4c2a5af77add15c95bd98f6b43640cc8"), -b256!("0000000000000000000000002992607c1614484fe6d865088e5c048f0650afd4"), - ], -data: Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000018de76816d8000")), - }, - Log { - address: hex!("cf8e7e6b26f407dee615fc4db18bf829e7aa8c09").into(), - topics: vec![ -b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), -b256!("0000000000000000000000002992607c1614484fe6d865088e5c048f0650afd4"), -b256!("0000000000000000000000008dbffe4c8bf3caf5deae3a99b50cfcf3648cbc09"), - ], -data: Bytes::from_static(&hex!("000000000000000000000000000000000000000000000002d24d8e9ac1aa79e2")), - }, - Log { - address: hex!("2992607c1614484fe6d865088e5c048f0650afd4").into(), - topics: vec![ -b256!("1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"), - ], - data: Bytes::from_static(&hex!("000000000000000000000000000000000000000000000009bd50642785c15736000000000000000000000000000000000000000000011bb7ac324f724a29bbbf")), - }, - Log { - address: hex!("2992607c1614484fe6d865088e5c048f0650afd4").into(), - topics: vec![ -b256!("d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"), -b256!("00000000000000000000000029843613c7211d014f5dd5718cf32bcd314914cb"), -b256!("0000000000000000000000008dbffe4c8bf3caf5deae3a99b50cfcf3648cbc09"), - ], - data: Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d24d8e9ac1aa79e2")), - }, - Log { - address: hex!("6d0f8d488b669aa9ba2d0f0b7b75a88bf5051cd3").into(), - topics: vec![ -b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), -b256!("0000000000000000000000008dbffe4c8bf3caf5deae3a99b50cfcf3648cbc09"), -b256!("000000000000000000000000c3feb4ef4c2a5af77add15c95bd98f6b43640cc8"), - ], - data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000000014bc73062aea8093")), - }, - Log { - address: hex!("8dbffe4c8bf3caf5deae3a99b50cfcf3648cbc09").into(), - topics: vec![ -b256!("1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"), - ], - data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000002f122cfadc1ca82a35000000000000000000000000000000000000000000000665879dc0609945d6d1")), - }, - Log { - address: hex!("8dbffe4c8bf3caf5deae3a99b50cfcf3648cbc09").into(), - topics: vec![ -b256!("d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"), -b256!("00000000000000000000000029843613c7211d014f5dd5718cf32bcd314914cb"), -b256!("000000000000000000000000c3feb4ef4c2a5af77add15c95bd98f6b43640cc8"), - ], - data: Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d24d8e9ac1aa79e200000000000000000000000000000000000000000000000014bc73062aea80930000000000000000000000000000000000000000000000000000000000000000")), - }, - ], - #[cfg(feature = "optimism")] - deposit_nonce: None, + // 0x4d3ecbef04ba7ce7f5ab55be0c61978ca97c117d7da448ed9771d4ff0c720a3f + ReceiptWithBloom { + receipt: Receipt { + tx_type: TxType::EIP1559, + success: true, + cumulative_gas_used: 346969, + logs: vec![ + Log { + address: hex!("4200000000000000000000000000000000000006").into(), + topics: vec![ + b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + b256!("000000000000000000000000c3feb4ef4c2a5af77add15c95bd98f6b43640cc8"), + b256!("0000000000000000000000002992607c1614484fe6d865088e5c048f0650afd4"), + ], + data: Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000018de76816d8000")), + }, + Log { + address: hex!("cf8e7e6b26f407dee615fc4db18bf829e7aa8c09").into(), + topics: vec![ + b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + b256!("0000000000000000000000002992607c1614484fe6d865088e5c048f0650afd4"), + b256!("0000000000000000000000008dbffe4c8bf3caf5deae3a99b50cfcf3648cbc09"), + ], + data: Bytes::from_static(&hex!("000000000000000000000000000000000000000000000002d24d8e9ac1aa79e2")), + }, + Log { + address: hex!("2992607c1614484fe6d865088e5c048f0650afd4").into(), + topics: vec![ + b256!("1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"), + ], + data: Bytes::from_static(&hex!("000000000000000000000000000000000000000000000009bd50642785c15736000000000000000000000000000000000000000000011bb7ac324f724a29bbbf")), + }, + Log { + address: hex!("2992607c1614484fe6d865088e5c048f0650afd4").into(), + topics: vec![ + b256!("d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"), + b256!("00000000000000000000000029843613c7211d014f5dd5718cf32bcd314914cb"), + b256!("0000000000000000000000008dbffe4c8bf3caf5deae3a99b50cfcf3648cbc09"), + ], + data: Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000018de76816d800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d24d8e9ac1aa79e2")), + }, + Log { + address: hex!("6d0f8d488b669aa9ba2d0f0b7b75a88bf5051cd3").into(), + topics: vec![ + b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + b256!("0000000000000000000000008dbffe4c8bf3caf5deae3a99b50cfcf3648cbc09"), + b256!("000000000000000000000000c3feb4ef4c2a5af77add15c95bd98f6b43640cc8"), + ], + data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000000014bc73062aea8093")), + }, + Log { + address: hex!("8dbffe4c8bf3caf5deae3a99b50cfcf3648cbc09").into(), + topics: vec![ + b256!("1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1"), + ], + data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000002f122cfadc1ca82a35000000000000000000000000000000000000000000000665879dc0609945d6d1")), + }, + Log { + address: hex!("8dbffe4c8bf3caf5deae3a99b50cfcf3648cbc09").into(), + topics: vec![ + b256!("d78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"), + b256!("00000000000000000000000029843613c7211d014f5dd5718cf32bcd314914cb"), + b256!("000000000000000000000000c3feb4ef4c2a5af77add15c95bd98f6b43640cc8"), + ], + data: Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d24d8e9ac1aa79e200000000000000000000000000000000000000000000000014bc73062aea80930000000000000000000000000000000000000000000000000000000000000000")), + }, + ], + #[cfg(feature = "optimism")] + deposit_nonce: None, + }, + bloom: Bloom(hex!("00200000000000000000000080000000000000000000000000040000100004000000000000000000000000100000000000000000000000000000100000000000000000000000000002000008000000200000000200000000020000000000000040000000000000000400000200000000000000000000000000000010000000000400000000010400000000000000000000000000002000c80000004080002000000000000000400200000000800000000000000000000000000000000000000000000002000000000000000000000000000000000100001000000000000000000000002000000000000000000000010000000000000000000000800000800000").into()), }, - bloom: Bloom(hex!("00200000000000000000000080000000000000000000000000040000100004000000000000000000000000100000000000000000000000000000100000000000000000000000000002000008000000200000000200000000020000000000000040000000000000000400000200000000000000000000000000000010000000000400000000010400000000000000000000000000002000c80000004080002000000000000000400200000000800000000000000000000000000000000000000000000002000000000000000000000000000000000100001000000000000000000000002000000000000000000000010000000000000000000000800000800000").into()), - }, - // 0xf738af5eb00ba23dbc1be2dbce41dbc0180f0085b7fb46646e90bf737af90351 - ReceiptWithBloom { - receipt: Receipt { - tx_type: TxType::EIP1559, - success: true, - cumulative_gas_used: 623249, - logs: vec![ - Log { - address: hex!("ac6564f3718837caadd42eed742d75c12b90a052").into(), - topics: vec![ -b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), -b256!("0000000000000000000000000000000000000000000000000000000000000000"), -b256!("000000000000000000000000a4fa7f3fbf0677f254ebdb1646146864c305b76e"), -b256!("000000000000000000000000000000000000000000000000000000000011a1d3"), - ], - data: Default::default(), - }, - Log { - address: hex!("ac6564f3718837caadd42eed742d75c12b90a052").into(), - topics: vec![ -b256!("9d89e36eadf856db0ad9ffb5a569e07f95634dddd9501141ecf04820484ad0dc"), -b256!("000000000000000000000000a4fa7f3fbf0677f254ebdb1646146864c305b76e"), -b256!("000000000000000000000000000000000000000000000000000000000011a1d3"), - ], - data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000037697066733a2f2f516d515141646b33736538396b47716577395256567a316b68643548375562476d4d4a485a62566f386a6d346f4a2f30000000000000000000")), - }, - Log { - address: hex!("ac6564f3718837caadd42eed742d75c12b90a052").into(), - topics: vec![ -b256!("110d160a1bedeea919a88fbc4b2a9fb61b7e664084391b6ca2740db66fef80fe"), -b256!("00000000000000000000000084d47f6eea8f8d87910448325519d1bb45c2972a"), -b256!("000000000000000000000000a4fa7f3fbf0677f254ebdb1646146864c305b76e"), -b256!("000000000000000000000000000000000000000000000000000000000011a1d3"), - ], - data: Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a4fa7f3fbf0677f254ebdb1646146864c305b76e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007717500762343034303661353035646234633961386163316433306335633332303265370000000000000000000000000000000000000000000000000000000000000037697066733a2f2f516d515141646b33736538396b47716577395256567a316b68643548375562476d4d4a485a62566f386a6d346f4a2f30000000000000000000")), - }, - ], - #[cfg(feature = "optimism")] - deposit_nonce: None, + // 0xf738af5eb00ba23dbc1be2dbce41dbc0180f0085b7fb46646e90bf737af90351 + ReceiptWithBloom { + receipt: Receipt { + tx_type: TxType::EIP1559, + success: true, + cumulative_gas_used: 623249, + logs: vec![ + Log { + address: hex!("ac6564f3718837caadd42eed742d75c12b90a052").into(), + topics: vec![ + b256!("ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), + b256!("0000000000000000000000000000000000000000000000000000000000000000"), + b256!("000000000000000000000000a4fa7f3fbf0677f254ebdb1646146864c305b76e"), + b256!("000000000000000000000000000000000000000000000000000000000011a1d3"), + ], + data: Default::default(), + }, + Log { + address: hex!("ac6564f3718837caadd42eed742d75c12b90a052").into(), + topics: vec![ + b256!("9d89e36eadf856db0ad9ffb5a569e07f95634dddd9501141ecf04820484ad0dc"), + b256!("000000000000000000000000a4fa7f3fbf0677f254ebdb1646146864c305b76e"), + b256!("000000000000000000000000000000000000000000000000000000000011a1d3"), + ], + data: Bytes::from_static(&hex!("00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000037697066733a2f2f516d515141646b33736538396b47716577395256567a316b68643548375562476d4d4a485a62566f386a6d346f4a2f30000000000000000000")), + }, + Log { + address: hex!("ac6564f3718837caadd42eed742d75c12b90a052").into(), + topics: vec![ + b256!("110d160a1bedeea919a88fbc4b2a9fb61b7e664084391b6ca2740db66fef80fe"), + b256!("00000000000000000000000084d47f6eea8f8d87910448325519d1bb45c2972a"), + b256!("000000000000000000000000a4fa7f3fbf0677f254ebdb1646146864c305b76e"), + b256!("000000000000000000000000000000000000000000000000000000000011a1d3"), + ], + data: Bytes::from_static(&hex!("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a4fa7f3fbf0677f254ebdb1646146864c305b76e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007717500762343034303661353035646234633961386163316433306335633332303265370000000000000000000000000000000000000000000000000000000000000037697066733a2f2f516d515141646b33736538396b47716577395256567a316b68643548375562476d4d4a485a62566f386a6d346f4a2f30000000000000000000")), + }, + ], + #[cfg(feature = "optimism")] + deposit_nonce: None, + }, + bloom: Bloom(hex!("00000000000000000000000000000000400000000000000000000000000000000000004000000000000001000000000000000002000000000100000000000000000000000000000000000008000000000000000000000000000000000000000004000000020000000000000000000800000000000000000000000010200100200008000002000000000000000000800000000000000000000002000000000000000000000000000000080000000000000000000000004000000000000000000000000002000000000000000000000000000000000000200000000000000020002000000000000000002000000000000000000000000000000000000000000000").into()), }, - bloom: Bloom(hex!("00000000000000000000000000000000400000000000000000000000000000000000004000000000000001000000000000000002000000000100000000000000000000000000000000000008000000000000000000000000000000000000000004000000020000000000000000000800000000000000000000000010200100200008000002000000000000000000800000000000000000000002000000000000000000000000000000080000000000000000000000004000000000000000000000000002000000000000000000000000000000000000200000000000000020002000000000000000002000000000000000000000000000000000000000000000").into()), - }, - ]; - let root = calculate_receipt_root(&receipts); - assert_eq!(root, b256!("e255fed45eae7ede0556fe4fabc77b0d294d18781a5a581cab09127bc4cd9ffb")) + ]; + let root = calculate_receipt_root(&receipts, OP_GOERLI.clone(), case.1); + assert_eq!(root, case.2); + } } #[test] @@ -446,7 +486,13 @@ b256!("000000000000000000000000000000000000000000000000000000000011a1d3"), bloom, }; let receipt = vec![receipt]; - let root = calculate_receipt_root(&receipt); + let root = calculate_receipt_root( + &receipt, + #[cfg(feature = "optimism")] + crate::OP_GOERLI.clone(), + #[cfg(feature = "optimism")] + 0, + ); assert_eq!(root, b256!("fe70ae4a136d98944951b2123859698d59ad251a381abc9960fa81cae3d0d4a0")); } diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 4b2fdd182f68..951678a9d3c4 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -88,9 +88,18 @@ impl Receipts { } /// Retrieves the receipt root for all recorded receipts from index. - pub fn root_slow(&self, index: usize) -> Option { + pub fn root_slow( + &self, + index: usize, + #[cfg(feature = "optimism")] chain_spec: std::sync::Arc, + #[cfg(feature = "optimism")] timestamp: u64, + ) -> Option { Some(calculate_receipt_root_ref( &self.receipt_vec[index].iter().map(Option::as_ref).collect::>>()?, + #[cfg(feature = "optimism")] + chain_spec, + #[cfg(feature = "optimism")] + timestamp, )) } @@ -247,7 +256,7 @@ impl ReceiptWithBloom { let b = &mut &**buf; let rlp_head = alloy_rlp::Header::decode(b)?; if !rlp_head.list { - return Err(alloy_rlp::Error::UnexpectedString) + return Err(alloy_rlp::Error::UnexpectedString); } let started_len = b.len(); @@ -282,7 +291,7 @@ impl ReceiptWithBloom { return Err(alloy_rlp::Error::ListLengthMismatch { expected: rlp_head.payload_length, got: consumed, - }) + }); } *buf = *b; Ok(this) @@ -429,7 +438,7 @@ impl<'a> ReceiptWithBloomEncoder<'a> { fn encode_inner(&self, out: &mut dyn BufMut, with_header: bool) { if matches!(self.receipt.tx_type, TxType::Legacy) { self.encode_fields(out); - return + return; } let mut payload = BytesMut::new(); diff --git a/crates/revm/src/optimism/processor.rs b/crates/revm/src/optimism/processor.rs index cfdc0660d141..ee236a0f15b8 100644 --- a/crates/revm/src/optimism/processor.rs +++ b/crates/revm/src/optimism/processor.rs @@ -36,11 +36,15 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { // See more about EIP here: https://eips.ethereum.org/EIPS/eip-658 if self.chain_spec.fork(Hardfork::Byzantium).active_at_block(block.header.number) { let time = Instant::now(); - if let Err(error) = - verify_receipt(block.header.receipts_root, block.header.logs_bloom, receipts.iter()) - { + if let Err(error) = verify_receipt( + block.header.receipts_root, + block.header.logs_bloom, + receipts.iter(), + self.chain_spec.clone(), + block.timestamp, + ) { debug!(target: "evm", ?error, ?receipts, "receipts verification failed"); - return Err(error) + return Err(error); }; self.stats.receipt_root_duration += time.elapsed(); } @@ -58,7 +62,7 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { // perf: do not execute empty blocks if block.body.is_empty() { - return Ok((Vec::new(), 0)) + return Ok((Vec::new(), 0)); } let senders = self.recover_senders(&block.body, senders)?; @@ -73,14 +77,14 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { // The sum of the transaction’s gas limit, Tg, and the gas utilized in this block prior, // must be no greater than the block’s gasLimit. let block_available_gas = block.header.gas_limit - cumulative_gas_used; - if transaction.gas_limit() > block_available_gas && - (is_regolith || !transaction.is_system_transaction()) + if transaction.gas_limit() > block_available_gas + && (is_regolith || !transaction.is_system_transaction()) { return Err(BlockValidationError::TransactionGasLimitMoreThanAvailableBlockGas { transaction_gas_limit: transaction.gas_limit(), block_available_gas, } - .into()) + .into()); } // Cache the depositor account prior to the state transition for the deposit nonce. diff --git a/crates/revm/src/processor.rs b/crates/revm/src/processor.rs index 1f30ef4dd985..a59b6840c51b 100644 --- a/crates/revm/src/processor.rs +++ b/crates/revm/src/processor.rs @@ -300,7 +300,7 @@ impl<'a> EVMProcessor<'a> { gas: GotExpected { got: cumulative_gas_used, expected: block.gas_used }, gas_spent_by_tx: receipts.gas_spent_by_tx()?, } - .into()) + .into()); } let time = Instant::now(); self.apply_post_execution_state_change(block, total_difficulty)?; @@ -311,8 +311,8 @@ impl<'a> EVMProcessor<'a> { !self .prune_modes .account_history - .map_or(false, |mode| mode.should_prune(block.number, tip)) && - !self + .map_or(false, |mode| mode.should_prune(block.number, tip)) + && !self .prune_modes .storage_history .map_or(false, |mode| mode.should_prune(block.number, tip)) @@ -359,7 +359,7 @@ impl<'a> EVMProcessor<'a> { self.prune_modes.receipts.map_or(false, |mode| mode.should_prune(block_number, tip)) { receipts.clear(); - return Ok(()) + return Ok(()); } // All receipts from the last 128 blocks are required for blockchain tree, even with @@ -367,7 +367,7 @@ impl<'a> EVMProcessor<'a> { let prunable_receipts = PruneMode::Distance(MINIMUM_PRUNING_DISTANCE).should_prune(block_number, tip); if !prunable_receipts { - return Ok(()) + return Ok(()); } let contract_log_pruner = self.prune_modes.receipts_log_filter.group_by_block(tip, None)?; @@ -427,7 +427,7 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { verify_receipt(block.header.receipts_root, block.header.logs_bloom, receipts.iter()) { debug!(target: "evm", ?error, ?receipts, "receipts verification failed"); - return Err(error) + return Err(error); }; self.stats.receipt_root_duration += time.elapsed(); } @@ -445,7 +445,7 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { // perf: do not execute empty blocks if block.body.is_empty() { - return Ok((Vec::new(), 0)) + return Ok((Vec::new(), 0)); } let senders = self.recover_senders(&block.body, senders)?; @@ -462,7 +462,7 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { transaction_gas_limit: transaction.gas_limit(), block_available_gas, } - .into()) + .into()); } // Execute transaction. let ResultAndState { result, state } = self.transact(transaction, sender)?; @@ -531,15 +531,23 @@ pub fn verify_receipt<'a>( expected_receipts_root: B256, expected_logs_bloom: Bloom, receipts: impl Iterator + Clone, + #[cfg(feature = "optimism")] chain_spec: Arc, + #[cfg(feature = "optimism")] timestamp: u64, ) -> Result<(), BlockExecutionError> { // Check receipts root. let receipts_with_bloom = receipts.map(|r| r.clone().into()).collect::>(); - let receipts_root = reth_primitives::proofs::calculate_receipt_root(&receipts_with_bloom); + let receipts_root = reth_primitives::proofs::calculate_receipt_root( + &receipts_with_bloom, + #[cfg(feature = "optimism")] + chain_spec, + #[cfg(feature = "optimism")] + timestamp, + ); if receipts_root != expected_receipts_root { return Err(BlockValidationError::ReceiptRootDiff( GotExpected { got: receipts_root, expected: expected_receipts_root }.into(), ) - .into()) + .into()); } // Create header log bloom. @@ -548,7 +556,7 @@ pub fn verify_receipt<'a>( return Err(BlockValidationError::BloomLogDiff( GotExpected { got: logs_bloom, expected: expected_logs_bloom }.into(), ) - .into()) + .into()); } Ok(()) diff --git a/crates/rpc/rpc/src/eth/api/pending_block.rs b/crates/rpc/rpc/src/eth/api/pending_block.rs index 3c6f6b58793c..092c99602b87 100644 --- a/crates/rpc/rpc/src/eth/api/pending_block.rs +++ b/crates/rpc/rpc/src/eth/api/pending_block.rs @@ -98,7 +98,7 @@ impl PendingBlockEnv { // which also removes all dependent transaction from the iterator before we can // continue best_txs.mark_invalid(&pool_tx); - continue + continue; } // convert tx to a signed transaction @@ -114,7 +114,7 @@ impl PendingBlockEnv { // the iterator. This is similar to the gas limit condition // for regular transactions above. best_txs.mark_invalid(&pool_tx); - continue + continue; } } @@ -137,11 +137,11 @@ impl PendingBlockEnv { // descendants best_txs.mark_invalid(&pool_tx); } - continue + continue; } err => { // this is an error that we should treat as fatal for this attempt - return Err(err.into()) + return Err(err.into()); } } } @@ -201,7 +201,15 @@ impl PendingBlockEnv { block_number, ); - let receipts_root = bundle.receipts_root_slow(block_number).expect("Block is present"); + let receipts_root = bundle + .receipts_root_slow( + block_number, + #[cfg(feature = "optimism")] + chain_spec.clone(), + #[cfg(feature = "optimism")] + block_env.timestamp.to::(), + ) + .expect("Block is present"); let logs_bloom = bundle.block_logs_bloom(block_number).expect("Block is present"); // calculate the state root diff --git a/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs b/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs index 2a65909fdb65..b76bda6bac20 100644 --- a/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs +++ b/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs @@ -227,11 +227,11 @@ impl BundleStateWithReceipts { /// Transform block number to the index of block. fn block_number_to_index(&self, block_number: BlockNumber) -> Option { if self.first_block > block_number { - return None + return None; } let index = block_number - self.first_block; if index >= self.receipts.len() as u64 { - return None + return None; } Some(index as usize) } @@ -250,8 +250,19 @@ impl BundleStateWithReceipts { /// Returns the receipt root for all recorded receipts. /// Note: this function calculated Bloom filters for every receipt and created merkle trees /// of receipt. This is a expensive operation. - pub fn receipts_root_slow(&self, block_number: BlockNumber) -> Option { - self.receipts.root_slow(self.block_number_to_index(block_number)?) + pub fn receipts_root_slow( + &self, + block_number: BlockNumber, + #[cfg(feature = "optimism")] chain_spec: std::sync::Arc, + #[cfg(feature = "optimism")] timestamp: u64, + ) -> Option { + self.receipts.root_slow( + self.block_number_to_index(block_number)?, + #[cfg(feature = "optimism")] + chain_spec, + #[cfg(feature = "optimism")] + timestamp, + ) } /// Return reference to receipts. @@ -310,7 +321,7 @@ impl BundleStateWithReceipts { /// If the target block number is not included in the state block range. pub fn split_at(self, at: BlockNumber) -> (Option, Self) { if at == self.first_block { - return (None, self) + return (None, self); } let (mut lower_state, mut higher_state) = (self.clone(), self); From 59c39c1d42db6090cb538e73beb4767d54736b7f Mon Sep 17 00:00:00 2001 From: clabby Date: Mon, 20 Nov 2023 14:14:04 -0500 Subject: [PATCH 09/14] fmt --- crates/payload/basic/src/lib.rs | 4 ++-- crates/primitives/src/proofs.rs | 8 ++++---- crates/revm/src/optimism/processor.rs | 4 ++-- crates/revm/src/processor.rs | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 3cca9873784a..6bfad0ad7c3d 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -464,8 +464,8 @@ where // upfront with the list of transactions sent in the attributes without caring about // the results of the polling job, if a best payload has not already been built. #[cfg(feature = "optimism")] - if self.config.chain_spec.is_optimism() - && self.config.attributes.optimism_payload_attributes.no_tx_pool + if self.config.chain_spec.is_optimism() && + self.config.attributes.optimism_payload_attributes.no_tx_pool { let args = BuildArguments { client: self.client.clone(), diff --git a/crates/primitives/src/proofs.rs b/crates/primitives/src/proofs.rs index 3cda3a3c63cf..ad625a4bdbbe 100644 --- a/crates/primitives/src/proofs.rs +++ b/crates/primitives/src/proofs.rs @@ -80,8 +80,8 @@ pub fn calculate_receipt_root( // receipts before calculating the receipt root. This was corrected in the Canyon // hardfork. #[cfg(feature = "optimism")] - if chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Regolith, timestamp) - && !chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Canyon, timestamp) + if chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Regolith, timestamp) && + !chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Canyon, timestamp) { let receipts = receipts .iter() @@ -114,8 +114,8 @@ pub fn calculate_receipt_root_ref( // receipts before calculating the receipt root. This was corrected in the Canyon // hardfork. #[cfg(feature = "optimism")] - if chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Regolith, timestamp) - && !chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Canyon, timestamp) + if chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Regolith, timestamp) && + !chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Canyon, timestamp) { let receipts = receipts .iter() diff --git a/crates/revm/src/optimism/processor.rs b/crates/revm/src/optimism/processor.rs index ee236a0f15b8..95b7fc2f5110 100644 --- a/crates/revm/src/optimism/processor.rs +++ b/crates/revm/src/optimism/processor.rs @@ -77,8 +77,8 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { // The sum of the transaction’s gas limit, Tg, and the gas utilized in this block prior, // must be no greater than the block’s gasLimit. let block_available_gas = block.header.gas_limit - cumulative_gas_used; - if transaction.gas_limit() > block_available_gas - && (is_regolith || !transaction.is_system_transaction()) + if transaction.gas_limit() > block_available_gas && + (is_regolith || !transaction.is_system_transaction()) { return Err(BlockValidationError::TransactionGasLimitMoreThanAvailableBlockGas { transaction_gas_limit: transaction.gas_limit(), diff --git a/crates/revm/src/processor.rs b/crates/revm/src/processor.rs index a59b6840c51b..d8cd54025a21 100644 --- a/crates/revm/src/processor.rs +++ b/crates/revm/src/processor.rs @@ -311,8 +311,8 @@ impl<'a> EVMProcessor<'a> { !self .prune_modes .account_history - .map_or(false, |mode| mode.should_prune(block.number, tip)) - && !self + .map_or(false, |mode| mode.should_prune(block.number, tip)) && + !self .prune_modes .storage_history .map_or(false, |mode| mode.should_prune(block.number, tip)) From a68828f0d40a4d9391df7231645f65233158b265 Mon Sep 17 00:00:00 2001 From: clabby Date: Mon, 20 Nov 2023 20:21:14 -0500 Subject: [PATCH 10/14] Semicolon nuke --- crates/payload/basic/src/lib.rs | 28 +++++++++---------- crates/payload/basic/src/optimism.rs | 16 +++++------ crates/primitives/src/proofs.rs | 6 ++-- crates/primitives/src/receipt.rs | 6 ++-- crates/revm/src/optimism/processor.rs | 6 ++-- crates/revm/src/processor.rs | 16 +++++------ crates/rpc/rpc/src/eth/api/pending_block.rs | 8 +++--- .../bundle_state_with_receipts.rs | 6 ++-- 8 files changed, 46 insertions(+), 46 deletions(-) diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 6bfad0ad7c3d..0bcda4b9175e 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -341,7 +341,7 @@ where // check if the deadline is reached if this.deadline.as_mut().poll(cx).is_ready() { trace!(target: "payload_builder", "payload building deadline reached"); - return Poll::Ready(Ok(())); + return Poll::Ready(Ok(())) } // check if the interval is reached @@ -426,7 +426,7 @@ where fn best_payload(&self) -> Result, PayloadBuilderError> { if let Some(ref payload) = self.best_payload { - return Ok(payload.clone()); + return Ok(payload.clone()) } // No payload has been built yet, but we need to return something that the CL then can // deliver, so we need to return an empty payload. @@ -488,7 +488,7 @@ where empty_payload, }, KeepPayloadJobAlive::Yes, - ); + ) } } @@ -531,13 +531,13 @@ impl Future for ResolveBestPayload { if let Poll::Ready(res) = fut.poll(cx) { this.maybe_better = None; if let Ok(BuildOutcome::Better { payload, .. }) = res { - return Poll::Ready(Ok(Arc::new(payload))); + return Poll::Ready(Ok(Arc::new(payload))) } } } if let Some(best) = this.best_payload.take() { - return Poll::Ready(Ok(best)); + return Poll::Ready(Ok(best)) } let mut empty_payload = this.empty_payload.take().expect("polled after completion"); @@ -618,7 +618,7 @@ impl PayloadConfig { pub(crate) fn extra_data(&self) -> reth_primitives::Bytes { #[cfg(feature = "optimism")] if self.chain_spec.is_optimism() { - return Default::default(); + return Default::default() } self.extra_data.clone() } @@ -801,12 +801,12 @@ where // which also removes all dependent transaction from the iterator before we can // continue best_txs.mark_invalid(&pool_tx); - continue; + continue } // check if the job was cancelled, if so we can exit early if cancel.is_cancelled() { - return Ok(BuildOutcome::Cancelled); + return Ok(BuildOutcome::Cancelled) } // convert tx to a signed transaction @@ -822,7 +822,7 @@ where // the gas limit condition for regular transactions above. trace!(target: "payload_builder", tx=?tx.hash, ?sum_blob_gas_used, ?tx_blob_gas, "skipping blob transaction because it would exceed the max data gas per block"); best_txs.mark_invalid(&pool_tx); - continue; + continue } } @@ -851,11 +851,11 @@ where best_txs.mark_invalid(&pool_tx); } - continue; + continue } err => { // this is an error that we should treat as fatal for this attempt - return Err(PayloadBuilderError::EvmExecutionError(err)); + return Err(PayloadBuilderError::EvmExecutionError(err)) } } } @@ -903,7 +903,7 @@ where // check if we have a better block if !is_better_payload(best_payload.as_deref(), total_fees) { // can skip building the block - return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }); + return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }) } let WithdrawalsOutcome { withdrawals_root, withdrawals } = @@ -1109,11 +1109,11 @@ fn commit_withdrawals>( withdrawals: Vec, ) -> RethResult { if !chain_spec.is_shanghai_active_at_timestamp(timestamp) { - return Ok(WithdrawalsOutcome::pre_shanghai()); + return Ok(WithdrawalsOutcome::pre_shanghai()) } if withdrawals.is_empty() { - return Ok(WithdrawalsOutcome::empty()); + return Ok(WithdrawalsOutcome::empty()) } let balance_increments = diff --git a/crates/payload/basic/src/optimism.rs b/crates/payload/basic/src/optimism.rs index 06511ffec1bb..59feba96bcd9 100644 --- a/crates/payload/basic/src/optimism.rs +++ b/crates/payload/basic/src/optimism.rs @@ -58,7 +58,7 @@ where for sequencer_tx in attributes.optimism_payload_attributes.transactions { // Check if the job was cancelled, if so we can exit early. if cancel.is_cancelled() { - return Ok(BuildOutcome::Cancelled); + return Ok(BuildOutcome::Cancelled) } // Convert the transaction to a [TransactionSignedEcRecovered]. This is @@ -102,11 +102,11 @@ where match err { EVMError::Transaction(err) => { trace!(target: "optimism_payload_builder", ?err, ?sequencer_tx, "Error in sequencer transaction, skipping."); - continue; + continue } err => { // this is an error that we should treat as fatal for this attempt - return Err(PayloadBuilderError::EvmExecutionError(err)); + return Err(PayloadBuilderError::EvmExecutionError(err)) } } } @@ -142,12 +142,12 @@ where // which also removes all dependent transaction from the iterator before we can // continue best_txs.mark_invalid(&pool_tx); - continue; + continue } // check if the job was cancelled, if so we can exit early if cancel.is_cancelled() { - return Ok(BuildOutcome::Cancelled); + return Ok(BuildOutcome::Cancelled) } // convert tx to a signed transaction @@ -178,11 +178,11 @@ where best_txs.mark_invalid(&pool_tx); } - continue; + continue } err => { // this is an error that we should treat as fatal for this attempt - return Err(PayloadBuilderError::EvmExecutionError(err)); + return Err(PayloadBuilderError::EvmExecutionError(err)) } } } @@ -220,7 +220,7 @@ where // check if we have a better block if !is_better_payload(best_payload.as_deref(), total_fees) { // can skip building the block - return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }); + return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }) } let WithdrawalsOutcome { withdrawals_root, withdrawals } = diff --git a/crates/primitives/src/proofs.rs b/crates/primitives/src/proofs.rs index ad625a4bdbbe..7e56b7fd0562 100644 --- a/crates/primitives/src/proofs.rs +++ b/crates/primitives/src/proofs.rs @@ -94,7 +94,7 @@ pub fn calculate_receipt_root( return ordered_trie_root_with_encoder(receipts.as_slice(), |r, buf| { r.encode_inner(buf, false) - }); + }) } ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_inner(buf, false)) @@ -128,7 +128,7 @@ pub fn calculate_receipt_root_ref( return ordered_trie_root_with_encoder(&receipts, |r, buf| { ReceiptWithBloomRef::from(r).encode_inner(buf, false) - }); + }) } ordered_trie_root_with_encoder(receipts, |r, buf| { @@ -140,7 +140,7 @@ pub fn calculate_receipt_root_ref( pub fn calculate_ommers_root(ommers: &[Header]) -> B256 { // Check if `ommers` list is empty if ommers.is_empty() { - return EMPTY_OMMER_ROOT_HASH; + return EMPTY_OMMER_ROOT_HASH } // RLP Encode let mut ommers_rlp = Vec::new(); diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 951678a9d3c4..d5dcce1aaa6d 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -256,7 +256,7 @@ impl ReceiptWithBloom { let b = &mut &**buf; let rlp_head = alloy_rlp::Header::decode(b)?; if !rlp_head.list { - return Err(alloy_rlp::Error::UnexpectedString); + return Err(alloy_rlp::Error::UnexpectedString) } let started_len = b.len(); @@ -291,7 +291,7 @@ impl ReceiptWithBloom { return Err(alloy_rlp::Error::ListLengthMismatch { expected: rlp_head.payload_length, got: consumed, - }); + }) } *buf = *b; Ok(this) @@ -438,7 +438,7 @@ impl<'a> ReceiptWithBloomEncoder<'a> { fn encode_inner(&self, out: &mut dyn BufMut, with_header: bool) { if matches!(self.receipt.tx_type, TxType::Legacy) { self.encode_fields(out); - return; + return } let mut payload = BytesMut::new(); diff --git a/crates/revm/src/optimism/processor.rs b/crates/revm/src/optimism/processor.rs index 95b7fc2f5110..1b34df370183 100644 --- a/crates/revm/src/optimism/processor.rs +++ b/crates/revm/src/optimism/processor.rs @@ -44,7 +44,7 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { block.timestamp, ) { debug!(target: "evm", ?error, ?receipts, "receipts verification failed"); - return Err(error); + return Err(error) }; self.stats.receipt_root_duration += time.elapsed(); } @@ -62,7 +62,7 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { // perf: do not execute empty blocks if block.body.is_empty() { - return Ok((Vec::new(), 0)); + return Ok((Vec::new(), 0)) } let senders = self.recover_senders(&block.body, senders)?; @@ -84,7 +84,7 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { transaction_gas_limit: transaction.gas_limit(), block_available_gas, } - .into()); + .into()) } // Cache the depositor account prior to the state transition for the deposit nonce. diff --git a/crates/revm/src/processor.rs b/crates/revm/src/processor.rs index d8cd54025a21..bb251466e270 100644 --- a/crates/revm/src/processor.rs +++ b/crates/revm/src/processor.rs @@ -300,7 +300,7 @@ impl<'a> EVMProcessor<'a> { gas: GotExpected { got: cumulative_gas_used, expected: block.gas_used }, gas_spent_by_tx: receipts.gas_spent_by_tx()?, } - .into()); + .into()) } let time = Instant::now(); self.apply_post_execution_state_change(block, total_difficulty)?; @@ -359,7 +359,7 @@ impl<'a> EVMProcessor<'a> { self.prune_modes.receipts.map_or(false, |mode| mode.should_prune(block_number, tip)) { receipts.clear(); - return Ok(()); + return Ok(()) } // All receipts from the last 128 blocks are required for blockchain tree, even with @@ -367,7 +367,7 @@ impl<'a> EVMProcessor<'a> { let prunable_receipts = PruneMode::Distance(MINIMUM_PRUNING_DISTANCE).should_prune(block_number, tip); if !prunable_receipts { - return Ok(()); + return Ok(()) } let contract_log_pruner = self.prune_modes.receipts_log_filter.group_by_block(tip, None)?; @@ -427,7 +427,7 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { verify_receipt(block.header.receipts_root, block.header.logs_bloom, receipts.iter()) { debug!(target: "evm", ?error, ?receipts, "receipts verification failed"); - return Err(error); + return Err(error) }; self.stats.receipt_root_duration += time.elapsed(); } @@ -445,7 +445,7 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { // perf: do not execute empty blocks if block.body.is_empty() { - return Ok((Vec::new(), 0)); + return Ok((Vec::new(), 0)) } let senders = self.recover_senders(&block.body, senders)?; @@ -462,7 +462,7 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { transaction_gas_limit: transaction.gas_limit(), block_available_gas, } - .into()); + .into()) } // Execute transaction. let ResultAndState { result, state } = self.transact(transaction, sender)?; @@ -547,7 +547,7 @@ pub fn verify_receipt<'a>( return Err(BlockValidationError::ReceiptRootDiff( GotExpected { got: receipts_root, expected: expected_receipts_root }.into(), ) - .into()); + .into()) } // Create header log bloom. @@ -556,7 +556,7 @@ pub fn verify_receipt<'a>( return Err(BlockValidationError::BloomLogDiff( GotExpected { got: logs_bloom, expected: expected_logs_bloom }.into(), ) - .into()); + .into()) } Ok(()) diff --git a/crates/rpc/rpc/src/eth/api/pending_block.rs b/crates/rpc/rpc/src/eth/api/pending_block.rs index 092c99602b87..73349c0e5e1d 100644 --- a/crates/rpc/rpc/src/eth/api/pending_block.rs +++ b/crates/rpc/rpc/src/eth/api/pending_block.rs @@ -98,7 +98,7 @@ impl PendingBlockEnv { // which also removes all dependent transaction from the iterator before we can // continue best_txs.mark_invalid(&pool_tx); - continue; + continue } // convert tx to a signed transaction @@ -114,7 +114,7 @@ impl PendingBlockEnv { // the iterator. This is similar to the gas limit condition // for regular transactions above. best_txs.mark_invalid(&pool_tx); - continue; + continue } } @@ -137,11 +137,11 @@ impl PendingBlockEnv { // descendants best_txs.mark_invalid(&pool_tx); } - continue; + continue } err => { // this is an error that we should treat as fatal for this attempt - return Err(err.into()); + return Err(err.into()) } } } diff --git a/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs b/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs index b76bda6bac20..c522f0fd50b3 100644 --- a/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs +++ b/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs @@ -227,11 +227,11 @@ impl BundleStateWithReceipts { /// Transform block number to the index of block. fn block_number_to_index(&self, block_number: BlockNumber) -> Option { if self.first_block > block_number { - return None; + return None } let index = block_number - self.first_block; if index >= self.receipts.len() as u64 { - return None; + return None } Some(index as usize) } @@ -321,7 +321,7 @@ impl BundleStateWithReceipts { /// If the target block number is not included in the state block range. pub fn split_at(self, at: BlockNumber) -> (Option, Self) { if at == self.first_block { - return (None, self); + return (None, self) } let (mut lower_state, mut higher_state) = (self.clone(), self); From 3a97fce952c0f5660059da81e233abb359ce6e16 Mon Sep 17 00:00:00 2001 From: clabby Date: Fri, 24 Nov 2023 10:33:27 -0500 Subject: [PATCH 11/14] @mattsse review --- crates/consensus/auto-seal/src/lib.rs | 4 +-- crates/payload/basic/src/lib.rs | 2 +- crates/payload/basic/src/optimism.rs | 2 +- crates/primitives/src/proofs.rs | 32 ++++++++++++++----- crates/primitives/src/receipt.rs | 15 ++++++--- crates/revm/src/optimism/processor.rs | 2 +- crates/revm/src/processor.rs | 2 +- crates/rpc/rpc/src/eth/api/pending_block.rs | 2 +- .../bundle_state_with_receipts.rs | 21 ++++++------ 9 files changed, 54 insertions(+), 28 deletions(-) diff --git a/crates/consensus/auto-seal/src/lib.rs b/crates/consensus/auto-seal/src/lib.rs index 3f2c40d0b163..e2dfc9c91111 100644 --- a/crates/consensus/auto-seal/src/lib.rs +++ b/crates/consensus/auto-seal/src/lib.rs @@ -333,7 +333,7 @@ impl StorageInner { bundle_state: &BundleStateWithReceipts, client: &S, gas_used: u64, - #[cfg(feature = "optimism")] chain_spec: Arc, + #[cfg(feature = "optimism")] chain_spec: &ChainSpec, ) -> Result { let receipts = bundle_state.receipts_by_block(header.number); header.receipts_root = if receipts.is_empty() { @@ -405,7 +405,7 @@ impl StorageInner { client, gas_used, #[cfg(feature = "optimism")] - chain_spec, + chain_spec.as_ref(), )?; trace!(target: "consensus::auto", root=?header.state_root, ?body, "calculated root"); diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 0bcda4b9175e..3f806d5b50dd 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -922,7 +922,7 @@ where .receipts_root_slow( block_number, #[cfg(feature = "optimism")] - chain_spec.clone(), + chain_spec.as_ref(), #[cfg(feature = "optimism")] attributes.timestamp, ) diff --git a/crates/payload/basic/src/optimism.rs b/crates/payload/basic/src/optimism.rs index 59feba96bcd9..8fade69b7023 100644 --- a/crates/payload/basic/src/optimism.rs +++ b/crates/payload/basic/src/optimism.rs @@ -236,7 +236,7 @@ where block_number, ); let receipts_root = bundle - .receipts_root_slow(block_number, chain_spec.clone(), attributes.timestamp) + .receipts_root_slow(block_number, chain_spec.as_ref(), attributes.timestamp) .expect("Number is in range"); let logs_bloom = bundle.block_logs_bloom(block_number).expect("Number is in range"); diff --git a/crates/primitives/src/proofs.rs b/crates/primitives/src/proofs.rs index 7e56b7fd0562..0efc906397f4 100644 --- a/crates/primitives/src/proofs.rs +++ b/crates/primitives/src/proofs.rs @@ -69,17 +69,23 @@ pub fn calculate_withdrawals_root(withdrawals: &[Withdrawal]) -> B256 { } /// Calculates the receipt root for a header. +#[cfg(not(feature = "optimism"))] +pub fn calculate_receipt_root(receipts: &[ReceiptWithBloom]) -> B256 { + ordered_trie_root_with_encoder(receipts, |r, buf| r.encode_inner(buf, false)) +} + +/// Calculates the receipt root for a header. +#[cfg(feature = "optimism")] pub fn calculate_receipt_root( receipts: &[ReceiptWithBloom], - #[cfg(feature = "optimism")] chain_spec: std::sync::Arc, - #[cfg(feature = "optimism")] timestamp: u64, + chain_spec: &crate::ChainSpec, + timestamp: u64, ) -> B256 { // There is a minor bug in op-geth and op-erigon where in the Regolith hardfork, // the receipt root calculation does not include the deposit nonce in the receipt // encoding. In the Regolith Hardfork, we must strip the deposit nonce from the // receipts before calculating the receipt root. This was corrected in the Canyon // hardfork. - #[cfg(feature = "optimism")] if chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Regolith, timestamp) && !chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Canyon, timestamp) { @@ -103,17 +109,27 @@ pub fn calculate_receipt_root( /// Calculates the receipt root for a header for the reference type of [Receipt]. /// /// NOTE: Prefer [calculate_receipt_root] if you have log blooms memoized. +#[cfg(not(feature = "optimism"))] +pub fn calculate_receipt_root_ref(receipts: &[&Receipt]) -> B256 { + ordered_trie_root_with_encoder(receipts, |r, buf| { + ReceiptWithBloomRef::from(*r).encode_inner(buf, false) + }) +} + +/// Calculates the receipt root for a header for the reference type of [Receipt]. +/// +/// NOTE: Prefer [calculate_receipt_root] if you have log blooms memoized. +#[cfg(feature = "optimism")] pub fn calculate_receipt_root_ref( receipts: &[&Receipt], - #[cfg(feature = "optimism")] chain_spec: std::sync::Arc, - #[cfg(feature = "optimism")] timestamp: u64, + chain_spec: &crate::ChainSpec, + timestamp: u64, ) -> B256 { // There is a minor bug in op-geth and op-erigon where in the Regolith hardfork, // the receipt root calculation does not include the deposit nonce in the receipt // encoding. In the Regolith Hardfork, we must strip the deposit nonce from the // receipts before calculating the receipt root. This was corrected in the Canyon // hardfork. - #[cfg(feature = "optimism")] if chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Regolith, timestamp) && !chain_spec.is_fork_active_at_timestamp(crate::Hardfork::Canyon, timestamp) { @@ -465,7 +481,7 @@ mod tests { bloom: Bloom(hex!("00000000000000000000000000000000400000000000000000000000000000000000004000000000000001000000000000000002000000000100000000000000000000000000000000000008000000000000000000000000000000000000000004000000020000000000000000000800000000000000000000000010200100200008000002000000000000000000800000000000000000000002000000000000000000000000000000080000000000000000000000004000000000000000000000000002000000000000000000000000000000000000200000000000000020002000000000000000002000000000000000000000000000000000000000000000").into()), }, ]; - let root = calculate_receipt_root(&receipts, OP_GOERLI.clone(), case.1); + let root = calculate_receipt_root(&receipts, OP_GOERLI.as_ref(), case.1); assert_eq!(root, case.2); } } @@ -489,7 +505,7 @@ mod tests { let root = calculate_receipt_root( &receipt, #[cfg(feature = "optimism")] - crate::OP_GOERLI.clone(), + crate::OP_GOERLI.as_ref(), #[cfg(feature = "optimism")] 0, ); diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index d5dcce1aaa6d..b92b698f05d7 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -88,17 +88,24 @@ impl Receipts { } /// Retrieves the receipt root for all recorded receipts from index. + #[cfg(not(feature = "optimism"))] + pub fn root_slow(&self, index: usize) -> Option { + Some(calculate_receipt_root_ref( + &self.receipt_vec[index].iter().map(Option::as_ref).collect::>>()?, + )) + } + + /// Retrieves the receipt root for all recorded receipts from index. + #[cfg(feature = "optimism")] pub fn root_slow( &self, index: usize, - #[cfg(feature = "optimism")] chain_spec: std::sync::Arc, - #[cfg(feature = "optimism")] timestamp: u64, + chain_spec: &crate::ChainSpec, + timestamp: u64, ) -> Option { Some(calculate_receipt_root_ref( &self.receipt_vec[index].iter().map(Option::as_ref).collect::>>()?, - #[cfg(feature = "optimism")] chain_spec, - #[cfg(feature = "optimism")] timestamp, )) } diff --git a/crates/revm/src/optimism/processor.rs b/crates/revm/src/optimism/processor.rs index 1b34df370183..b238fd6452b1 100644 --- a/crates/revm/src/optimism/processor.rs +++ b/crates/revm/src/optimism/processor.rs @@ -40,7 +40,7 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { block.header.receipts_root, block.header.logs_bloom, receipts.iter(), - self.chain_spec.clone(), + self.chain_spec.as_ref(), block.timestamp, ) { debug!(target: "evm", ?error, ?receipts, "receipts verification failed"); diff --git a/crates/revm/src/processor.rs b/crates/revm/src/processor.rs index bb251466e270..0a4806e7d461 100644 --- a/crates/revm/src/processor.rs +++ b/crates/revm/src/processor.rs @@ -531,7 +531,7 @@ pub fn verify_receipt<'a>( expected_receipts_root: B256, expected_logs_bloom: Bloom, receipts: impl Iterator + Clone, - #[cfg(feature = "optimism")] chain_spec: Arc, + #[cfg(feature = "optimism")] chain_spec: &ChainSpec, #[cfg(feature = "optimism")] timestamp: u64, ) -> Result<(), BlockExecutionError> { // Check receipts root. diff --git a/crates/rpc/rpc/src/eth/api/pending_block.rs b/crates/rpc/rpc/src/eth/api/pending_block.rs index 73349c0e5e1d..7bd2053c9feb 100644 --- a/crates/rpc/rpc/src/eth/api/pending_block.rs +++ b/crates/rpc/rpc/src/eth/api/pending_block.rs @@ -205,7 +205,7 @@ impl PendingBlockEnv { .receipts_root_slow( block_number, #[cfg(feature = "optimism")] - chain_spec.clone(), + chain_spec.as_ref(), #[cfg(feature = "optimism")] block_env.timestamp.to::(), ) diff --git a/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs b/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs index c522f0fd50b3..6077a2f6560f 100644 --- a/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs +++ b/crates/storage/provider/src/bundle_state/bundle_state_with_receipts.rs @@ -250,19 +250,22 @@ impl BundleStateWithReceipts { /// Returns the receipt root for all recorded receipts. /// Note: this function calculated Bloom filters for every receipt and created merkle trees /// of receipt. This is a expensive operation. + #[cfg(not(feature = "optimism"))] + pub fn receipts_root_slow(&self, block_number: BlockNumber) -> Option { + self.receipts.root_slow(self.block_number_to_index(block_number)?) + } + + /// Returns the receipt root for all recorded receipts. + /// Note: this function calculated Bloom filters for every receipt and created merkle trees + /// of receipt. This is a expensive operation. + #[cfg(feature = "optimism")] pub fn receipts_root_slow( &self, block_number: BlockNumber, - #[cfg(feature = "optimism")] chain_spec: std::sync::Arc, - #[cfg(feature = "optimism")] timestamp: u64, + chain_spec: &reth_primitives::ChainSpec, + timestamp: u64, ) -> Option { - self.receipts.root_slow( - self.block_number_to_index(block_number)?, - #[cfg(feature = "optimism")] - chain_spec, - #[cfg(feature = "optimism")] - timestamp, - ) + self.receipts.root_slow(self.block_number_to_index(block_number)?, chain_spec, timestamp) } /// Return reference to receipts. From 4c1004c7a70e9f835a6a5487725075d1ac28e6ea Mon Sep 17 00:00:00 2001 From: clabby Date: Tue, 21 Nov 2023 19:30:07 -0500 Subject: [PATCH 12/14] Add deposit receipt version --- .../interfaces/src/test_utils/generators.rs | 2 + crates/net/eth-wire/src/types/receipts.rs | 6 + crates/payload/basic/src/lib.rs | 2 + crates/payload/basic/src/optimism.rs | 9 ++ crates/primitives/src/proofs.rs | 12 ++ crates/primitives/src/receipt.rs | 107 ++++++++++++++++-- crates/revm/src/optimism/processor.rs | 8 ++ crates/rpc/rpc/src/eth/api/pending_block.rs | 2 + .../storage/provider/src/test_utils/blocks.rs | 4 + 9 files changed, 142 insertions(+), 10 deletions(-) diff --git a/crates/interfaces/src/test_utils/generators.rs b/crates/interfaces/src/test_utils/generators.rs index a9328a4e695d..eed6e5c4a4a5 100644 --- a/crates/interfaces/src/test_utils/generators.rs +++ b/crates/interfaces/src/test_utils/generators.rs @@ -368,6 +368,8 @@ pub fn random_receipt( }, #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, } } diff --git a/crates/net/eth-wire/src/types/receipts.rs b/crates/net/eth-wire/src/types/receipts.rs index 215c9ea6cbbf..88a0a6e12616 100644 --- a/crates/net/eth-wire/src/types/receipts.rs +++ b/crates/net/eth-wire/src/types/receipts.rs @@ -50,6 +50,8 @@ mod test { logs: vec![], #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }, bloom: Default::default(), }]]); @@ -121,6 +123,8 @@ mod test { success: false, #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }, bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(), }, @@ -158,6 +162,8 @@ mod test { success: false, #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }, bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into(), }, diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 3f806d5b50dd..533651b7c55e 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -888,6 +888,8 @@ where logs: result.logs().into_iter().map(into_reth_log).collect(), #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, })); // update add to total fees diff --git a/crates/payload/basic/src/optimism.rs b/crates/payload/basic/src/optimism.rs index 8fade69b7023..19a73b07d2b5 100644 --- a/crates/payload/basic/src/optimism.rs +++ b/crates/payload/basic/src/optimism.rs @@ -128,6 +128,13 @@ where logs: result.logs().into_iter().map(into_reth_log).collect(), #[cfg(feature = "optimism")] deposit_nonce: depositor.map(|account| account.nonce), + // The deposit receipt version was introduced in Canyon to indicate an update to how + // receipt hashes should be computed when set. The state transition process + // ensures this is only set for post-Canyon deposit transactions. + #[cfg(feature = "optimism")] + deposit_receipt_version: chain_spec + .is_fork_active_at_timestamp(Hardfork::Canyon, attributes.timestamp) + .then_some(1), })); // append transaction to the list of executed transactions @@ -204,6 +211,8 @@ where logs: result.logs().into_iter().map(into_reth_log).collect(), #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, })); // update add to total fees diff --git a/crates/primitives/src/proofs.rs b/crates/primitives/src/proofs.rs index 0efc906397f4..f4851744fbf1 100644 --- a/crates/primitives/src/proofs.rs +++ b/crates/primitives/src/proofs.rs @@ -279,6 +279,8 @@ mod tests { logs: vec![], #[cfg(feature = "optimism")] deposit_nonce: Some(4012991u64), + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }, bloom: Bloom(hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").into()), }, @@ -321,6 +323,8 @@ mod tests { ], #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }, bloom: Bloom(hex!("00001000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000040000000000004000000000080000000000000000000000000000000000000000000000000000008000000000000080020000000000000000000000000002000000000000000000000000000080000010000").into()), }, @@ -363,6 +367,8 @@ mod tests { ], #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }, bloom: Bloom(hex!("00000000000000000000200000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000002000000000020000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000040000000000004000000000080000000000000000000000000000000000000000000000000000008000000000000080020000000000000000000000000002000000000000000000000000000080000000000").into()), }, @@ -435,6 +441,8 @@ mod tests { ], #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }, bloom: Bloom(hex!("00200000000000000000000080000000000000000000000000040000100004000000000000000000000000100000000000000000000000000000100000000000000000000000000002000008000000200000000200000000020000000000000040000000000000000400000200000000000000000000000000000010000000000400000000010400000000000000000000000000002000c80000004080002000000000000000400200000000800000000000000000000000000000000000000000000002000000000000000000000000000000000100001000000000000000000000002000000000000000000000010000000000000000000000800000800000").into()), }, @@ -477,6 +485,8 @@ mod tests { ], #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }, bloom: Bloom(hex!("00000000000000000000000000000000400000000000000000000000000000000000004000000000000001000000000000000002000000000100000000000000000000000000000000000008000000000000000000000000000000000000000004000000020000000000000000000800000000000000000000000010200100200008000002000000000000000000800000000000000000000002000000000000000000000000000000080000000000000000000000004000000000000000000000000002000000000000000000000000000000000000200000000000000020002000000000000000002000000000000000000000000000000000000000000000").into()), }, @@ -498,6 +508,8 @@ mod tests { logs, #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }, bloom, }; diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index b92b698f05d7..95f3b36108a4 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -30,9 +30,17 @@ pub struct Receipt { pub cumulative_gas_used: u64, /// Log send from contracts. pub logs: Vec, - /// Deposit nonce for Optimism deposited transactions + /// Deposit nonce for Optimism deposit transactions #[cfg(feature = "optimism")] pub deposit_nonce: Option, + /// Deposit receipt version for Optimism deposit transactions + /// + /// + /// The deposit receipt version was introduced in Canyon to indicate an update to how + /// receipt hashes should be computed when set. The state transition process + /// ensures this is only set for post-Canyon deposit transactions. + #[cfg(feature = "optimism")] + pub deposit_receipt_version: Option, } impl Receipt { @@ -210,15 +218,32 @@ impl proptest::arbitrary::Arbitrary for Receipt { success in any::(), cumulative_gas_used in any::(), logs in proptest::collection::vec(proptest::arbitrary::any::(), 0..=20), - _deposit_nonce in any::>()) -> Receipt + mut _deposit_nonce in any::>(), + _deposit_receipt_version in any::>()) -> Receipt { + // Only receipts for deposit transactions may contain a deposit nonce + #[cfg(feature = "optimism")] + let (deposit_nonce, deposit_receipt_version) = if tx_type == TxType::DEPOSIT { + // The deposit receipt version is only present if the deposit nonce is present + if _deposit_receipt_version.is_some() && _deposit_nonce.is_none() { + _deposit_nonce = _deposit_receipt_version; + } + (_deposit_nonce, _deposit_receipt_version) + } else { + (None, None) + }; + Receipt { tx_type, success, cumulative_gas_used, logs, // Only receipts for deposit transactions may contain a deposit nonce #[cfg(feature = "optimism")] - deposit_nonce: (tx_type == TxType::DEPOSIT).then_some(_deposit_nonce).flatten() + deposit_nonce, + // Only receipts for deposit transactions may contain a deposit nonce + #[cfg(feature = "optimism")] + deposit_receipt_version + } } }; @@ -238,8 +263,11 @@ impl<'a> arbitrary::Arbitrary<'a> for Receipt { // Only receipts for deposit transactions may contain a deposit nonce #[cfg(feature = "optimism")] - let deposit_nonce = - if tx_type == TxType::DEPOSIT { Option::::arbitrary(u)? } else { None }; + let (deposit_nonce, deposit_receipt_version) = if tx_type == TxType::DEPOSIT { + (Option::::arbitrary(u)?, Option::::arbitrary(u)?) + } else { + (None, None) + }; Ok(Self { tx_type, @@ -248,6 +276,8 @@ impl<'a> arbitrary::Arbitrary<'a> for Receipt { logs, #[cfg(feature = "optimism")] deposit_nonce, + #[cfg(feature = "optimism")] + deposit_receipt_version, }) } } @@ -275,12 +305,28 @@ impl ReceiptWithBloom { let receipt = match tx_type { #[cfg(feature = "optimism")] TxType::DEPOSIT => { - let consumed = started_len - b.len(); - let has_nonce = rlp_head.payload_length - consumed > 0; - let deposit_nonce = - if has_nonce { Some(alloy_rlp::Decodable::decode(b)?) } else { None }; + let has_deposit_nonce = rlp_head.payload_length - (started_len - b.len()) > 0; + let (deposit_nonce, deposit_receipt_version) = if has_deposit_nonce { + let deposit_nonce = Some(alloy_rlp::Decodable::decode(b)?); + let has_deposit_receipt_version = + rlp_head.payload_length - (started_len - b.len()) > 0; + if has_deposit_receipt_version { + (deposit_nonce, Some(alloy_rlp::Decodable::decode(b)?)) + } else { + (deposit_nonce, None) + } + } else { + (None, None) + }; - Receipt { tx_type, success, cumulative_gas_used, logs, deposit_nonce } + Receipt { + tx_type, + success, + cumulative_gas_used, + logs, + deposit_nonce, + deposit_receipt_version, + } } _ => Receipt { tx_type, @@ -289,6 +335,8 @@ impl ReceiptWithBloom { logs, #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }, }; @@ -421,6 +469,9 @@ impl<'a> ReceiptWithBloomEncoder<'a> { if let Some(deposit_nonce) = self.receipt.deposit_nonce { rlp_head.payload_length += deposit_nonce.length(); } + if let Some(deposit_receipt_version) = self.receipt.deposit_receipt_version { + rlp_head.payload_length += deposit_receipt_version.length(); + } } rlp_head @@ -438,6 +489,9 @@ impl<'a> ReceiptWithBloomEncoder<'a> { if let Some(deposit_nonce) = self.receipt.deposit_nonce { deposit_nonce.encode(out) } + if let Some(deposit_receipt_version) = self.receipt.deposit_receipt_version { + deposit_receipt_version.encode(out) + } } } @@ -528,6 +582,8 @@ mod tests { success: false, #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }, bloom: [0; 256].into(), }; @@ -560,6 +616,8 @@ mod tests { success: false, #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }, bloom: [0; 256].into(), }; @@ -581,6 +639,7 @@ mod tests { logs: vec![], success: true, deposit_nonce: Some(4012991), + deposit_receipt_version: None, }, bloom: [0; 256].into(), }; @@ -593,6 +652,32 @@ mod tests { assert_eq!(buf.freeze(), &data[..]); } + #[cfg(feature = "optimism")] + #[test] + fn decode_deposit_receipt_canyon_roundtrip() { + let data = hex!("7ef9010d0182b741b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0833d3bbf01"); + + // Deposit Receipt (post-regolith) + let expected = ReceiptWithBloom { + receipt: Receipt { + tx_type: TxType::DEPOSIT, + cumulative_gas_used: 46913, + logs: vec![], + success: true, + deposit_nonce: Some(4012991), + deposit_receipt_version: Some(1), + }, + bloom: [0; 256].into(), + }; + + let receipt = ReceiptWithBloom::decode(&mut &data[..]).unwrap(); + assert_eq!(receipt, expected); + + let mut buf = BytesMut::default(); + expected.encode_inner(&mut buf, false); + assert_eq!(buf.freeze(), &data[..]); + } + #[test] fn gigantic_receipt() { let receipt = Receipt { @@ -617,6 +702,8 @@ mod tests { ], #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, }; let mut data = vec![]; diff --git a/crates/revm/src/optimism/processor.rs b/crates/revm/src/optimism/processor.rs index b238fd6452b1..891a0d63f470 100644 --- a/crates/revm/src/optimism/processor.rs +++ b/crates/revm/src/optimism/processor.rs @@ -129,6 +129,14 @@ impl<'a> BlockExecutor for EVMProcessor<'a> { logs: result.into_logs().into_iter().map(into_reth_log).collect(), #[cfg(feature = "optimism")] deposit_nonce: depositor.map(|account| account.nonce), + // The deposit receipt version was introduced in Canyon to indicate an update to how + // receipt hashes should be computed when set. The state transition process ensures + // this is only set for post-Canyon deposit transactions. + #[cfg(feature = "optimism")] + deposit_receipt_version: self + .chain_spec() + .is_fork_active_at_timestamp(Hardfork::Canyon, block.timestamp) + .then_some(1), }); } diff --git a/crates/rpc/rpc/src/eth/api/pending_block.rs b/crates/rpc/rpc/src/eth/api/pending_block.rs index 7bd2053c9feb..32c2fdc252ad 100644 --- a/crates/rpc/rpc/src/eth/api/pending_block.rs +++ b/crates/rpc/rpc/src/eth/api/pending_block.rs @@ -174,6 +174,8 @@ impl PendingBlockEnv { logs: result.logs().into_iter().map(into_reth_log).collect(), #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, })); // append transaction to the list of executed transactions diff --git a/crates/storage/provider/src/test_utils/blocks.rs b/crates/storage/provider/src/test_utils/blocks.rs index 3162266bc781..562483b5e1d8 100644 --- a/crates/storage/provider/src/test_utils/blocks.rs +++ b/crates/storage/provider/src/test_utils/blocks.rs @@ -139,6 +139,8 @@ fn block1(number: BlockNumber) -> (SealedBlockWithSenders, BundleStateWithReceip }], #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, })]]), number, ); @@ -196,6 +198,8 @@ fn block2( }], #[cfg(feature = "optimism")] deposit_nonce: None, + #[cfg(feature = "optimism")] + deposit_receipt_version: None, })]]), number, ); From c27ab55ea2dce85bfade2ae0079b8c4aced82366 Mon Sep 17 00:00:00 2001 From: clabby Date: Wed, 22 Nov 2023 21:19:28 -0500 Subject: [PATCH 13/14] :broom: --- crates/primitives/src/receipt.rs | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 95f3b36108a4..d3858d690e01 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -218,17 +218,15 @@ impl proptest::arbitrary::Arbitrary for Receipt { success in any::(), cumulative_gas_used in any::(), logs in proptest::collection::vec(proptest::arbitrary::any::(), 0..=20), - mut _deposit_nonce in any::>(), + _deposit_nonce in any::>(), _deposit_receipt_version in any::>()) -> Receipt { // Only receipts for deposit transactions may contain a deposit nonce #[cfg(feature = "optimism")] let (deposit_nonce, deposit_receipt_version) = if tx_type == TxType::DEPOSIT { // The deposit receipt version is only present if the deposit nonce is present - if _deposit_receipt_version.is_some() && _deposit_nonce.is_none() { - _deposit_nonce = _deposit_receipt_version; - } - (_deposit_nonce, _deposit_receipt_version) + let deposit_receipt_version = _deposit_nonce.is_some().then_some(_deposit_receipt_version).flatten(); + (_deposit_nonce, deposit_receipt_version) } else { (None, None) }; @@ -243,7 +241,6 @@ impl proptest::arbitrary::Arbitrary for Receipt { // Only receipts for deposit transactions may contain a deposit nonce #[cfg(feature = "optimism")] deposit_receipt_version - } } }; @@ -264,7 +261,10 @@ impl<'a> arbitrary::Arbitrary<'a> for Receipt { // Only receipts for deposit transactions may contain a deposit nonce #[cfg(feature = "optimism")] let (deposit_nonce, deposit_receipt_version) = if tx_type == TxType::DEPOSIT { - (Option::::arbitrary(u)?, Option::::arbitrary(u)?) + let deposit_nonce = Option::::arbitrary(u)?; + let deposit_nonce_version = + deposit_nonce.is_some().then(|| Option::::arbitrary(u)).transpose()?.flatten(); + (deposit_nonce, deposit_nonce_version) } else { (None, None) }; @@ -305,19 +305,11 @@ impl ReceiptWithBloom { let receipt = match tx_type { #[cfg(feature = "optimism")] TxType::DEPOSIT => { - let has_deposit_nonce = rlp_head.payload_length - (started_len - b.len()) > 0; - let (deposit_nonce, deposit_receipt_version) = if has_deposit_nonce { - let deposit_nonce = Some(alloy_rlp::Decodable::decode(b)?); - let has_deposit_receipt_version = - rlp_head.payload_length - (started_len - b.len()) > 0; - if has_deposit_receipt_version { - (deposit_nonce, Some(alloy_rlp::Decodable::decode(b)?)) - } else { - (deposit_nonce, None) - } - } else { - (None, None) - }; + let remaining = |b: &[u8]| rlp_head.payload_length - (started_len - b.len()) > 0; + let deposit_nonce = + remaining(b).then(|| alloy_rlp::Decodable::decode(b)).transpose()?; + let deposit_receipt_version = + remaining(b).then(|| alloy_rlp::Decodable::decode(b)).transpose()?; Receipt { tx_type, From 7cef5ee332c236d35018dd7700217a8541a4e6d7 Mon Sep 17 00:00:00 2001 From: clabby Date: Thu, 23 Nov 2023 18:24:25 -0500 Subject: [PATCH 14/14] @rkasiuk review clippy --- crates/primitives/src/receipt.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index d3858d690e01..37c6fd37c13a 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -225,7 +225,7 @@ impl proptest::arbitrary::Arbitrary for Receipt { #[cfg(feature = "optimism")] let (deposit_nonce, deposit_receipt_version) = if tx_type == TxType::DEPOSIT { // The deposit receipt version is only present if the deposit nonce is present - let deposit_receipt_version = _deposit_nonce.is_some().then_some(_deposit_receipt_version).flatten(); + let deposit_receipt_version = _deposit_nonce.and(_deposit_receipt_version); (_deposit_nonce, deposit_receipt_version) } else { (None, None) @@ -263,7 +263,7 @@ impl<'a> arbitrary::Arbitrary<'a> for Receipt { let (deposit_nonce, deposit_receipt_version) = if tx_type == TxType::DEPOSIT { let deposit_nonce = Option::::arbitrary(u)?; let deposit_nonce_version = - deposit_nonce.is_some().then(|| Option::::arbitrary(u)).transpose()?.flatten(); + deposit_nonce.map(|_| Option::::arbitrary(u)).transpose()?.flatten(); (deposit_nonce, deposit_nonce_version) } else { (None, None)