Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verify l2 withdrawals root in live sync #14583

Closed
emhane opened this issue Feb 19, 2025 · 2 comments · Fixed by #14636
Closed

Verify l2 withdrawals root in live sync #14583

emhane opened this issue Feb 19, 2025 · 2 comments · Fixed by #14636
Labels
A-consensus Related to the consensus engine A-op-reth Related to Optimism and op-reth

Comments

@emhane
Copy link
Member

emhane commented Feb 19, 2025

Describe the feature

Verify isthmus withdrawals root with consensus rules implemented in #14308 either before, or optimistically after, this statement.

let hashed_state = self.provider.hashed_post_state(&output.state);

Pros of doing before is early bail if l2 withdrawals root doesn't verify and skip hashing all state updates (just the state updates for the predeploy account, if any).

To do this we either need to surface the EngineApiTreeHandler to sdk level, or some hack with adding a trait method FullConsensus::validate_block_post_execution_live_sync_only

wdyt @mattsse @klkvr

Additional context

No response

@mattsse
Copy link
Collaborator

mattsse commented Feb 20, 2025

To do this we either need to surface the EngineApiTreeHandler to sdk level

this is planned but this requires a lot of work.

for this feature I think we can get away with integrating this into the PayloadValidator instead. we should treat this validation step similar to state root, and check outside of the consensus traits (maybe we should consider integrating this there eventually).

but I believe an easier integration would be in the payloadvalidator for now
and replicate

let hashed_storage_updates =
state.bundle_state.state().get(&ADDRESS_L2_TO_L1_MESSAGE_PASSER).map(|account| {
// block contained withdrawals transactions, use predeploy storage updates from
// execution
HashedStorage::from_plain_storage(
account.status,
account.storage.iter().map(|(slot, value)| (slot, &value.present_value)),
)
});
// withdrawals root field in block header is used for storage root of L2 predeploy
// `l2tol1-message-passer`
Some(state.database.as_ref().storage_root(
ADDRESS_L2_TO_L1_MESSAGE_PASSER,
hashed_storage_updates.unwrap_or_default(),
)?)

the state root stuff is super messy rn (working on it).

@emhane
Copy link
Member Author

emhane commented Feb 21, 2025

this new method for verifying against hashed storage fits better into FullConsensus trait, no? alongside validate_block_post_execution

/// [`Consensus`] implementation which knows full node primitives and is able to validation block's
/// execution outcome.
#[auto_impl::auto_impl(&, Arc)]
pub trait FullConsensus<N: NodePrimitives>: AsConsensus<N::Block> {
/// Validate a block considering world state, i.e. things that can not be checked before
/// execution.
///
/// See the Yellow Paper sections 4.3.2 "Holistic Validity".
///
/// Note: validating blocks does not include other validations of the Consensus
fn validate_block_post_execution(
&self,
block: &RecoveredBlock<N::Block>,
result: &BlockExecutionResult<N::Receipt>,
) -> Result<(), ConsensusError>;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-consensus Related to the consensus engine A-op-reth Related to Optimism and op-reth
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants