From 435d915422dbedb46846fcd7c792f2ccbb163837 Mon Sep 17 00:00:00 2001 From: Julian Meyer Date: Fri, 30 Jan 2026 10:40:30 -0800 Subject: [PATCH] chore: make engine tree crate items public (#21487) --- crates/engine/tree/src/tree/cached_state.rs | 55 ++++++++--------- crates/engine/tree/src/tree/metrics.rs | 60 +++++++++---------- crates/engine/tree/src/tree/mod.rs | 16 ++++- .../tree/src/tree/payload_processor/bal.rs | 4 +- .../tree/src/tree/payload_processor/mod.rs | 24 ++++---- .../src/tree/payload_processor/multiproof.rs | 4 +- .../src/tree/payload_processor/prewarm.rs | 46 +++++++------- .../engine/tree/src/tree/precompile_cache.rs | 22 +++---- crates/engine/tree/src/tree/state.rs | 39 +++++------- 9 files changed, 140 insertions(+), 130 deletions(-) diff --git a/crates/engine/tree/src/tree/cached_state.rs b/crates/engine/tree/src/tree/cached_state.rs index 7122b86fcb..fdd3ea4c68 100644 --- a/crates/engine/tree/src/tree/cached_state.rs +++ b/crates/engine/tree/src/tree/cached_state.rs @@ -76,7 +76,8 @@ impl CacheConfig for EpochCacheConfig { type FixedCache = fixed_cache::Cache; /// A wrapper of a state provider and a shared cache. -pub(crate) struct CachedStateProvider { +#[derive(Debug)] +pub struct CachedStateProvider { /// The state provider state_provider: S, @@ -96,7 +97,7 @@ where { /// Creates a new [`CachedStateProvider`] from an [`ExecutionCache`], state provider, and /// [`CachedStateMetrics`]. - pub(crate) const fn new( + pub const fn new( state_provider: S, caches: ExecutionCache, metrics: CachedStateMetrics, @@ -114,7 +115,7 @@ impl CachedStateProvider { /// [`State`](revm::database::State) also caches internally during block execution and the cache /// is then updated after the block with the entire [`BundleState`] output of that block which /// contains all accessed accounts,code,storage. See also [`ExecutionCache::insert_state`]. - pub(crate) const fn prewarm(mut self) -> Self { + pub const fn prewarm(mut self) -> Self { self.prewarm = true; self } @@ -131,7 +132,7 @@ impl CachedStateProvider { /// and the fixed-cache internal stats (collisions, size, capacity). #[derive(Metrics, Clone)] #[metrics(scope = "sync.caching")] -pub(crate) struct CachedStateMetrics { +pub struct CachedStateMetrics { /// Number of times a new execution cache was created execution_cache_created_total: Counter, @@ -186,7 +187,7 @@ pub(crate) struct CachedStateMetrics { impl CachedStateMetrics { /// Sets all values to zero, indicating that a new block is being executed. - pub(crate) fn reset(&self) { + pub fn reset(&self) { // code cache self.code_cache_hits.set(0); self.code_cache_misses.set(0); @@ -204,7 +205,7 @@ impl CachedStateMetrics { } /// Returns a new zeroed-out instance of [`CachedStateMetrics`]. - pub(crate) fn zeroed() -> Self { + pub fn zeroed() -> Self { let zeroed = Self::default(); zeroed.reset(); zeroed @@ -326,7 +327,7 @@ impl AccountReader for CachedStateProvider { /// Represents the status of a key in the cache. #[derive(Debug, Clone, PartialEq, Eq)] -pub(crate) enum CachedStatus { +pub enum CachedStatus { /// The key is not in the cache (or was invalidated). The value was recalculated. NotCached(T), /// The key exists in cache and has a specific value. @@ -487,7 +488,7 @@ impl HashedPostStateProvider for CachedStateProvider /// Since EIP-6780, SELFDESTRUCT only works within the same transaction where the /// contract was created, so we don't need to handle clearing the storage. #[derive(Debug, Clone)] -pub(crate) struct ExecutionCache { +pub struct ExecutionCache { /// Cache for contract bytecode, keyed by code hash. code_cache: Arc, FbBuildHasher<32>>>, @@ -519,7 +520,7 @@ impl ExecutionCache { /// /// Fixed-cache requires power-of-two sizes for efficient indexing. /// With epochs enabled, the minimum size is 4096 entries. - pub(crate) const fn bytes_to_entries(size_bytes: usize, entry_size: usize) -> usize { + pub const fn bytes_to_entries(size_bytes: usize, entry_size: usize) -> usize { let entries = size_bytes / entry_size; // Round down to nearest power of two let rounded = if entries == 0 { 1 } else { (entries + 1).next_power_of_two() >> 1 }; @@ -532,7 +533,7 @@ impl ExecutionCache { } /// Build an [`ExecutionCache`] struct, so that execution caches can be easily cloned. - pub(crate) fn new(total_cache_size: usize) -> Self { + pub fn new(total_cache_size: usize) -> Self { let storage_cache_size = (total_cache_size * 8888) / 10000; // 88.88% of total let account_cache_size = (total_cache_size * 556) / 10000; // 5.56% of total let code_cache_size = (total_cache_size * 556) / 10000; // 5.56% of total @@ -566,7 +567,7 @@ impl ExecutionCache { } /// Gets code from cache, or inserts using the provided function. - pub(crate) fn get_or_try_insert_code_with( + pub fn get_or_try_insert_code_with( &self, hash: B256, f: impl FnOnce() -> Result, E>, @@ -585,7 +586,7 @@ impl ExecutionCache { } /// Gets storage from cache, or inserts using the provided function. - pub(crate) fn get_or_try_insert_storage_with( + pub fn get_or_try_insert_storage_with( &self, address: Address, key: StorageKey, @@ -605,7 +606,7 @@ impl ExecutionCache { } /// Gets account from cache, or inserts using the provided function. - pub(crate) fn get_or_try_insert_account_with( + pub fn get_or_try_insert_account_with( &self, address: Address, f: impl FnOnce() -> Result, E>, @@ -624,12 +625,7 @@ impl ExecutionCache { } /// Insert storage value into cache. - pub(crate) fn insert_storage( - &self, - address: Address, - key: StorageKey, - value: Option, - ) { + pub fn insert_storage(&self, address: Address, key: StorageKey, value: Option) { self.storage_cache.insert((address, key), value.unwrap_or_default()); } @@ -662,7 +658,8 @@ impl ExecutionCache { /// /// Returns an error if the state updates are inconsistent and should be discarded. #[instrument(level = "debug", target = "engine::caching", skip_all)] - pub(crate) fn insert_state(&self, state_updates: &BundleState) -> Result<(), ()> { + #[expect(clippy::result_unit_err)] + pub fn insert_state(&self, state_updates: &BundleState) -> Result<(), ()> { let _enter = debug_span!(target: "engine::tree", "contracts", len = state_updates.contracts.len()) .entered(); @@ -771,7 +768,7 @@ impl ExecutionCache { /// A saved cache that has been used for executing a specific block, which has been updated for its /// execution. #[derive(Debug, Clone)] -pub(crate) struct SavedCache { +pub struct SavedCache { /// The hash of the block these caches were used to execute. hash: B256, @@ -791,43 +788,43 @@ pub(crate) struct SavedCache { impl SavedCache { /// Creates a new instance with the internals - pub(super) fn new(hash: B256, caches: ExecutionCache, metrics: CachedStateMetrics) -> Self { + pub fn new(hash: B256, caches: ExecutionCache, metrics: CachedStateMetrics) -> Self { Self { hash, caches, metrics, usage_guard: Arc::new(()), disable_cache_metrics: false } } /// Sets whether to disable cache metrics recording. - pub(super) const fn with_disable_cache_metrics(mut self, disable: bool) -> Self { + pub const fn with_disable_cache_metrics(mut self, disable: bool) -> Self { self.disable_cache_metrics = disable; self } /// Returns the hash for this cache - pub(crate) const fn executed_block_hash(&self) -> B256 { + pub const fn executed_block_hash(&self) -> B256 { self.hash } /// Splits the cache into its caches, metrics, and `disable_cache_metrics` flag, consuming it. - pub(crate) fn split(self) -> (ExecutionCache, CachedStateMetrics, bool) { + pub fn split(self) -> (ExecutionCache, CachedStateMetrics, bool) { (self.caches, self.metrics, self.disable_cache_metrics) } /// Returns true if the cache is available for use (no other tasks are currently using it). - pub(crate) fn is_available(&self) -> bool { + pub fn is_available(&self) -> bool { Arc::strong_count(&self.usage_guard) == 1 } /// Returns the current strong count of the usage guard. - pub(crate) fn usage_count(&self) -> usize { + pub fn usage_count(&self) -> usize { Arc::strong_count(&self.usage_guard) } /// Returns the [`ExecutionCache`] belonging to the tracked hash. - pub(crate) const fn cache(&self) -> &ExecutionCache { + pub const fn cache(&self) -> &ExecutionCache { &self.caches } /// Returns the metrics associated with this cache. - pub(crate) const fn metrics(&self) -> &CachedStateMetrics { + pub const fn metrics(&self) -> &CachedStateMetrics { &self.metrics } diff --git a/crates/engine/tree/src/tree/metrics.rs b/crates/engine/tree/src/tree/metrics.rs index 5a97eae36d..97ca9c0ad8 100644 --- a/crates/engine/tree/src/tree/metrics.rs +++ b/crates/engine/tree/src/tree/metrics.rs @@ -13,13 +13,13 @@ use std::time::{Duration, Instant}; /// Metrics for the `EngineApi`. #[derive(Debug, Default)] -pub(crate) struct EngineApiMetrics { +pub struct EngineApiMetrics { /// Engine API-specific metrics. - pub(crate) engine: EngineMetrics, + pub engine: EngineMetrics, /// Block executor metrics. - pub(crate) executor: ExecutorMetrics, + pub executor: ExecutorMetrics, /// Metrics for block validation - pub(crate) block_validation: BlockValidationMetrics, + pub block_validation: BlockValidationMetrics, /// Canonical chain and reorg related metrics pub tree: TreeMetrics, /// Metrics for EIP-7928 Block-Level Access Lists (BAL). @@ -32,7 +32,7 @@ impl EngineApiMetrics { /// /// This method updates metrics for execution time, gas usage, and the number /// of accounts, storage slots and bytecodes updated. - pub(crate) fn record_block_execution( + pub fn record_block_execution( &self, output: &BlockExecutionOutput, execution_duration: Duration, @@ -59,27 +59,27 @@ impl EngineApiMetrics { } /// Returns a reference to the executor metrics for use in state hooks. - pub(crate) const fn executor_metrics(&self) -> &ExecutorMetrics { + pub const fn executor_metrics(&self) -> &ExecutorMetrics { &self.executor } /// Records the duration of block pre-execution changes (e.g., beacon root update). - pub(crate) fn record_pre_execution(&self, elapsed: Duration) { + pub fn record_pre_execution(&self, elapsed: Duration) { self.executor.pre_execution_histogram.record(elapsed); } /// Records the duration of block post-execution changes (e.g., finalization). - pub(crate) fn record_post_execution(&self, elapsed: Duration) { + pub fn record_post_execution(&self, elapsed: Duration) { self.executor.post_execution_histogram.record(elapsed); } /// Records the time spent waiting for the next transaction from the iterator. - pub(crate) fn record_transaction_wait(&self, elapsed: Duration) { + pub fn record_transaction_wait(&self, elapsed: Duration) { self.executor.transaction_wait_histogram.record(elapsed); } /// Records the duration of a single transaction execution. - pub(crate) fn record_transaction_execution(&self, elapsed: Duration) { + pub fn record_transaction_execution(&self, elapsed: Duration) { self.executor.transaction_execution_histogram.record(elapsed); } } @@ -87,7 +87,7 @@ impl EngineApiMetrics { /// Metrics for the entire blockchain tree #[derive(Metrics)] #[metrics(scope = "blockchain_tree")] -pub(crate) struct TreeMetrics { +pub struct TreeMetrics { /// The highest block number in the canonical chain pub canonical_chain_height: Gauge, /// The number of reorgs @@ -103,7 +103,7 @@ pub(crate) struct TreeMetrics { /// Metrics for the `EngineApi`. #[derive(Metrics)] #[metrics(scope = "consensus.engine.beacon")] -pub(crate) struct EngineMetrics { +pub struct EngineMetrics { /// Engine API forkchoiceUpdated response type metrics #[metric(skip)] pub(crate) forkchoice_updated: ForkchoiceUpdatedMetrics, @@ -336,42 +336,42 @@ pub(crate) struct BalMetrics { /// Metrics for non-execution related block validation. #[derive(Metrics, Clone)] #[metrics(scope = "sync.block_validation")] -pub(crate) struct BlockValidationMetrics { +pub struct BlockValidationMetrics { /// Total number of storage tries updated in the state root calculation - pub(crate) state_root_storage_tries_updated_total: Counter, + pub state_root_storage_tries_updated_total: Counter, /// Total number of times the parallel state root computation fell back to regular. - pub(crate) state_root_parallel_fallback_total: Counter, + pub state_root_parallel_fallback_total: Counter, /// Total number of times the state root task failed but the fallback succeeded. - pub(crate) state_root_task_fallback_success_total: Counter, + pub state_root_task_fallback_success_total: Counter, /// Latest state root duration, ie the time spent blocked waiting for the state root. - pub(crate) state_root_duration: Gauge, + pub state_root_duration: Gauge, /// Histogram for state root duration ie the time spent blocked waiting for the state root - pub(crate) state_root_histogram: Histogram, + pub state_root_histogram: Histogram, /// Histogram of deferred trie computation duration. - pub(crate) deferred_trie_compute_duration: Histogram, + pub deferred_trie_compute_duration: Histogram, /// Payload conversion and validation latency - pub(crate) payload_validation_duration: Gauge, + pub payload_validation_duration: Gauge, /// Histogram of payload validation latency - pub(crate) payload_validation_histogram: Histogram, + pub payload_validation_histogram: Histogram, /// Payload processor spawning duration - pub(crate) spawn_payload_processor: Histogram, + pub spawn_payload_processor: Histogram, /// Post-execution validation duration - pub(crate) post_execution_validation_duration: Histogram, + pub post_execution_validation_duration: Histogram, /// Total duration of the new payload call - pub(crate) total_duration: Histogram, + pub total_duration: Histogram, /// Size of `HashedPostStateSorted` (`total_len`) - pub(crate) hashed_post_state_size: Histogram, + pub hashed_post_state_size: Histogram, /// Size of `TrieUpdatesSorted` (`total_len`) - pub(crate) trie_updates_sorted_size: Histogram, + pub trie_updates_sorted_size: Histogram, /// Size of `AnchoredTrieInput` overlay `TrieUpdatesSorted` (`total_len`) - pub(crate) anchored_overlay_trie_updates_size: Histogram, + pub anchored_overlay_trie_updates_size: Histogram, /// Size of `AnchoredTrieInput` overlay `HashedPostStateSorted` (`total_len`) - pub(crate) anchored_overlay_hashed_state_size: Histogram, + pub anchored_overlay_hashed_state_size: Histogram, } impl BlockValidationMetrics { /// Records a new state root time, updating both the histogram and state root gauge - pub(crate) fn record_state_root(&self, trie_output: &TrieUpdates, elapsed_as_secs: f64) { + pub fn record_state_root(&self, trie_output: &TrieUpdates, elapsed_as_secs: f64) { self.state_root_storage_tries_updated_total .increment(trie_output.storage_tries_ref().len() as u64); self.state_root_duration.set(elapsed_as_secs); @@ -380,7 +380,7 @@ impl BlockValidationMetrics { /// Records a new payload validation time, updating both the histogram and the payload /// validation gauge - pub(crate) fn record_payload_validation(&self, elapsed_as_secs: f64) { + pub fn record_payload_validation(&self, elapsed_as_secs: f64) { self.payload_validation_duration.set(elapsed_as_secs); self.payload_validation_histogram.record(elapsed_as_secs); } diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 957c3dc592..ac52d85c7a 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -3,7 +3,7 @@ use crate::{ chain::FromOrchestrator, engine::{DownloadRequest, EngineApiEvent, EngineApiKind, EngineApiRequest, FromEngine}, persistence::PersistenceHandle, - tree::{error::InsertPayloadError, metrics::EngineApiMetrics, payload_validator::TreeCtx}, + tree::{error::InsertPayloadError, payload_validator::TreeCtx}, }; use alloy_consensus::BlockHeader; use alloy_eips::{eip1898::BlockWithParent, merge::EPOCH_SLOTS, BlockNumHash, NumHash}; @@ -55,7 +55,7 @@ pub mod error; pub mod instrumented_state; mod invalid_headers; mod metrics; -mod payload_processor; +pub mod payload_processor; pub mod payload_validator; mod persistence_state; pub mod precompile_cache; @@ -66,7 +66,9 @@ mod trie_updates; use crate::tree::error::AdvancePersistenceError; pub use block_buffer::BlockBuffer; +pub use cached_state::{CachedStateMetrics, CachedStateProvider, ExecutionCache, SavedCache}; pub use invalid_headers::InvalidHeaderCache; +pub use metrics::EngineApiMetrics; pub use payload_processor::*; pub use payload_validator::{BasicEngineValidator, EngineValidator}; pub use persistence_state::PersistenceState; @@ -158,6 +160,16 @@ impl EngineApiTreeState { forkchoice_state_tracker: ForkchoiceStateTracker::default(), } } + + /// Returns a reference to the tree state. + pub const fn tree_state(&self) -> &TreeState { + &self.tree_state + } + + /// Returns true if the block has been marked as invalid. + pub fn has_invalid_header(&mut self, hash: &B256) -> bool { + self.invalid_headers.get(hash).is_some() + } } /// The outcome of a tree operation. diff --git a/crates/engine/tree/src/tree/payload_processor/bal.rs b/crates/engine/tree/src/tree/payload_processor/bal.rs index 1353e1b628..0109dd2ee5 100644 --- a/crates/engine/tree/src/tree/payload_processor/bal.rs +++ b/crates/engine/tree/src/tree/payload_processor/bal.rs @@ -21,7 +21,7 @@ pub fn total_slots(bal: &BlockAccessList) -> usize { /// first, followed by read-only slots. The iterator intelligently skips accounts and slots /// outside the specified range for efficient traversal. #[derive(Debug)] -pub(crate) struct BALSlotIter<'a> { +pub struct BALSlotIter<'a> { bal: &'a BlockAccessList, range: Range, current_index: usize, @@ -34,7 +34,7 @@ pub(crate) struct BALSlotIter<'a> { impl<'a> BALSlotIter<'a> { /// Creates a new iterator over storage slots within the specified range. - pub(crate) fn new(bal: &'a BlockAccessList, range: Range) -> Self { + pub fn new(bal: &'a BlockAccessList, range: Range) -> Self { let mut iter = Self { bal, range, current_index: 0, account_idx: 0, slot_idx: 0 }; iter.skip_to_range_start(); iter diff --git a/crates/engine/tree/src/tree/payload_processor/mod.rs b/crates/engine/tree/src/tree/payload_processor/mod.rs index a7d023d14a..e517d2a83c 100644 --- a/crates/engine/tree/src/tree/payload_processor/mod.rs +++ b/crates/engine/tree/src/tree/payload_processor/mod.rs @@ -145,7 +145,7 @@ where Evm: ConfigureEvm, { /// Returns a reference to the workload executor driving payload tasks. - pub(super) const fn executor(&self) -> &WorkloadExecutor { + pub const fn executor(&self) -> &WorkloadExecutor { &self.executor } @@ -345,7 +345,7 @@ where /// /// Returns a [`PayloadHandle`] to communicate with the task. #[instrument(level = "debug", target = "engine::tree::payload_processor", skip_all)] - pub(super) fn spawn_cache_exclusive>( + pub fn spawn_cache_exclusive>( &self, env: ExecutionEnv, transactions: I, @@ -634,7 +634,7 @@ where /// /// The cache enables subsequent blocks to reuse account, storage, and bytecode data without /// hitting the database, maintaining performance consistency. - pub(crate) fn on_inserted_executed_block( + pub fn on_inserted_executed_block( &self, block_with_parent: BlockWithParent, bundle_state: &BundleState, @@ -731,19 +731,19 @@ impl PayloadHandle { } /// Returns a clone of the caches used by prewarming - pub(super) fn caches(&self) -> Option { + pub fn caches(&self) -> Option { self.prewarm_handle.saved_cache.as_ref().map(|cache| cache.cache().clone()) } /// Returns a clone of the cache metrics used by prewarming - pub(super) fn cache_metrics(&self) -> Option { + pub fn cache_metrics(&self) -> Option { self.prewarm_handle.saved_cache.as_ref().map(|cache| cache.metrics().clone()) } /// Terminates the pre-warming transaction processing. /// /// Note: This does not terminate the task yet. - pub(super) fn stop_prewarming_execution(&self) { + pub fn stop_prewarming_execution(&self) { self.prewarm_handle.stop_prewarming_execution() } @@ -754,7 +754,7 @@ impl PayloadHandle { /// path without cloning the expensive `BundleState`. /// /// Returns a sender for the channel that should be notified on block validation success. - pub(super) fn terminate_caching( + pub fn terminate_caching( &mut self, execution_outcome: Option>>, ) -> Option> { @@ -774,7 +774,7 @@ impl PayloadHandle { /// Generic over `R` (receipt type) to allow sharing `Arc>` with the /// prewarm task without cloning the expensive `BundleState`. #[derive(Debug)] -pub(crate) struct CacheTaskHandle { +pub struct CacheTaskHandle { /// The shared cache the task operates with. saved_cache: Option, /// Channel to the spawned prewarm task if any @@ -785,7 +785,7 @@ impl CacheTaskHandle { /// Terminates the pre-warming transaction processing. /// /// Note: This does not terminate the task yet. - pub(super) fn stop_prewarming_execution(&self) { + pub fn stop_prewarming_execution(&self) { self.to_prewarm_task .as_ref() .map(|tx| tx.send(PrewarmTaskEvent::TerminateTransactionExecution).ok()); @@ -796,7 +796,7 @@ impl CacheTaskHandle { /// If the [`BlockExecutionOutput`] is provided it will update the shared cache using its /// bundle state. Using `Arc` avoids cloning the expensive `BundleState`. #[must_use = "sender must be used and notified on block validation success"] - pub(super) fn terminate_caching( + pub fn terminate_caching( &mut self, execution_outcome: Option>>, ) -> Option> { @@ -850,7 +850,7 @@ impl Drop for CacheTaskHandle { /// - Prepares data for state root proof computation /// - Runs concurrently but must not interfere with cache saves #[derive(Clone, Debug, Default)] -struct PayloadExecutionCache { +pub struct PayloadExecutionCache { /// Guarded cloneable cache identified by a block hash. inner: Arc>>, /// Metrics for cache operations. @@ -930,7 +930,7 @@ impl PayloadExecutionCache { /// /// Violating this requirement can result in cache corruption, incorrect state data, /// and potential consensus failures. - pub(crate) fn update_with_guard(&self, update_fn: F) + pub fn update_with_guard(&self, update_fn: F) where F: FnOnce(&mut Option), { diff --git a/crates/engine/tree/src/tree/payload_processor/multiproof.rs b/crates/engine/tree/src/tree/payload_processor/multiproof.rs index 6ad99d9e45..053bf6bfda 100644 --- a/crates/engine/tree/src/tree/payload_processor/multiproof.rs +++ b/crates/engine/tree/src/tree/payload_processor/multiproof.rs @@ -100,7 +100,7 @@ impl SparseTrieUpdate { /// Messages used internally by the multi proof task. #[derive(Debug)] -pub(super) enum MultiProofMessage { +pub enum MultiProofMessage { /// Prefetch proof targets PrefetchProofs(VersionedMultiProofTargets), /// New state update from transaction execution with its source @@ -257,7 +257,7 @@ fn extend_multiproof_targets(dest: &mut MultiProofTargets, src: &VersionedMultiP /// A set of multiproof targets which can be either in the legacy or V2 representations. #[derive(Debug)] -pub(super) enum VersionedMultiProofTargets { +pub enum VersionedMultiProofTargets { /// Legacy targets Legacy(MultiProofTargets), /// V2 targets diff --git a/crates/engine/tree/src/tree/payload_processor/prewarm.rs b/crates/engine/tree/src/tree/payload_processor/prewarm.rs index cb29b95f46..a7a1560297 100644 --- a/crates/engine/tree/src/tree/payload_processor/prewarm.rs +++ b/crates/engine/tree/src/tree/payload_processor/prewarm.rs @@ -49,7 +49,8 @@ use std::{ use tracing::{debug, debug_span, instrument, trace, warn, Span}; /// Determines the prewarming mode: transaction-based or BAL-based. -pub(super) enum PrewarmMode { +#[derive(Debug)] +pub enum PrewarmMode { /// Prewarm by executing transactions from a stream. Transactions(Receiver), /// Prewarm by prefetching slots from a Block Access List. @@ -69,7 +70,8 @@ struct IndexedTransaction { /// individually in parallel. /// /// Note: This task runs until cancelled externally. -pub(super) struct PrewarmCacheTask +#[derive(Debug)] +pub struct PrewarmCacheTask where N: NodePrimitives, Evm: ConfigureEvm, @@ -99,7 +101,7 @@ where Evm: ConfigureEvm + 'static, { /// Initializes the task with the given transactions pending execution - pub(super) fn new( + pub fn new( executor: WorkloadExecutor, execution_cache: PayloadExecutionCache, ctx: PrewarmContext, @@ -370,11 +372,8 @@ where name = "prewarm and caching", skip_all )] - pub(super) fn run( - self, - mode: PrewarmMode, - actions_tx: Sender>, - ) where + pub fn run(self, mode: PrewarmMode, actions_tx: Sender>) + where Tx: ExecutableTxFor + Clone + Send + 'static, { // Spawn execution tasks based on mode @@ -436,23 +435,29 @@ where /// Context required by tx execution tasks. #[derive(Debug, Clone)] -pub(super) struct PrewarmContext +pub struct PrewarmContext where N: NodePrimitives, Evm: ConfigureEvm, { - pub(super) env: ExecutionEnv, - pub(super) evm_config: Evm, - pub(super) saved_cache: Option, + /// The execution environment. + pub env: ExecutionEnv, + /// The EVM configuration. + pub evm_config: Evm, + /// The saved cache. + pub saved_cache: Option, /// Provider to obtain the state - pub(super) provider: StateProviderBuilder, - pub(super) metrics: PrewarmMetrics, + pub provider: StateProviderBuilder, + /// The metrics for the prewarm task. + pub metrics: PrewarmMetrics, /// An atomic bool that tells prewarm tasks to not start any more execution. - pub(super) terminate_execution: Arc, - pub(super) precompile_cache_disabled: bool, - pub(super) precompile_cache_map: PrecompileCacheMap>, + pub terminate_execution: Arc, + /// Whether the precompile cache is disabled. + pub precompile_cache_disabled: bool, + /// The precompile cache map. + pub precompile_cache_map: PrecompileCacheMap>, /// Whether V2 proof calculation is enabled. - pub(super) v2_proofs_enabled: bool, + pub v2_proofs_enabled: bool, } impl PrewarmContext @@ -852,7 +857,8 @@ fn multiproof_targets_v2_from_state(state: EvmState) -> (VersionedMultiProofTarg /// /// Generic over `R` (receipt type) to allow sharing `Arc>` with the main /// execution path without cloning the expensive `BundleState`. -pub(super) enum PrewarmTaskEvent { +#[derive(Debug)] +pub enum PrewarmTaskEvent { /// Forcefully terminate all remaining transaction execution. TerminateTransactionExecution, /// Forcefully terminate the task on demand and update the shared cache with the given output @@ -882,7 +888,7 @@ pub(super) enum PrewarmTaskEvent { /// Metrics for transactions prewarming. #[derive(Metrics, Clone)] #[metrics(scope = "sync.prewarm")] -pub(crate) struct PrewarmMetrics { +pub struct PrewarmMetrics { /// The number of transactions to prewarm pub(crate) transactions: Gauge, /// A histogram of the number of transactions to prewarm diff --git a/crates/engine/tree/src/tree/precompile_cache.rs b/crates/engine/tree/src/tree/precompile_cache.rs index 3754560f7d..6b8f06f6e4 100644 --- a/crates/engine/tree/src/tree/precompile_cache.rs +++ b/crates/engine/tree/src/tree/precompile_cache.rs @@ -21,7 +21,8 @@ impl PrecompileCacheMap where S: Eq + Hash + std::fmt::Debug + Send + Sync + Clone + 'static, { - pub(crate) fn cache_for_address(&self, address: Address) -> PrecompileCache { + /// Get the precompile cache for the given address. + pub fn cache_for_address(&self, address: Address) -> PrecompileCache { // Try just using `.get` first to avoid acquiring a write lock. if let Some(cache) = self.0.get(&address) { return cache.clone(); @@ -90,7 +91,7 @@ impl CacheEntry { /// A cache for precompile inputs / outputs. #[derive(Debug)] -pub(crate) struct CachedPrecompile +pub struct CachedPrecompile where S: Eq + Hash + std::fmt::Debug + Send + Sync + Clone + 'static, { @@ -109,7 +110,7 @@ where S: Eq + Hash + std::fmt::Debug + Send + Sync + Clone + 'static, { /// `CachedPrecompile` constructor. - pub(crate) const fn new( + pub const fn new( precompile: DynPrecompile, cache: PrecompileCache, spec_id: S, @@ -118,7 +119,8 @@ where Self { precompile, cache, spec_id, metrics } } - pub(crate) fn wrap( + /// Wrap the given precompile in a cached precompile. + pub fn wrap( precompile: DynPrecompile, cache: PrecompileCache, spec_id: S, @@ -196,18 +198,18 @@ where /// Metrics for the cached precompile. #[derive(reth_metrics::Metrics, Clone)] #[metrics(scope = "sync.caching")] -pub(crate) struct CachedPrecompileMetrics { +pub struct CachedPrecompileMetrics { /// Precompile cache hits - precompile_cache_hits: metrics::Counter, + pub precompile_cache_hits: metrics::Counter, /// Precompile cache misses - precompile_cache_misses: metrics::Counter, + pub precompile_cache_misses: metrics::Counter, /// Precompile cache size. Uses the LRU cache length as the size metric. - precompile_cache_size: metrics::Gauge, + pub precompile_cache_size: metrics::Gauge, /// Precompile execution errors. - precompile_errors: metrics::Counter, + pub precompile_errors: metrics::Counter, } impl CachedPrecompileMetrics { @@ -215,7 +217,7 @@ impl CachedPrecompileMetrics { /// /// Adds address as an `address` label padded with zeros to at least two hex symbols, prefixed /// by `0x`. - pub(crate) fn new_with_address(address: Address) -> Self { + pub fn new_with_address(address: Address) -> Self { Self::new_with_labels(&[("address", format!("0x{address:02x}"))]) } } diff --git a/crates/engine/tree/src/tree/state.rs b/crates/engine/tree/src/tree/state.rs index 2827997a9d..b71b29fa64 100644 --- a/crates/engine/tree/src/tree/state.rs +++ b/crates/engine/tree/src/tree/state.rs @@ -48,7 +48,7 @@ pub struct TreeState { impl TreeState { /// Returns a new, empty tree state that points to the given canonical head. - pub(crate) fn new(current_canonical_head: BlockNumHash, engine_kind: EngineApiKind) -> Self { + pub fn new(current_canonical_head: BlockNumHash, engine_kind: EngineApiKind) -> Self { Self { blocks_by_hash: HashMap::default(), blocks_by_number: BTreeMap::new(), @@ -60,25 +60,22 @@ impl TreeState { } /// Resets the state and points to the given canonical head. - pub(crate) fn reset(&mut self, current_canonical_head: BlockNumHash) { + pub fn reset(&mut self, current_canonical_head: BlockNumHash) { *self = Self::new(current_canonical_head, self.engine_kind); } /// Returns the number of executed blocks stored. - pub(crate) fn block_count(&self) -> usize { + pub fn block_count(&self) -> usize { self.blocks_by_hash.len() } /// Returns the [`ExecutedBlock`] by hash. - pub(crate) fn executed_block_by_hash(&self, hash: B256) -> Option<&ExecutedBlock> { + pub fn executed_block_by_hash(&self, hash: B256) -> Option<&ExecutedBlock> { self.blocks_by_hash.get(&hash) } /// Returns the sealed block header by hash. - pub(crate) fn sealed_header_by_hash( - &self, - hash: &B256, - ) -> Option> { + pub fn sealed_header_by_hash(&self, hash: &B256) -> Option> { self.blocks_by_hash.get(hash).map(|b| b.sealed_block().sealed_header().clone()) } @@ -87,7 +84,7 @@ impl TreeState { /// highest persisted block connected to this chain. /// /// Returns `None` if the block for the given hash is not found. - pub(crate) fn blocks_by_hash(&self, hash: B256) -> Option<(B256, Vec>)> { + pub fn blocks_by_hash(&self, hash: B256) -> Option<(B256, Vec>)> { let block = self.blocks_by_hash.get(&hash).cloned()?; let mut parent_hash = block.recovered_block().parent_hash(); let mut blocks = vec![block]; @@ -160,7 +157,7 @@ impl TreeState { } /// Insert executed block into the state. - pub(crate) fn insert_executed(&mut self, executed: ExecutedBlock) { + pub fn insert_executed(&mut self, executed: ExecutedBlock) { let hash = executed.recovered_block().hash(); let parent_hash = executed.recovered_block().parent_hash(); let block_number = executed.recovered_block().number(); @@ -216,7 +213,7 @@ impl TreeState { } /// Returns whether or not the hash is part of the canonical chain. - pub(crate) fn is_canonical(&self, hash: B256) -> bool { + pub fn is_canonical(&self, hash: B256) -> bool { let mut current_block = self.current_canonical_head.hash; if current_block == hash { return true @@ -234,11 +231,7 @@ impl TreeState { /// Removes canonical blocks below the upper bound, only if the last persisted hash is /// part of the canonical chain. - pub(crate) fn remove_canonical_until( - &mut self, - upper_bound: BlockNumber, - last_persisted_hash: B256, - ) { + pub fn remove_canonical_until(&mut self, upper_bound: BlockNumber, last_persisted_hash: B256) { debug!(target: "engine::tree", ?upper_bound, ?last_persisted_hash, "Removing canonical blocks from the tree"); // If the last persisted hash is not canonical, then we don't want to remove any canonical @@ -263,7 +256,7 @@ impl TreeState { /// Removes all blocks that are below the finalized block, as well as removing non-canonical /// sidechains that fork from below the finalized block. - pub(crate) fn prune_finalized_sidechains(&mut self, finalized_num_hash: BlockNumHash) { + pub fn prune_finalized_sidechains(&mut self, finalized_num_hash: BlockNumHash) { let BlockNumHash { number: finalized_num, hash: finalized_hash } = finalized_num_hash; // We remove disconnected sidechains in three steps: @@ -323,7 +316,7 @@ impl TreeState { /// NOTE: if the finalized block is greater than the upper bound, the only blocks that will be /// removed are canonical blocks and sidechains that fork below the `upper_bound`. This is the /// same behavior as if the `finalized_num` were `Some(upper_bound)`. - pub(crate) fn remove_until( + pub fn remove_until( &mut self, upper_bound: BlockNumHash, last_persisted_hash: B256, @@ -361,22 +354,22 @@ impl TreeState { } /// Updates the canonical head to the given block. - pub(crate) const fn set_canonical_head(&mut self, new_head: BlockNumHash) { + pub const fn set_canonical_head(&mut self, new_head: BlockNumHash) { self.current_canonical_head = new_head; } /// Returns the tracked canonical head. - pub(crate) const fn canonical_head(&self) -> &BlockNumHash { + pub const fn canonical_head(&self) -> &BlockNumHash { &self.current_canonical_head } /// Returns the block hash of the canonical head. - pub(crate) const fn canonical_block_hash(&self) -> B256 { + pub const fn canonical_block_hash(&self) -> B256 { self.canonical_head().hash } /// Returns the block number of the canonical head. - pub(crate) const fn canonical_block_number(&self) -> BlockNumber { + pub const fn canonical_block_number(&self) -> BlockNumber { self.canonical_head().number } } @@ -386,7 +379,7 @@ impl TreeState { /// Determines if the second block is a descendant of the first block. /// /// If the two blocks are the same, this returns `false`. - pub(crate) fn is_descendant( + pub fn is_descendant( &self, first: BlockNumHash, second: alloy_eips::eip1898::BlockWithParent,