diff --git a/crates/optimism/consensus/src/error.rs b/crates/optimism/consensus/src/error.rs index 7ada2e9bbaf..5197b263d68 100644 --- a/crates/optimism/consensus/src/error.rs +++ b/crates/optimism/consensus/src/error.rs @@ -3,6 +3,7 @@ use alloc::sync::Arc; use alloy_primitives::B256; use reth_consensus::ConsensusError; +use reth_primitives_traits::GotExpected; use reth_storage_errors::provider::ProviderError; /// Optimism consensus error. @@ -28,6 +29,12 @@ pub enum OpConsensusError { /// L1 [`ConsensusError`], that also occurs on L2. #[error(transparent)] Eth(ConsensusError), + /// DA footprint gas missing from header + #[error("DA footprint gas missing from header")] + DAFootprintGasMissing, + /// DA footprint gas mismatch + #[error("DA footprint gas mismatch: {0:?}")] + DAFootprintGasDiff(GotExpected), } impl From for ConsensusError { diff --git a/crates/optimism/consensus/src/lib.rs b/crates/optimism/consensus/src/lib.rs index 8be804db451..ebca044c03d 100644 --- a/crates/optimism/consensus/src/lib.rs +++ b/crates/optimism/consensus/src/lib.rs @@ -80,7 +80,7 @@ where block: &RecoveredBlock, result: &BlockExecutionResult, ) -> Result<(), ConsensusError> { - validate_block_post_execution(block.header(), &self.chain_spec, result) + Ok(validate_block_post_execution(block.header(), &self.chain_spec, result)?) } } diff --git a/crates/optimism/consensus/src/validation/jovian.rs b/crates/optimism/consensus/src/validation/jovian.rs index d369ed5a040..eb3de4f22f9 100644 --- a/crates/optimism/consensus/src/validation/jovian.rs +++ b/crates/optimism/consensus/src/validation/jovian.rs @@ -1,7 +1,7 @@ //! Block verification w.r.t. consensus rules new in Jovian hardfork. +use crate::OpConsensusError; use alloy_consensus::BlockHeader; -use reth_consensus::ConsensusError; use reth_execution_types::BlockExecutionResult; use reth_optimism_primitives::DepositReceipt; use reth_primitives_traits::GotExpected; @@ -13,12 +13,13 @@ use reth_primitives_traits::GotExpected; pub fn validate_blob_gas_used( header: impl BlockHeader, result: &BlockExecutionResult, -) -> Result<(), ConsensusError> { +) -> Result<(), OpConsensusError> { let computed_blob_gas_used = result.blob_gas_used; - let header_blob_gas_used = header.blob_gas_used().ok_or(ConsensusError::BlobGasUsedMissing)?; + let header_blob_gas_used = + header.blob_gas_used().ok_or(OpConsensusError::DAFootprintGasMissing)?; if computed_blob_gas_used != header_blob_gas_used { - return Err(ConsensusError::BlobGasUsedDiff(GotExpected { + return Err(OpConsensusError::DAFootprintGasDiff(GotExpected { got: computed_blob_gas_used, expected: header_blob_gas_used, })); diff --git a/crates/optimism/consensus/src/validation/mod.rs b/crates/optimism/consensus/src/validation/mod.rs index b0d6d18b6b8..6c7e2ed38b1 100644 --- a/crates/optimism/consensus/src/validation/mod.rs +++ b/crates/optimism/consensus/src/validation/mod.rs @@ -8,7 +8,7 @@ pub mod jovian; use reth_execution_types::BlockExecutionResult; pub use reth_optimism_chainspec::decode_holocene_base_fee; -use crate::proof::calculate_receipt_root_optimism; +use crate::{proof::calculate_receipt_root_optimism, OpConsensusError}; use alloc::vec::Vec; use alloy_consensus::{BlockHeader, TxReceipt, EMPTY_OMMER_ROOT_HASH}; use alloy_eips::Encodable2718; @@ -90,7 +90,7 @@ pub fn validate_block_post_execution( header: impl BlockHeader, chain_spec: impl OpHardforks, result: &BlockExecutionResult, -) -> Result<(), ConsensusError> { +) -> Result<(), OpConsensusError> { // Validate that the blob gas used is present and correctly computed if Jovian is active. if chain_spec.is_jovian_active_at_timestamp(header.timestamp()) { jovian::validate_blob_gas_used(&header, result)?; @@ -116,17 +116,17 @@ pub fn validate_block_post_execution( .map(|r| Bytes::from(r.with_bloom_ref().encoded_2718())) .collect::>(); tracing::debug!(%error, ?receipts, "receipts verification failed"); - return Err(error) + Err(error)? } // 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 header.gas_used() != cumulative_gas_used { - return Err(ConsensusError::BlockGasUsed { + return Err(OpConsensusError::Eth(ConsensusError::BlockGasUsed { gas: GotExpected { got: cumulative_gas_used, expected: header.gas_used() }, gas_spent_by_tx: gas_spent_by_transactions(receipts), - }) + })) } Ok(()) @@ -558,7 +558,7 @@ mod tests { }; assert!(matches!( validate_block_post_execution(&header, &chainspec, &result).unwrap_err(), - ConsensusError::BlobGasUsedDiff(diff) + OpConsensusError::DAFootprintGasDiff(diff) if diff.got == BLOB_GAS_USED && diff.expected == BLOB_GAS_USED + 1 )); }