Skip to main content

Store

Struct Store 

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

Main storage interface for the ethrex client.

Store is Clone and thread-safe; all clones share the same backend and caches via Arc. Reads consult an in-memory block-data buffer before disk so not-yet-flushed blocks are always visible.

Implementations§

Source§

impl Store

Source

pub async fn wait_for_persistence_idle(&self) -> Result<(), StoreError>

Block until the persist worker has fully processed all previously-sent Block messages (staged, trie-layer built, flushed, evicted).

Uses an ack-based Ping rather than a bare send because the channel is buffered — a bare send proves nothing about prior message completion. The worker is FIFO, so it handles the Ping only after every earlier Block is done.

Concurrent-producer caveat: if another thread sends a Block after the Ping is enqueued, that block may not be flushed by the time this returns.

Source

pub async fn shutdown(&self) -> Result<(), StoreError>

Flushes all in-memory state to disk for a clean shutdown.

Sends a Shutdown handshake to the persist worker, which (being FIFO) first drains every queued Block, then force-flushes the block-data buffer to disk. Once the worker acks, this syncs the backend (memtables + WAL) so the next process start needs no WAL recovery.

The in-memory trie diff-layers are intentionally not force-committed. The on-disk trie is a single-version, path-based store, so folding the non-finalized tail into it would leave a post-restart reorg unable to reconstruct the overwritten ancestor state (the node would wedge). The recent (< DB_COMMIT_THRESHOLD) layers are dropped and re-executed on the next start from the deep, reorg-safe on-disk base — exactly as after any restart today.

After this returns the persist worker has exited; the store must not be used for further writes. Idempotent only in the sense that a second call errors on the closed channel — call it exactly once, on shutdown.

Source

pub async fn add_block(&self, block: Block) -> Result<(), StoreError>

Add a block in a single transaction. This will store -> BlockHeader, BlockBody, BlockTransactions, BlockNumber.

Source

pub async fn add_blocks(&self, blocks: Vec<Block>) -> Result<(), StoreError>

Add a batch of blocks in a single transaction. This will store -> BlockHeader, BlockBody, BlockTransactions, BlockNumber.

Source

pub async fn add_block_header( &self, block_hash: BlockHash, block_header: BlockHeader, ) -> Result<(), StoreError>

Add block header

Source

pub async fn add_block_headers( &self, block_headers: Vec<BlockHeader>, ) -> Result<(), StoreError>

Add a batch of block headers

Source

pub fn get_block_header( &self, block_number: BlockNumber, ) -> Result<Option<BlockHeader>, StoreError>

Obtain canonical block header

Source

pub async fn add_block_body( &self, block_hash: BlockHash, block_body: BlockBody, ) -> Result<(), StoreError>

Add block body

Source

pub async fn add_backfilled_blocks( &self, blocks: Vec<BackfilledBlock>, new_earliest: BlockNumber, ) -> Result<(), StoreError>

Backfill historical chain data for a contiguous range of already-canonical blocks (bodies, receipts, and optionally the transaction-lookup index), then lower earliest_block_number to new_earliest — all in one write transaction.

This is the storage half of --history.chain backfill. It does NOT touch state, the trie layer cache, or fork choice: the headers and canonical mapping already exist from snap-sync header backfill, so only the body / receipt / tx-index tables are filled. Writing the data and advancing the frontier atomically preserves the invariant that every block in [earliest_block_number, head] has a stored body — a crash mid-batch leaves both the data and the frontier unchanged, so resume never skips a hole.

new_earliest must be the lowest block number covered by blocks (the bottom of the contiguous filled range); the caller fills downward without gaps.

Source

pub fn rocksdb_stats(&self) -> Option<RocksDbStats>

RocksDB observability snapshot (per-column-family sizes/keys/files, block cache, compaction). None for the in-memory backend. Read by the metrics collector; cheap (RocksDB property reads).

Source

pub async fn get_block_body( &self, block_number: BlockNumber, ) -> Result<Option<BlockBody>, StoreError>

Obtain canonical block body

Source

pub async fn remove_block( &self, block_number: BlockNumber, ) -> Result<(), StoreError>

Remove canonical block

Source

pub async fn get_block_bodies( &self, from: BlockNumber, to: BlockNumber, ) -> Result<Vec<Option<BlockBody>>, StoreError>

Obtain canonical block bodies in from..=to

Source

pub async fn get_block_bodies_by_hash( &self, hashes: Vec<BlockHash>, ) -> Result<Vec<BlockBody>, StoreError>

Obtain block bodies from a list of hashes

Source

pub async fn get_block_body_by_hash( &self, block_hash: BlockHash, ) -> Result<Option<BlockBody>, StoreError>

Obtain any block body using the hash

Source

pub fn get_block_header_by_hash( &self, block_hash: BlockHash, ) -> Result<Option<BlockHeader>, StoreError>

Source

pub fn add_pending_block(&self, block: Block) -> Result<(), StoreError>

Source

pub async fn get_pending_block( &self, block_hash: BlockHash, ) -> Result<Option<Block>, StoreError>

Source

pub async fn add_block_number( &self, block_hash: BlockHash, block_number: BlockNumber, ) -> Result<(), StoreError>

Add block number for a given hash

Source

pub async fn get_block_number( &self, block_hash: BlockHash, ) -> Result<Option<BlockNumber>, StoreError>

Obtain block number for a given hash

Source

pub async fn add_transaction_location( &self, transaction_hash: H256, block_number: BlockNumber, block_hash: BlockHash, index: Index, ) -> Result<(), StoreError>

Store transaction location (block number and index of the transaction within the block)

Source

pub async fn add_transaction_locations( &self, locations: Vec<(H256, BlockNumber, BlockHash, Index)>, ) -> Result<(), StoreError>

Store transaction locations in batch (one db transaction for all)

Source

pub async fn get_transaction_location( &self, transaction_hash: H256, ) -> Result<Option<(BlockNumber, BlockHash, Index)>, StoreError>

Obtain transaction location (block hash and index)

Source

pub async fn add_receipt( &self, block_hash: BlockHash, index: Index, receipt: Receipt, ) -> Result<(), StoreError>

Add receipt

Source

pub async fn add_receipts( &self, block_hash: BlockHash, receipts: Vec<Receipt>, ) -> Result<(), StoreError>

Add receipts

Source

pub async fn get_receipt( &self, block_number: BlockNumber, index: Index, ) -> Result<Option<Receipt>, StoreError>

Obtain receipt for a canonical block represented by the block number.

Source

pub fn code_cache_budget_bytes(&self) -> u64

Capacity of the bytecode cache, in Code::size bytes, which is how much bytecode this node is configured to keep resident and so bounds what a block warm reads speculatively.

A poisoned cache reports zero, which stops warming rather than warming into a cache no reader can reach.

Source

pub fn get_account_code( &self, code_hash: H256, ) -> Result<Option<Code>, StoreError>

Get account code by its hash.

Checks the in-memory block-data buffer first, then the LRU cache (account_code_cache), and finally the database. Code that has been inserted via engine_newPayload but not yet flushed to disk is therefore visible to callers without an explicit flush.

Source

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

Batched Self::get_account_code.

Resolves the buffer and the LRU first, then reads whatever is left by whichever of two strategies gets more of those reads in flight for a batch this size: a parallel fan-out of point gets, or sorted keys split into contiguous shards read concurrently. See the comment on the read below for how the choice is made. The LRU is locked once for the whole batch rather than twice per code.

Results are returned in the order of code_hashes. Duplicate hashes are read once. None means the hash is absent from the database.

Source

pub fn code_exists(&self, code_hash: H256) -> Result<bool, StoreError>

Check if account code exists by its hash, without constructing the full Code struct. More efficient than get_account_code for existence checks since it skips RLP decoding and Code struct construction (no jumpdest-bitmap decoding). Note: The underlying get() still reads the value from RocksDB (including blob files).

Source

pub fn get_code_metadata( &self, code_hash: H256, ) -> Result<Option<CodeMetadata>, StoreError>

Get code metadata (length) by its hash.

Checks cache first, falls back to database. If metadata is missing, falls back to loading full code and extracts length (auto-migration).

Source

pub async fn add_account_code(&self, code: Code) -> Result<(), StoreError>

Add account code

Source

pub async fn clear_snap_state(&self) -> Result<(), StoreError>

Clears all checkpoint data created during the last snap sync

Source

pub async fn get_transaction_by_hash( &self, transaction_hash: H256, ) -> Result<Option<Transaction>, StoreError>

Source

pub async fn get_transaction_by_location( &self, block_hash: H256, index: u64, ) -> Result<Option<Transaction>, StoreError>

Source

pub async fn get_block_by_hash( &self, block_hash: BlockHash, ) -> Result<Option<Block>, StoreError>

Source

pub async fn get_block_by_number( &self, block_number: BlockNumber, ) -> Result<Option<Block>, StoreError>

Source

pub async fn get_canonical_block_hash( &self, block_number: BlockNumber, ) -> Result<Option<BlockHash>, StoreError>

Source

pub async fn set_chain_config( &mut self, chain_config: &ChainConfig, ) -> Result<(), StoreError>

Stores the chain configuration values, should only be called once after reading the genesis file Ignores previously stored values if present

Source

pub async fn update_earliest_block_number( &self, block_number: BlockNumber, ) -> Result<(), StoreError>

Update earliest block number

Source

pub async fn get_earliest_block_number(&self) -> Result<BlockNumber, StoreError>

Obtain earliest block number

Source

pub async fn get_finalized_block_number( &self, ) -> Result<Option<BlockNumber>, StoreError>

Obtain finalized block number

Source

pub async fn get_safe_block_number( &self, ) -> Result<Option<BlockNumber>, StoreError>

Obtain safe block number

Source

pub fn get_latest_block_number(&self) -> Result<BlockNumber, StoreError>

Obtain latest block number

Source

pub async fn update_pending_block_number( &self, block_number: BlockNumber, ) -> Result<(), StoreError>

Update pending block number

Source

pub async fn get_pending_block_number( &self, ) -> Result<Option<BlockNumber>, StoreError>

Obtain pending block number

Source

pub async fn get_receipts_for_block( &self, block_hash: &BlockHash, ) -> Result<Vec<Receipt>, StoreError>

Source

pub async fn get_receipts_for_block_from_index( &self, block_hash: &BlockHash, start_index: u64, max_count: Option<usize>, ) -> Result<Vec<Receipt>, StoreError>

Retrieves receipts for a block starting from the given index, optionally limited to max_count receipts.

Uses cursor-based prefix iteration over the 32-byte block hash prefix for efficient batch retrieval. Used by:

  • eth/70 partial receipt requests (EIP-7975) via p2p
  • eth_getTransactionReceipt RPC with a count limit to avoid fetching the entire block’s receipts
Source

pub async fn set_header_download_checkpoint( &self, block_hash: BlockHash, ) -> Result<(), StoreError>

Sets the hash of the last header downloaded during a snap sync

Source

pub async fn get_header_download_checkpoint( &self, ) -> Result<Option<BlockHash>, StoreError>

Gets the hash of the last header downloaded during a snap sync

Source

pub async fn set_latest_valid_ancestor( &self, bad_block: BlockHash, latest_valid: BlockHash, ) -> Result<(), StoreError>

The forkchoice_update and new_payload methods require the latest_valid_hash when processing an invalid payload. To provide this, we must track invalid chains.

We only store the last known valid head upon encountering a bad block, rather than tracking every subsequent invalid block.

Source

pub async fn get_latest_valid_ancestor( &self, block: BlockHash, ) -> Result<Option<BlockHash>, StoreError>

Returns the latest valid ancestor hash for a given invalid block hash. Used to provide latest_valid_hash in the Engine API when processing invalid payloads.

Source

pub async fn add_bad_block(&self, block: Block) -> Result<(), StoreError>

Records a block that failed validation so it can be served by debug_getBadBlocks. The list is bounded to [MAX_BAD_BLOCKS] entries, kept sorted by descending block number, with the oldest dropped once the bound is exceeded. Duplicate (number, hash) entries are ignored.

Source

pub async fn get_bad_blocks(&self) -> Result<Vec<Block>, StoreError>

Returns the recent bad blocks seen by the client, sorted by descending block number. Used by debug_getBadBlocks.

Source

pub fn get_block_number_sync( &self, block_hash: BlockHash, ) -> Result<Option<BlockNumber>, StoreError>

Obtain block number for a given hash

Source

pub fn get_canonical_block_hash_sync( &self, block_number: BlockNumber, ) -> Result<Option<BlockHash>, StoreError>

Get the canonical block hash for a given block number.

Source

pub async fn write_storage_trie_nodes_batch( &self, storage_trie_nodes: StorageUpdates, ) -> Result<(), StoreError>

CAUTION: This method writes directly to the underlying database, bypassing any caching layer. For updating the state after block execution, use Self::store_block_updates.

Source

pub async fn write_account_code_batch( &self, account_codes: Vec<(H256, Code)>, ) -> Result<(), StoreError>

CAUTION: This method writes directly to the underlying database, bypassing any caching layer. For updating the state after block execution, use Self::store_block_updates.

Source

pub fn write( &self, table: &'static str, key: Vec<u8>, value: Vec<u8>, ) -> Result<(), StoreError>

Helper method for async writes Spawns blocking task to avoid blocking tokio runtime

Source

pub async fn read_async( &self, table: &'static str, key: Vec<u8>, ) -> Result<Option<Vec<u8>>, StoreError>

Helper method for async reads Spawns blocking task to avoid blocking tokio runtime

Source

pub fn read( &self, table: &'static str, key: Vec<u8>, ) -> Result<Option<Vec<u8>>, StoreError>

Helper method for sync reads Spawns blocking task to avoid blocking tokio runtime

Source

pub async fn write_batch_async( &self, table: &'static str, batch_ops: Vec<(Vec<u8>, Vec<u8>)>, ) -> Result<(), StoreError>

Helper method for batch writes Spawns blocking task to avoid blocking tokio runtime This is the most important optimization for healing performance

Source

pub fn write_batch( &self, table: &'static str, batch_ops: Vec<(Vec<u8>, Vec<u8>)>, ) -> Result<(), StoreError>

Helper method for batch writes

Source

pub async fn add_fullsync_batch( &self, headers: Vec<BlockHeader>, ) -> Result<(), StoreError>

Source

pub async fn read_fullsync_batch( &self, start: BlockNumber, limit: u64, ) -> Result<Vec<Option<BlockHeader>>, StoreError>

Source

pub async fn clear_fullsync_headers(&self) -> Result<(), StoreError>

Source

pub fn delete( &self, table: &'static str, key: Vec<u8>, ) -> Result<(), StoreError>

Delete a key from a table

Source

pub fn store_block_updates( &self, update_batch: UpdateBatch, ) -> Result<(), StoreError>

Source

pub fn new( path: impl AsRef<Path>, engine_type: EngineType, ) -> Result<Self, StoreError>

Opens (or creates) a store at path with the default StoreConfig.

Production callers that need to override storage tunables (e.g. the RocksDB block cache size from a CLI option) should use Store::new_with_config.

Source

pub fn new_with_config( path: impl AsRef<Path>, engine_type: EngineType, config: StoreConfig, ) -> Result<Self, StoreError>

Opens (or creates) a store at path, applying the supplied StoreConfig.

Source

pub async fn new_from_genesis( store_path: &Path, engine_type: EngineType, genesis_path: &str, ) -> Result<Self, StoreError>

Opens (or creates) a store at store_path and seeds it from the given genesis file, using the default StoreConfig.

Source

pub async fn new_from_genesis_with_config( store_path: &Path, engine_type: EngineType, genesis_path: &str, config: StoreConfig, ) -> Result<Self, StoreError>

Opens (or creates) a store at store_path from genesis, applying the supplied StoreConfig.

Source

pub async fn get_account_info( &self, block_number: BlockNumber, address: Address, ) -> Result<Option<AccountInfo>, StoreError>

Source

pub fn get_account_info_by_hash( &self, block_hash: BlockHash, address: Address, ) -> Result<Option<AccountInfo>, StoreError>

Source

pub fn get_account_state_by_acc_hash( &self, block_hash: BlockHash, account_hash: H256, ) -> Result<Option<AccountState>, StoreError>

Source

pub async fn get_fork_id(&self) -> Result<ForkId, StoreError>

Source

pub async fn get_code_by_account_address( &self, block_number: BlockNumber, address: Address, ) -> Result<Option<Code>, StoreError>

Source

pub async fn get_nonce_by_account_address( &self, block_number: BlockNumber, address: Address, ) -> Result<Option<u64>, StoreError>

Source

pub fn apply_account_updates_batch( &self, block_hash: BlockHash, account_updates: &[AccountUpdate], ) -> Result<Option<AccountUpdatesList>, StoreError>

Applies account updates based on the block’s latest storage state and returns the new state root after the updates have been applied.

Source

pub fn apply_account_updates_from_trie_batch<'a>( &self, state_trie: &mut Trie, account_updates: impl IntoIterator<Item = &'a AccountUpdate>, ) -> Result<AccountUpdatesList, StoreError>

Source

pub fn apply_account_updates_from_trie_with_witness( &self, state_trie: Trie, account_updates: &[AccountUpdate], storage_tries: HashMap<Address, (TrieWitness, Trie)>, ) -> Result<(HashMap<Address, (TrieWitness, Trie)>, AccountUpdatesList), StoreError>

Performs the same actions as apply_account_updates_from_trie but also returns the used storage tries with witness recorded

Source

pub async fn setup_genesis_state_trie( &self, genesis_accounts: BTreeMap<Address, GenesisAccount>, ) -> Result<H256, StoreError>

Adds all genesis accounts and returns the genesis block’s state_root

Source

pub fn store_witness( &self, block_hash: BlockHash, block_number: u64, witness: ExecutionWitness, ) -> Result<(), StoreError>

Stores a pre-serialized execution witness for a block.

The witness is converted to RPC format (RpcExecutionWitness) before storage to avoid expensive encode_subtrie traversal on every read. This pre-computes the serialization at write time instead of read time.

Source

pub fn get_witness_json_bytes( &self, block_number: u64, block_hash: BlockHash, ) -> Result<Option<Vec<u8>>, StoreError>

Returns the raw JSON bytes of a cached witness for a block.

This is the most efficient method for the RPC handler since it avoids deserialization and re-serialization. The bytes can be parsed directly as a JSON Value for the RPC response.

Source

pub fn get_witness_by_number_and_hash( &self, block_number: u64, block_hash: BlockHash, ) -> Result<Option<RpcExecutionWitness>, StoreError>

Returns the deserialized RpcExecutionWitness for a block.

Prefer get_witness_json_bytes when you need to return the witness as JSON (e.g., for RPC responses) to avoid re-serialization.

Source

pub fn store_block_access_list( &self, block_hash: BlockHash, bal: &BlockAccessList, ) -> Result<(), StoreError>

Stores a block access list for a given block hash.

Source

pub fn get_block_access_list( &self, block_hash: BlockHash, ) -> Result<Option<BlockAccessList>, StoreError>

Returns the block access list for a given block hash, if stored.

Source

pub async fn add_initial_state( &mut self, genesis: Genesis, ) -> Result<(), StoreError>

Source

pub async fn add_initial_state_skip_validation( &mut self, genesis: Genesis, ) -> Result<(), StoreError>

Like Store::add_initial_state, but trusts a pre-existing datadir’s state instead of validating it against the provided genesis. If a genesis header is already stored, it is kept as-is rather than recomputing the genesis state root from genesis.alloc and rejecting on mismatch. The chain config from the genesis file is still applied either way.

Intended for booting a datadir produced out-of-band (e.g. by a state generator that writes the state trie directly and emits a genesis file with an empty alloc), where the operator vouches for the stored state root. Has no effect on a fresh datadir: the genesis is built normally.

Source

pub async fn load_initial_state(&self) -> Result<(), StoreError>

Source

pub fn get_storage_at( &self, block_number: BlockNumber, address: Address, storage_key: H256, ) -> Result<Option<U256>, StoreError>

Source

pub fn get_storage_at_root( &self, state_root: H256, address: Address, storage_key: H256, ) -> Result<Option<U256>, StoreError>

Source

pub fn get_storage_at_root_with_known_storage_root( &self, state_root: H256, account_hash: H256, storage_root: H256, storage_key: H256, ) -> Result<Option<U256>, StoreError>

Gets storage value when the account hash and storage root are already known.

This skips the state-trie account lookup and account RLP decode done by Self::get_storage_at_root, and directly opens the account storage trie.

Source

pub fn get_chain_config(&self) -> ChainConfig

Source

pub async fn get_latest_canonical_block_hash( &self, ) -> Result<Option<BlockHash>, StoreError>

Source

pub async fn forkchoice_update( &self, new_canonical_blocks: Vec<(BlockNumber, BlockHash)>, head_number: BlockNumber, head_hash: BlockHash, safe: Option<BlockNumber>, finalized: Option<BlockNumber>, ) -> Result<(), StoreError>

Updates the canonical chain. Inserts new canonical blocks, removes blocks beyond the new head, and updates the head, safe, and finalized block pointers. All operations are performed in a single database transaction.

Source

pub fn state_trie( &self, block_hash: BlockHash, ) -> Result<Option<Trie>, StoreError>

Obtain the storage trie for the given block

Source

pub fn storage_trie( &self, block_hash: BlockHash, address: Address, ) -> Result<Option<Trie>, StoreError>

Obtain the storage trie for the given account on the given block

Source

pub async fn get_account_state( &self, block_number: BlockNumber, address: Address, ) -> Result<Option<AccountState>, StoreError>

Source

pub fn get_account_state_by_root( &self, state_root: H256, address: Address, ) -> Result<Option<AccountState>, StoreError>

Source

pub fn get_account_state_from_trie( &self, state_trie: &Trie, address: Address, ) -> Result<Option<AccountState>, StoreError>

Source

pub fn get_account_states_batch_by_root( &self, state_root: H256, addresses: &[Address], ) -> Result<Vec<Option<AccountState>>, StoreError>

Batch lookup of account states by address against a given state root.

Fast path: for addresses whose hashed path falls within the FKV cursor (and which are not present in the in-memory diff-layer cache), values are fetched in a single multi_get on ACCOUNT_FLATKEYVALUE. Other addresses fall back to per-address trie walks.

Results are returned in the same order as the input addresses.

Source

pub fn get_storage_values_batch_by_root( &self, state_root: H256, slots: &[(H256, H256, H256)], ) -> Result<Vec<Option<U256>>, StoreError>

Batch lookup of storage slot values against a given state root.

Each input tuple is (account_hash, storage_root, slot) where account_hash is the keccak hash of the account address and slot is the raw (un-hashed) storage key, matching the inputs available to Self::get_storage_at_root_with_known_storage_root.

Fast path: for slots whose prefixed FKV leaf path falls within the FKV cursor (and which are not present in the in-memory diff-layer cache), values are fetched in a single multi_get on STORAGE_FLATKEYVALUE. The batch is sorted by the prefixed FKV key (hashed order) before the multi_get so that adjacent slots share RocksDB data blocks, removing the random-order read amplification of per-slot lookups. Slots not yet swept by the FKV generator fall back to per-slot trie walks via Self::get_storage_at_root_with_known_storage_root, which preserves the exact FKV / trie / diff-cache ordering of the single-slot path.

Results are returned in the same order as the input slots. A missing slot (deleted or never written) yields None, identical to the single-get path.

Source

pub fn prefetch_trie_nodes( &self, storage_slots: &[(Address, H256)], accounts: &[Address], ) -> Result<usize, StoreError>

Best-effort warming of the MPT internal nodes the merkleizer will walk, driven entirely by the BAL working set. The merkle phase reads trie nodes from STORAGE_TRIE_NODES / ACCOUNT_TRIE_NODES (see BackendTrieDB::get) by nibble path; the existing flat-KV prefetch warms only the leaf-value CFs that execution reads, so every merkle-walk node read is otherwise cold. This pulls those node blocks into the page/block cache up front so the subsequent walk runs warm.

The keys are not discovered by walking (a walk is QD1 and serial): the internal nodes on the path to a leaf are all at prefixes of that leaf’s nibble path, so for every BAL leaf we speculatively probe every prefix up to MAX_PREFETCH_DEPTH. Prefixes that are not real nodes are rejected by the CF bloom filter in RAM (no disk read; measured ~free), and the shallow prefixes collapse on dedup. This turns the cold merkle node reads into one sorted, sharded, high-queue-depth multi_get per CF — the same lever that fixed the flat-KV sload path, applied to the trie-node CFs.

Results are discarded. Missing a node (e.g. one deeper than the probe band) is harmless: the merkleizer just cold-reads it. Run this synchronously up front (mirroring the flat-KV prefetch) so it never races the merkleizer; it touches different CFs than execution, so it does not contend with the executor either. Returns the number of probed keys that hit a real stored node (warmed). On the warm/no-op path this still reports coverage; a near-zero hit count against a non-empty working set signals a key-encoding mismatch (the effectiveness test asserts on this).

Source

pub async fn get_account_proof( &self, state_root: H256, address: Address, storage_keys: &[H256], ) -> Result<Option<AccountProof>, StoreError>

Constructs a merkle proof for the given account address against a given state. If storage_keys are provided, also constructs the storage proofs for those keys.

Returns None if the state trie is missing, otherwise returns the proof.

Source

pub fn iter_accounts_from( &self, state_root: H256, starting_address: H256, ) -> Result<impl Iterator<Item = (H256, AccountState)>, StoreError>

Source

pub fn iter_accounts( &self, state_root: H256, ) -> Result<impl Iterator<Item = (H256, AccountState)>, StoreError>

Source

pub fn iter_storage_from( &self, state_root: H256, hashed_address: H256, starting_slot: H256, ) -> Result<Option<impl Iterator<Item = (H256, U256)>>, StoreError>

Source

pub fn iter_storage( &self, state_root: H256, hashed_address: H256, ) -> Result<Option<impl Iterator<Item = (H256, U256)>>, StoreError>

Source

pub fn get_account_range_proof( &self, state_root: H256, starting_hash: H256, last_hash: Option<H256>, ) -> Result<Vec<Vec<u8>>, StoreError>

Source

pub fn get_storage_range_proof( &self, state_root: H256, hashed_address: H256, starting_hash: H256, last_hash: Option<H256>, ) -> Result<Option<Vec<Vec<u8>>>, StoreError>

Source

pub fn get_trie_nodes( &self, state_root: H256, paths: Vec<Vec<u8>>, byte_limit: u64, ) -> Result<Vec<Vec<u8>>, StoreError>

Receives the root of the state trie and a list of paths where the first path will correspond to a path in the state trie (aka a hashed account address) and the following paths will be paths in the account’s storage trie (aka hashed storage keys) If only one hash (account) is received, then the state trie node containing the account will be returned. If more than one hash is received, then the storage trie nodes where each storage key is stored will be returned For more information check out snap capability message GetTrieNodes The paths can be either full paths (hash) or partial paths (compact-encoded nibbles), if a partial path is given for the account this method will not return storage nodes for it

Source

pub fn open_state_trie(&self, state_root: H256) -> Result<Trie, StoreError>

Obtain a state trie from the given state root Doesn’t check if the state root is valid Used for internal store operations

Source

pub fn open_direct_state_trie( &self, state_root: H256, ) -> Result<Trie, StoreError>

Obtain a state trie from the given state root Doesn’t check if the state root is valid Used for internal store operations

Source

pub fn open_locked_state_trie( &self, state_root: H256, ) -> Result<Trie, StoreError>

Obtain a state trie locked for reads from the given state root Doesn’t check if the state root is valid Used for internal store operations

Source

pub fn open_storage_trie( &self, account_hash: H256, state_root: H256, storage_root: H256, ) -> Result<Trie, StoreError>

Obtain a storage trie from the given address and storage_root. Doesn’t check if the account is stored

Source

pub fn open_direct_storage_trie( &self, account_hash: H256, storage_root: H256, ) -> Result<Trie, StoreError>

Obtain a storage trie from the given address and storage_root. Doesn’t check if the account is stored

Source

pub fn open_locked_storage_trie( &self, account_hash: H256, state_root: H256, storage_root: H256, ) -> Result<Trie, StoreError>

Obtain a read-locked storage trie from the given address and storage_root. Doesn’t check if the account is stored

Source

pub fn has_state_root(&self, state_root: H256) -> Result<bool, StoreError>

Source

pub fn is_state_in_layer_cache( &self, state_root: H256, ) -> Result<bool, StoreError>

Returns true if the in-memory layer cache currently has a layer with the given state_root. Used by the deep-reorg orchestrator to decide whether the head’s state can be reached through forward execution (cache hit) or whether a deep-reorg path with overlay construction is required.

Source

pub fn highest_state_history_block_number( &self, ) -> Result<Option<BlockNumber>, StoreError>

Returns the highest block number with a STATE_HISTORY entry; the cache edge D (the deepest block whose post-state is on disk). Returns None if the journal is empty (no commits since boot, or fully pruned by finality).

O(1) via reverse seek on the column family’s last key.

Source

pub fn get_state_history_block_hash( &self, block_number: BlockNumber, ) -> Result<Option<BlockHash>, StoreError>

Returns the hash of the block whose trie-layer commit the STATE_HISTORY entry at block_number journals, or None when there is no entry.

The persist worker stages one entry per committed layer, so the entry at Self::highest_state_history_block_number identifies the block whose post-state is the one on disk.

Source

pub fn lowest_state_history_block_number( &self, ) -> Result<Option<BlockNumber>, StoreError>

Returns the lowest block number with a STATE_HISTORY entry. Returns None if the journal is empty (no commits since boot, or fully pruned by finality).

O(1) via forward seek on the column family’s first key.

Source

pub fn reorg_retention(&self) -> Result<u64, StoreError>

The in-memory diff-layer retention (the layer cache’s commit threshold): the deepest reorg the node can serve straight from the layer cache, with no journal/overlay reconstruction. RocksDB default 128, in-memory 10000. Used by compute_reorg_ceiling as the physical floor when there is no finality signal.

Source

pub fn install_overlay_for_reorg( &self, from_block: BlockNumber, to_block: BlockNumber, expected_hash: impl Fn(BlockNumber) -> Option<H256>, ) -> Result<(), StoreError>

Atomically prepares the store for a deep-reorg apply pass.

Builds an [Overlay] from journal entries in [to_block, from_block] (inclusive both ends), verifies each entry’s block_hash against expected_hash, then swaps the in-memory layer cache for a fresh one with the overlay installed. After this call:

  • The layer cache contains zero forward layers.
  • The overlay is in place; subsequent TrieWrapper::get calls cascade layer cache -> overlay -> disk.
  • The on-disk trie/flat-KV state is unchanged (still at the OLD chain’s edge D).

Side-chain blocks [pivot+1 .. new_head] should now be executed in chain order through the normal Blockchain::add_block path; each block’s reads cascade through the overlay, and each block’s commit produces a new forward layer.

Errors abort the swap: if overlay construction fails (missing entry, hash mismatch, decode error), the existing layer cache is left intact.

Source

pub fn reorg_overlay_size_hint(&self) -> Result<(usize, usize), StoreError>

Returns (entry_count, byte_size) of the currently installed overlay, or (0, 0) when no overlay is installed. Used by the observability layer in fork_choice.rs immediately after install_overlay_for_reorg to emit ethrex_reorg_overlay_entries / ethrex_reorg_overlay_bytes.

Source

pub fn set_journal_pruning_paused(&self, paused: bool)

Pauses or resumes STATE_HISTORY pruning at finality advance (see the journal_pruning_paused field). Called by Blockchain::enter_reorg / ReorgGuard::drop to bracket a deep-reorg apply pass.

Source

pub fn clear_reorg_overlay(&self) -> Result<(), StoreError>

Removes any installed overlay from the layer cache. Called by the reconciliation path after the first new-chain commit folds the overlay into disk. Idempotent.

Source

pub fn abort_reorg(&self) -> Result<(), StoreError>

Aborts an in-progress deep reorg and resets the layer cache to a fresh empty state with the same commit threshold. Both the overlay and any partially-built new-chain layers are discarded. On-disk state is untouched (still at the OLD chain’s D), so subsequent FCU evaluations start from a clean foundation.

Source

pub fn ancestors(&self, block_hash: BlockHash) -> AncestorIterator ⓘ

Takes a block hash and returns an iterator to its ancestors. Block headers are returned in reverse order, starting from the given block and going up to the genesis block.

Source

pub fn is_canonical_sync( &self, block_hash: BlockHash, ) -> Result<bool, StoreError>

Checks if a given block belongs to the current canonical chain. Returns false if the block is not known

Source

pub fn generate_flatkeyvalue(&self) -> Result<(), StoreError>

Source

pub fn create_checkpoint( &self, path: impl AsRef<Path>, ) -> Result<(), StoreError>

Source

pub fn get_store_directory(&self) -> Result<PathBuf, StoreError>

Source

pub fn last_written(&self) -> Result<Vec<u8>, StoreError>

Source

pub fn flatkeyvalue_fully_generated(&self) -> Result<bool, StoreError>

Returns true once the flat-key-value generator has finished its full pass.

Completion is recorded by the 1-byte [0xff] sentinel the generator writes to MISC_VALUES["last_written"] on the final iteration (see flatkeyvalue_generator); every non-final frontier value is a real nibble path (bytes 0x00..=0x0f), so the sentinel is unambiguous. Reads the durable marker rather than the in-memory frontier, which is expanded to [0xff; 64]/[0xff; 131] and would need length-aware handling.

Used to gate journal-backed deep reorgs: entries journaled while generation is still in progress omit past-frontier flat-KV pre-images.

Source

pub fn advance_flushed_upto( &self, block_number: BlockNumber, ) -> Result<(), StoreError>

Raises the flushed_upto marker to block_number, on disk and in the buffer’s mirror, so the next start anchors at that height. The marker is a durability floor and only moves forward: a value at or below the current one is a no-op.

Used when startup adopts a head above the recorded one (interrupted full-sync batch): the blocks were flushed by the persist worker before the interruption, but the failed starts in between walked the marker down.

Must run while the persist worker is idle (at startup, before p2p and RPC exist): the buffer update is a read-clone-swap with no compare-and-swap, so a concurrent persist message could lose either mutation.

Source

pub fn read_flushed_upto(&self) -> Result<BlockNumber, StoreError>

Returns the highest block number durably flushed to disk, or 0 when the marker is absent. Use Self::read_flushed_upto_opt when you need to distinguish “absent marker” (legacy DB, everything is durable) from “marker present and equal to 0”.

Trait Implementations§

Source§

impl Clone for Store

Source§

fn clone(&self) -> Store

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Store

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !RefUnwindSafe for Store

§

impl !UnwindSafe for Store

§

impl Freeze for Store

§

impl Send for Store

§

impl Sync for Store

§

impl Unpin for Store

§

impl UnsafeUnpin for Store

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToDebugString for T
where T: Debug,

Source§

fn to_debug_string(&self) -> String

Returns the String produced by Ts Debug implementation.

§Examples
use malachite_base::strings::ToDebugString;

assert_eq!([1, 2, 3].to_debug_string(), "[1, 2, 3]");
assert_eq!(
    [vec![2, 3], vec![], vec![4]].to_debug_string(),
    "[[2, 3], [], [4]]"
);
assert_eq!(Some(5).to_debug_string(), "Some(5)");
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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