forked from paradigmxyz/reth
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Write and validate l2tol1-message-passer in block header
- Loading branch information
Showing
5 changed files
with
176 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
//! Optimism consensus errors | ||
use alloy_primitives::B256; | ||
use derive_more::{Display, Error, From}; | ||
use reth_consensus::ConsensusError; | ||
use reth_storage_errors::ProviderError; | ||
|
||
/// Optimism consensus error. | ||
#[derive(Debug, PartialEq, Eq, Clone, Display, Error, From)] | ||
pub enum OpConsensusError { | ||
/// Block body has non-empty withdrawals list. | ||
#[display("non-empty withdrawals list")] | ||
WithdrawalsNonEmpty, | ||
/// Failed to load storage root of | ||
/// [`L2toL1MessagePasser`](reth_optimism_primitives::ADDRESS_L2_TO_L1_MESSAGE_PASSER). | ||
#[display("failed to load storage root of L2toL1MessagePasser pre-deploy: {_0}")] | ||
#[from] | ||
LoadStorageRootFailed(ProviderError), | ||
/// Storage root of | ||
/// [`L2toL1MessagePasser`](reth_optimism_primitives::ADDRESS_L2_TO_L1_MESSAGE_PASSER) missing | ||
/// in block (withdrawals root field). | ||
#[display("storage root of l2tol1-msg-passer predeploy missing from block header (withdrawals root field empty)")] | ||
StorageRootMissing, | ||
/// Storage root of | ||
/// [`L2toL1MessagePasser`](reth_optimism_primitives::ADDRESS_L2_TO_L1_MESSAGE_PASSER) | ||
/// in block (withdrawals field), doesn't match local storage root. | ||
#[display("L2toL1MessagePasser storage root mismatch, got: {got}, expected {expected}"] | ||
StorageRootMismatch { | ||
/// Storage root of pre-deploy in block. | ||
got: B256, | ||
/// Storage root of pre-deploy loaded from local state. | ||
expected: B256, | ||
}, | ||
/// L1 [`ConsensusError`], that also occurs on L2. | ||
#[display("{_0}")] | ||
#[from] | ||
Eth(ConsensusError), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
//! Canyon consensus rule checks. | ||
use alloy_consensus::BlockHeader; | ||
use alloy_trie::EMPTY_ROOT_HASH; | ||
use reth_consensus::ConsensusError; | ||
use reth_primitives::GotExpected; | ||
use reth_primitives_traits::BlockBody; | ||
|
||
use crate::OpConsensusError; | ||
|
||
/// Validate that withdrawals in block body (Shanghai) is always empty in Canyon. | ||
// todo: link OP docs | ||
#[inline] | ||
pub fn validate_empty_shanghai_withdrawals<B: BlockBody>(body: &B) -> Result<(), OpConsensusError> { | ||
// Shanghai rule | ||
let withdrawals = body.withdrawals().ok_or(ConsensusError::BodyWithdrawalsMissing)?; | ||
|
||
// Canyon rule | ||
if !withdrawals.is_empty() { | ||
return Err(OpConsensusError::WithdrawalsNonEmpty) | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Validate that withdrawals root in block header (Shanghai) is always [`EMPTY_ROOT_HASH`] in | ||
/// Canyon. | ||
#[inline] | ||
pub fn validate_empty_withdrawals_root<H: BlockHeader>(header: &H) -> Result<(), ConsensusError> { | ||
// Shanghai rule | ||
let header_withdrawals_root = | ||
header.withdrawals_root().ok_or(ConsensusError::WithdrawalsRootMissing)?; | ||
|
||
// Canyon rules | ||
if header_withdrawals_root != EMPTY_ROOT_HASH { | ||
return Err(ConsensusError::BodyWithdrawalsRootDiff( | ||
GotExpected { got: header_withdrawals_root, expected: EMPTY_ROOT_HASH }.into(), | ||
)); | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
//! Block validation w.r.t. consensus rules new in isthmus hardfork. | ||
use alloy_consensus::BlockHeader; | ||
use reth_optimism_primitives::predeploys::ADDRESS_L2_TO_L1_MESSAGE_PASSER; | ||
use reth_storage_api::{StateProviderFactory, StorageRootProvider}; | ||
|
||
use crate::OpConsensusError; | ||
|
||
/// Validates block header field `withdrawals_root` against storage root of | ||
/// `2toL1-message-passer` predeploy. | ||
pub fn validate_l2_to_l1_msg_passer<H: BlockHeader, P: StateProviderFactory>( | ||
provider: &P, | ||
header: &H, | ||
) -> Result<(), OpConsensusError> { | ||
let header_storage_root = | ||
header.withdrawals_root().ok_or(OpConsensusError::StorageRootMissing)?; | ||
|
||
let state = provider.latest().map_err(OpConsensusError::LoadStorageRootFailed)?; | ||
|
||
let storage_root = state | ||
.storage_root(ADDRESS_L2_TO_L1_MESSAGE_PASSER, Default::default()) | ||
.map_err(OpConsensusError::LoadStorageRootFailed)?; | ||
|
||
if header_storage_root != storage_root { | ||
return Err(OpConsensusError::StorageRootMismatch { | ||
got: header_storage_root, | ||
expected: storage_root, | ||
}) | ||
} | ||
|
||
Ok(()) | ||
} |
5 changes: 5 additions & 0 deletions
5
crates/optimism/consensus/src/validation.rs → .../optimism/consensus/src/validation/mod.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters