-
Notifications
You must be signed in to change notification settings - Fork 5
refactor: add storage trait abstraction for ValidatorDB and unit tests #111
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
Open
flyq
wants to merge
1
commit into
main
Choose a base branch
from
liquan/refator2
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+523
−10
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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,141 @@ | ||
| //! Storage trait abstractions for `ValidatorDB`. | ||
| //! | ||
| //! These traits decouple consumers from the concrete `redb`-backed `ValidatorDB` implementation, | ||
| //! enabling alternative backends (e.g., in-memory for testing) without changing consumer code. | ||
|
|
||
| use std::collections::HashMap; | ||
|
|
||
| use alloy_genesis::Genesis; | ||
| use alloy_primitives::{B256, BlockHash, BlockNumber}; | ||
| use alloy_rpc_types_eth::{Block, Header}; | ||
| use op_alloy_rpc_types::Transaction; | ||
| use revm::state::Bytecode; | ||
| use salt::SaltWitness; | ||
|
|
||
| use crate::{ | ||
| executor::ValidationResult, light_witness::LightWitness, validator_db::ValidationDbResult, | ||
| withdrawals::MptWitness, | ||
| }; | ||
|
|
||
| /// Chain state management: tips, growth, rollback, genesis, anchor, and pruning. | ||
| /// | ||
| /// Encapsulates the full lifecycle of chain state from initialization (genesis/anchor) | ||
| /// through synchronization (remote/local chain growth) to maintenance (rollback/pruning). | ||
| pub trait ChainState { | ||
| /// Returns the highest block in the local canonical chain, or `None` if empty. | ||
| fn get_local_tip(&self) -> ValidationDbResult<Option<(BlockNumber, BlockHash)>>; | ||
|
|
||
| /// Returns the highest block in the remote (unvalidated) chain, or `None` if empty. | ||
| fn get_remote_tip(&self) -> ValidationDbResult<Option<(BlockNumber, BlockHash)>>; | ||
|
|
||
| /// Extends the remote chain with a consecutive sequence of unvalidated block headers. | ||
| /// | ||
| /// Each header's parent hash must match the current remote chain tip. | ||
| fn grow_remote_chain(&self, headers: &[Header]) -> ValidationDbResult<()>; | ||
|
|
||
| /// Extends the canonical chain with the next validated block from the remote chain. | ||
| /// | ||
| /// Returns `true` if a block was advanced, `false` if no work to do. | ||
| fn grow_local_chain(&self) -> ValidationDbResult<bool>; | ||
|
|
||
| /// Promotes the first remote chain block to canonical without validation. | ||
| /// | ||
| /// Used by debug-trace-server where blocks are trusted from upstream RPC. | ||
| /// Returns `true` if a block was promoted, `false` if remote chain is empty. | ||
| fn promote_remote_to_canonical(&self) -> ValidationDbResult<bool>; | ||
|
|
||
| /// Rolls back both canonical and remote chains to the given block number. | ||
| fn rollback_chain(&self, to_block: BlockNumber) -> ValidationDbResult<()>; | ||
|
|
||
| /// Looks up a block hash by number in canonical chain first, then remote chain. | ||
| fn get_block_hash(&self, block_number: BlockNumber) -> ValidationDbResult<Option<BlockHash>>; | ||
|
|
||
| /// Returns the earliest (lowest) block in the canonical chain. | ||
| fn get_earliest_local_block(&self) -> ValidationDbResult<Option<(BlockNumber, BlockHash)>>; | ||
|
|
||
| /// Resets the chain to start from a trusted anchor block, clearing all chain state. | ||
| fn reset_anchor_block( | ||
| &self, | ||
| block_number: BlockNumber, | ||
| block_hash: BlockHash, | ||
| post_state_root: B256, | ||
| post_withdrawals_root: B256, | ||
| ) -> ValidationDbResult<()>; | ||
|
|
||
| /// Returns the stored anchor block, or `None` if not set. | ||
| fn get_anchor_block(&self) -> ValidationDbResult<Option<(BlockNumber, BlockHash)>>; | ||
|
|
||
| /// Persists the genesis configuration. | ||
| fn store_genesis(&self, genesis: &Genesis) -> ValidationDbResult<()>; | ||
|
|
||
| /// Loads the genesis configuration, or `None` if not stored yet. | ||
| fn load_genesis(&self) -> ValidationDbResult<Option<Genesis>>; | ||
|
|
||
| /// Removes chain data older than the given block number. | ||
| /// | ||
| /// Returns the number of blocks pruned. | ||
| fn prune_history(&self, before_block: BlockNumber) -> ValidationDbResult<u64>; | ||
| } | ||
|
|
||
| /// Validation task lifecycle: creation, claiming, and recovery. | ||
| /// | ||
| /// Manages the queue of blocks pending validation, including both the full-validation | ||
| /// path (stateless-validator) and the data-only path (debug-trace-server). | ||
| pub trait TaskQueue { | ||
| /// Queues blocks with full witness data for validation workers. | ||
| fn add_validation_tasks( | ||
| &self, | ||
| tasks: &[(Block<Transaction>, SaltWitness, MptWitness)], | ||
| ) -> ValidationDbResult<()>; | ||
|
|
||
| /// Stores block data and light witnesses without creating validation tasks. | ||
| /// | ||
| /// Used by debug-trace-server where blocks are served for tracing, not validated. | ||
| fn store_block_data( | ||
| &self, | ||
| tasks: &[(Block<Transaction>, LightWitness)], | ||
| ) -> ValidationDbResult<()>; | ||
|
|
||
| /// Atomically claims the next pending validation task. | ||
| /// | ||
| /// Returns `None` when no tasks are available. | ||
| fn get_next_task( | ||
| &self, | ||
| ) -> ValidationDbResult<Option<(Block<Transaction>, SaltWitness, MptWitness)>>; | ||
|
|
||
| /// Moves interrupted (in-progress) tasks back to the pending queue. | ||
| fn recover_interrupted_tasks(&self) -> ValidationDbResult<()>; | ||
| } | ||
|
|
||
| /// Block and witness data retrieval, plus contract bytecode cache. | ||
| pub trait BlockDataStore { | ||
| /// Retrieves block data and light witness for a given block hash. | ||
| fn get_block_and_witness( | ||
| &self, | ||
| block_hash: BlockHash, | ||
| ) -> ValidationDbResult<(Block<Transaction>, LightWitness)>; | ||
|
|
||
| /// Retrieves cached contract bytecodes. | ||
| /// | ||
| /// Returns `(found, missing)` where `found` maps code hashes to bytecodes and | ||
| /// `missing` lists code hashes not present in the cache. | ||
| fn get_contract_codes( | ||
| &self, | ||
| code_hashes: &[B256], | ||
| ) -> ValidationDbResult<(HashMap<B256, Bytecode>, Vec<B256>)>; | ||
|
|
||
| /// Stores contract bytecodes in the cache. | ||
| fn add_contract_codes(&self, bytecodes: &[(B256, Bytecode)]) -> ValidationDbResult<()>; | ||
| } | ||
|
|
||
| /// Validation result storage and lookup. | ||
| pub trait ValidationResultStore { | ||
| /// Records a completed validation and removes the task from the in-progress queue. | ||
| fn complete_validation(&self, result: ValidationResult) -> ValidationDbResult<()>; | ||
|
|
||
| /// Retrieves the validation result for a block, or `None` if not yet validated. | ||
| fn get_validation_result( | ||
| &self, | ||
| block_hash: BlockHash, | ||
| ) -> ValidationDbResult<Option<ValidationResult>>; | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
&[Header]trait signature forces an allocation + full clone of every header on the hot path. The original code passed an iterator with no allocation:Consider changing the trait method to accept
impl IntoIterator<Item = &Header>— though that isn't directly expressible in a trait method today without a generic parameter. A practical middle ground: keep&[Header]in the trait but change the inherentValidatorDB::grow_remote_chainto also accept&[Header]so the trait impl is a zero-cost pass-through, and fix the call site to avoid the clone by collecting&block.headerinto aVec<&Header>:This still needs a
Vecbut at least avoids cloning eachHeader.