This document describes the RocksDB wrapper implementation in fuel-core, which provides the persistent key-value storage backend. The RocksDb<Description> wrapper manages column families, caching, batch writes, and snapshots for efficient blockchain data storage. For the higher-level historical state management built on top of this wrapper, see Historical State Management. For details on the transactional layer, see Transactional Storage.
Sources: crates/fuel-core/src/state/rocks_db.rs1-1096
The RocksDb<Description> struct wraps the underlying DBWithThreadMode<MultiThreaded> instance from the rocksdb crate, providing a type-safe interface parameterized by a DatabaseDescription. This allows different database domains (OnChain, OffChain, Relayer, etc.) to use the same wrapper with domain-specific column families.
Key Components:
| Component | Type | Purpose |
|---|---|---|
db | Arc<PrimaryInstance> | Thread-safe reference to RocksDB instance |
block_opts | Arc<BlockBasedOptions> | Shared block cache configuration |
read_options | ReadOptions | Per-instance read settings (snapshots) |
create_family | Option<Arc<Mutex<BTreeMap>>> | Lazy column family creation state |
snapshot | Option<SnapshotWithThreadMode> | Optional point-in-time snapshot |
metrics | Arc<DatabaseMetrics> | Read/write operation metrics |
Sources: crates/fuel-core/src/state/rocks_db.rs154-164 crates/fuel-core/src/state/rocks_db.rs76-93
The DatabaseConfig structure controls RocksDB behavior through three key parameters:
Configuration Parameters:
| Parameter | Default (test) | Default (production) | Purpose |
|---|---|---|---|
cache_capacity | None | Configured | Total cache memory budget |
max_fds | 512 | System limit / 2 | Max file descriptors |
columns_policy | Lazy | OnCreation | Column family opening strategy |
ColumnsPolicy:
Lazy: Column families are created on-demand during first access. Used in testing and development to avoid upfront initialization cost.OnCreation: All column families are opened when the database is created. Provides better production performance by avoiding dynamic column creation.Sources: crates/fuel-core/src/state/rocks_db.rs124-152
The wrapper supports three opening modes, each suited for different use cases:
Opening Configuration:
The open() method configures RocksDB with optimized settings:
| Setting | Value | Purpose |
|---|---|---|
| Compression | Lz4 | Fast compression for all column families |
| Max WAL size | 64 MB | Write-ahead log size limit |
| Parallelism | max(1, cpu_count / 2) | Background compaction threads |
| Max background jobs | 6 | Concurrent compaction tasks |
| Bytes per sync | 1 MB | Periodic fsync threshold |
Sources: crates/fuel-core/src/state/rocks_db.rs235-436 crates/fuel-core/src/state/rocks_db.rs334-352
RocksDB stores data in column families, which are isolated keyspaces within the database. Each DatabaseDescription defines its own set of columns.
Column Family Access:
The cf() method resolves column families by ID, with lazy creation support:
cf_handle()create_family is Some:
create_cf() to create the column familyDouble-Key Tables:
Some tables use composite keys (e.g., contract state keyed by contract_id + state_key). For these tables, a SliceTransform prefix extractor is configured to enable efficient prefix scans:
Sources: crates/fuel-core/src/state/rocks_db.rs490-548 crates/fuel-core/src/state/rocks_db.rs358-421
The RocksDB wrapper implements a two-tier caching strategy to minimize disk I/O:
Cache Configuration Details:
| Cache Component | Size | Purpose |
|---|---|---|
| Block Cache | capacity / 3 | Caches compressed SST blocks |
| Row Cache | capacity / 3 | Caches uncompressed rows |
| Index/Filter Blocks | In block cache | Reduces random read overhead |
| L0 Filter Pinning | Always pinned | Prevents eviction of L0 index/filter blocks |
Bloom Filter:
A bloom filter with 10 bits per key is configured for all column families, reducing unnecessary disk reads for non-existent keys by approximately 99.9%.
Sources: crates/fuel-core/src/state/rocks_db.rs313-350
The RocksDB wrapper implements batched writes to minimize write amplification and ensure atomic commits across multiple keys and column families.
Batch Write Process:
WriteBatch and conflict detection setInsert or Remove operation to batchdb.write() calldatabase_commit_time metricConflict Detection:
The HashSet<(&u32, &ReferenceBytesKey)> ensures that a single batch doesn't contain conflicting operations for the same key, which would indicate a logic error in the caller:
Sources: crates/fuel-core/src/state/rocks_db.rs1034-1094
The wrapper provides efficient read operations with metrics tracking:
Single Key Operations:
| Method | Purpose | Metrics |
|---|---|---|
get() | Retrieve full value | read_meter, bytes_read, per-column metrics |
size_of_value() | Get value size without reading | read_meter, per-column metrics |
read() | Read subset of value bytes | read_meter, bytes_read |
exists() | Check key existence | Via size_of_value() |
Batch Operations:
The multi_get() method retrieves multiple values in a single RocksDB call, reducing syscall overhead:
This method:
db.multi_get_cf_opt() with all keysSources: crates/fuel-core/src/state/rocks_db.rs924-1002 crates/fuel-core/src/state/rocks_db.rs649-676
The wrapper provides flexible iteration over keys and key-value pairs with support for prefixes, start positions, and directions:
Prefix Iteration Modes:
| Configuration | Behavior |
|---|---|
| No prefix, no start | Full scan in specified direction |
| Prefix only (forward) | Iterator from prefix with prefix_same_as_start |
| Prefix only (reverse) | Calculate next prefix, iterate backward |
| Start only | Iterator from start with total_order_seek |
| Prefix + start | Validate start has prefix, iterate within prefix |
Reverse Prefix Iteration:
RocksDB doesn't natively support reverse prefix iteration. The wrapper works around this by:
Sources: crates/fuel-core/src/state/rocks_db.rs554-763 crates/fuel-core/src/state/rocks_db.rs1098-1106
The wrapper supports creating immutable point-in-time snapshots for consistent reads without blocking writes:
Snapshot Characteristics:
| Property | Description |
|---|---|
| Isolation | Read-only view at snapshot creation time |
| Sharing | Shares underlying db and block_opts via Arc |
| Lifetime | Transmuted to 'static but guaranteed valid |
| Overhead | Minimal - only snapshot metadata allocated |
Safety Invariant:
The snapshot is transmuted to 'static lifetime, but safety is ensured by:
RocksDb structDrop to drop snapshot before dbdb: Arc reference (snapshot lifetime < db lifetime)Sources: crates/fuel-core/src/state/rocks_db.rs453-488 crates/fuel-core/src/state/rocks_db.rs166-172
The wrapper provides backup and restore functionality for operational safety (available under backup feature):
Backup Configuration:
| Setting | Value | Purpose |
|---|---|---|
| Max background operations | max(1, cpu_count / 4) | Parallel backup operations |
| Backup directory | Per-description subdirectory | Isolates database backups |
| Database mode | Read-only | Prevents WAL interference |
| Max FDs | -1 (unlimited) | Avoids FD exhaustion during backup |
Usage Pattern:
Sources: crates/fuel-core/src/state/rocks_db.rs765-869 crates/fuel-core/src/combined_database.rs104-212
The wrapper tracks detailed metrics for monitoring database performance:
Metric Collection Points:
| Operation | Metrics Updated |
|---|---|
get(), read() | read_meter, bytes_read, per-column read counter |
multi_get() | read_meter (per key), bytes_read, per-column read counter |
iterator() | read_meter (per item), bytes_read, per-column read counter |
commit_changes() | write_meter (per operation), bytes_written, database_commit_time |
Metrics are stored in an Arc<DatabaseMetrics> shared across snapshots, ensuring consistent tracking even when using snapshot views.
Sources: crates/fuel-core/src/state/rocks_db.rs309-312 crates/fuel-core/src/state/rocks_db.rs946-1001 crates/fuel-core/src/state/rocks_db.rs1053-1091
The RocksDb wrapper implements the KeyValueInspect and IterableStore traits, enabling seamless integration with higher storage layers:
Implementation Details:
The wrapper implements KeyValueInspect::get() by delegating to RocksDB's get_cf_opt():
The IterableStore implementation provides iter_store() and iter_store_keys() by delegating to the internal _iter_store() method with KeyAndValue or KeyOnly type parameters.
Sources: crates/fuel-core/src/state/rocks_db.rs924-1028 crates/fuel-core/src/state/rocks_db.rs876-922 crates/fuel-core/src/state/historical_rocksdb.rs499-558
Refresh this wiki