Skip to content

Commit

Permalink
feat: add ReceiptBuilder for OpTransactionExecutor
Browse files Browse the repository at this point in the history
  • Loading branch information
klkvr committed Jan 13, 2025
1 parent df00877 commit 2e5808a
Show file tree
Hide file tree
Showing 12 changed files with 266 additions and 96 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/optimism/consensus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ reth-chainspec.workspace = true
reth-consensus-common.workspace = true
reth-consensus.workspace = true
reth-primitives.workspace = true
reth-primitives-traits.workspace = true

# op-reth
reth-optimism-forks.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/optimism/consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl FullConsensus<OpPrimitives> for OpBeaconConsensus {
block: &BlockWithSenders<OpBlock>,
input: PostExecutionInput<'_, OpReceipt>,
) -> Result<(), ConsensusError> {
validate_block_post_execution(block, &self.chain_spec, input.receipts)
validate_block_post_execution(&block.header, &self.chain_spec, input.receipts)
}
}

Expand Down
8 changes: 4 additions & 4 deletions crates/optimism/consensus/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ use alloy_primitives::B256;
use alloy_trie::root::ordered_trie_root_with_encoder;
use reth_chainspec::ChainSpec;
use reth_optimism_forks::{OpHardfork, OpHardforks};
use reth_optimism_primitives::OpReceipt;
use reth_optimism_primitives::{DepositReceipt, OpReceipt};
use reth_primitives::ReceiptWithBloom;

/// Calculates the receipt root for a header.
pub(crate) fn calculate_receipt_root_optimism(
receipts: &[ReceiptWithBloom<OpReceipt>],
pub(crate) fn calculate_receipt_root_optimism<R: DepositReceipt>(
receipts: &[ReceiptWithBloom<R>],
chain_spec: &ChainSpec,
timestamp: u64,
) -> B256 {
Expand All @@ -28,7 +28,7 @@ pub(crate) fn calculate_receipt_root_optimism(
.iter()
.cloned()
.map(|mut r| {
if let OpReceipt::Deposit(receipt) = &mut r.receipt {
if let Some(receipt) = r.receipt.as_deposit_receipt_mut() {
receipt.deposit_nonce = None;
}
r
Expand Down
28 changes: 14 additions & 14 deletions crates/optimism/consensus/src/validation.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
use crate::proof::calculate_receipt_root_optimism;
use alloc::vec::Vec;
use alloy_consensus::TxReceipt;
use alloy_consensus::{BlockHeader, TxReceipt};
use alloy_primitives::{Bloom, B256};
use reth_chainspec::{ChainSpec, EthereumHardforks};
use reth_consensus::ConsensusError;
use reth_optimism_primitives::{OpBlock, OpReceipt};
use reth_primitives::{gas_spent_by_transactions, BlockWithSenders, GotExpected};
use reth_optimism_primitives::DepositReceipt;
use reth_primitives::{gas_spent_by_transactions, GotExpected};

/// Validate a block with regard to execution results:
///
/// - Compares the receipts root in the block header to the block body
/// - Compares the gas used in the block header to the actual gas usage after execution
pub fn validate_block_post_execution(
block: &BlockWithSenders<OpBlock>,
pub fn validate_block_post_execution<R: DepositReceipt>(
header: impl BlockHeader,
chain_spec: &ChainSpec,
receipts: &[OpReceipt],
receipts: &[R],
) -> Result<(), ConsensusError> {
// Before Byzantium, receipts contained state root that would mean that expensive
// operation as hashing that is required for state root got calculated in every
// transaction This was replaced with is_success flag.
// See more about EIP here: https://eips.ethereum.org/EIPS/eip-658
if chain_spec.is_byzantium_active_at_block(block.header.number) {
if chain_spec.is_byzantium_active_at_block(header.number()) {
if let Err(error) = verify_receipts(
block.header.receipts_root,
block.header.logs_bloom,
header.receipts_root(),
header.logs_bloom(),
receipts,
chain_spec,
block.header.timestamp,
header.timestamp(),
) {
tracing::debug!(%error, ?receipts, "receipts verification failed");
return Err(error)
Expand All @@ -36,9 +36,9 @@ pub fn validate_block_post_execution(
// Check if gas used matches the value set in header.
let cumulative_gas_used =
receipts.last().map(|receipt| receipt.cumulative_gas_used()).unwrap_or(0);
if block.header.gas_used != cumulative_gas_used {
if header.gas_used() != cumulative_gas_used {
return Err(ConsensusError::BlockGasUsed {
gas: GotExpected { got: cumulative_gas_used, expected: block.header.gas_used },
gas: GotExpected { got: cumulative_gas_used, expected: header.gas_used() },
gas_spent_by_tx: gas_spent_by_transactions(receipts),
})
}
Expand All @@ -47,10 +47,10 @@ pub fn validate_block_post_execution(
}

/// Verify the calculated receipts root against the expected receipts root.
fn verify_receipts(
fn verify_receipts<R: DepositReceipt>(
expected_receipts_root: B256,
expected_logs_bloom: Bloom,
receipts: &[OpReceipt],
receipts: &[R],
chain_spec: &ChainSpec,
timestamp: u64,
) -> Result<(), ConsensusError> {
Expand Down
Loading

0 comments on commit 2e5808a

Please sign in to comment.