Skip to main content

CachingDatabase

Struct CachingDatabase 

Source
pub struct CachingDatabase { /* private fields */ }
Expand description

A database wrapper that caches state lookups for parallel pre-warming.

This enables parallel warming workers to share cached data, and allows the sequential execution phase to reuse warmed state. Reduces redundant database/trie lookups when multiple transactions touch the same accounts.

Thread-safe via RwLock - optimized for read-heavy concurrent access.

This caching database is inspired by reth’s overlay/proof worker cache.

Besides the per-block warmer/executor sharing above, the mempool prewarmer builds one instance per slot and publishes it across the block boundary: execute_block_pipeline seeds the next block’s execution with it when the parent state and fork match (see ethrex-blockchain::prewarm).

§Invariant

Because one instance is shared across the block boundary (and the prewarmer may still be filling it while the next block executes), every cached entry must be a pure function of the parent state root. A cache layer whose entries also depend on the executing block (fork, number, timestamp, …) needs a matching handoff guard in execute_block_pipeline — see precompile_cache, whose fork-dependent entries are covered by the fork-equality check there.

Implementations§

Source§

impl CachingDatabase

Source

pub fn new(inner: Arc<dyn Database>, precompile_cache_enabled: bool) -> Self

Source

pub fn code_bytes(&self) -> u64

Total Code::size of the bytecode this cache holds.

Source

pub fn touched_keys_where( &self, account_filter: &dyn Fn(&Address) -> bool, slot_filter: &dyn Fn(&(Address, H256)) -> bool, ) -> TouchedKeys

Snapshot of the touched key sets matching the given filters: cached accounts (with their storage roots) and cached storage slot keys. The filters let a caller that tracks already-processed keys collect only the delta, keeping the per-call allocation O(new) while the scan stays O(cache).

Trait Implementations§

Source§

impl Database for CachingDatabase

Source§

fn get_account_states_batch( &self, addresses: &[Address], ) -> Result<Vec<AccountState>, DatabaseError>

Warms every address through Self::prefetch_accounts, then answers from the cache under one read lock. Repeated addresses cost a single database read, and a caller that wants the states pays one map lookup each rather than a full get_account_state round trip per address.

The read lock spans the whole assembly, so callers should keep addresses to a bounded slice: a writer (an executor filling the same cache) waits on it.

Source§

fn prefetch_codes(&self, code_hashes: &[H256]) -> Result<u64, DatabaseError>

Fetches the uncached bytecodes in one batch and inserts them, reading each distinct hash once however many entries share it.

Returns only the warmed byte count, not the bytecodes: the executor reads code through Self::get_account_code, which this turns into a cache hit. Assembling a result vector here would hold the write lock that guards every executor code read for the length of the batch, to build something a warming caller discards.

Source§

fn get_account_state( &self, address: Address, ) -> Result<AccountState, DatabaseError>

Source§

fn get_storage_value( &self, address: Address, key: H256, ) -> Result<U256, DatabaseError>

Source§

fn get_block_hash(&self, block_number: u64) -> Result<H256, DatabaseError>

Source§

fn get_chain_config(&self) -> Result<ChainConfig, DatabaseError>

Source§

fn get_account_code(&self, code_hash: H256) -> Result<Code, DatabaseError>

Source§

fn get_code_metadata( &self, code_hash: H256, ) -> Result<CodeMetadata, DatabaseError>

Source§

fn precompile_cache(&self) -> Option<&PrecompileCache>

Access the precompile cache, if available at this database layer.
Source§

fn code_cache_budget_bytes(&self) -> u64

Byte budget for warming bytecode ahead of execution, as measured by Code::size. Read more
Source§

fn prefetch_accounts(&self, addresses: &[Address]) -> Result<(), DatabaseError>

Prefetch a batch of accounts into the cache. Default: sequential fallback.
Source§

fn prefetch_storage( &self, keys: &[(Address, H256)], ) -> Result<(), DatabaseError>

Prefetch a batch of storage slots into the cache. Default: sequential fallback.
Source§

fn get_account_codes_batch( &self, code_hashes: &[H256], ) -> Result<Vec<Option<Code>>, DatabaseError>

Batch bytecode lookup, aligned to code_hashes. None means the hash is absent from the database. Default: loop. Backends with a batched read path (e.g. rocksdb multi_get_cf on the account-codes table) should override this; the caching layer above dispatches to it from Self::prefetch_codes.
Source§

fn get_storage_values_batch( &self, keys: &[(Address, H256)], ) -> Result<Vec<U256>, DatabaseError>

Batch storage-slot lookup. Default: loop. Backends with a batched read path (e.g. rocksdb multi_get_cf on the storage flat key-value table) should override this and the caching layer above will dispatch to it.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> ArchivePointee for T

Source§

type ArchivedMetadata = ()

The archived version of the pointer metadata for this type.
Source§

fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata

Converts some archived metadata to the pointer metadata for itself.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T, U> ExactFrom<T> for U
where U: TryFrom<T>,

Source§

fn exact_from(value: T) -> U

Source§

impl<T, U> ExactInto<U> for T
where U: ExactFrom<T>,

Source§

fn exact_into(self) -> U

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> LayoutRaw for T

Source§

fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>

Returns the layout of the type.
Source§

impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
where T: SharedNiching<N1, N2>, N1: Niching<T>, N2: Niching<T>,

Source§

unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool

Returns whether the given value has been niched. Read more
Source§

fn resolve_niched(out: Place<NichedOption<T, N1>>)

Writes data to out indicating that a T is niched.
Source§

impl<T, U> OverflowingInto<U> for T
where U: OverflowingFrom<T>,

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Pointee for T

Source§

type Metadata = ()

The metadata type for pointers and references to this type.
Source§

impl<T, U> RoundingInto<U> for T
where U: RoundingFrom<T>,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> SaturatingInto<U> for T
where U: SaturatingFrom<T>,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T, U> WrappingInto<U> for T
where U: WrappingFrom<T>,

Source§

fn wrapping_into(self) -> U