Skip to content

Conversation

damiramirez
Copy link
Contributor

@damiramirez damiramirez commented Sep 23, 2025

Warning

This is a large refactor in progress. The API and implementation are subject to change

Motivation

Our current StoreEngine interface has grown into a God Object with over 50 methods, making it difficult to add new database backends. Business logic is scattered across every database implementation, leading to code duplication and maintenance overhead.

This PR addresses these issues by introducing a minimal, focused interface that makes adding new databases to ethrex trivial.

Also removes libmdbx from ethrex

Description

This PR implements a fundamental redesign of the storage layer using a three-tier architecture: Storage → Storage Engine → Storage Backend → Database Implementation

  • Store
    • Implements Store wrapping StoreEngine
    • High-level blockchain operations
  • StorageEngine
    • Handles complex operations
    • Manages data serialization/deserialization using RLP encoding
  • StorageBackend
    • Defines the contract for database operations with transactions
    • Supports basic DB operations

New storage structure

crates/storage
├── api.rs
├── backend
│   ├── in_memory.rs
│   ├── mod.rs
│   └── rocksdb.rs
├── Cargo.toml
├── clippy.toml
├── engine.rs
├── error.rs
├── lib.rs
├── rlp.rs
├── store.rs
├── trie.rs
└── utils.rs

The new StorageBackend trait provides a thin abstraction over database operations:

// This can be used when we have a database that supports dupsort tables or other options
// This struct exists but I'm not using it for now
#[derive(Debug, Clone)]
pub struct TableOptions {
    pub dupsort: bool,
}

pub trait StorageBackend: Debug + Send + Sync {
    fn open(path: impl AsRef<Path>) -> Result<Self, StoreError>
    // Check if needed
    fn create_table(&self, name: &str, options: TableOptions) -> Result<(), StoreError>;
    fn clear_table(&self, table: &str) -> Result<(), StoreError>;
    fn begin_read(&self) -> Result<Box<dyn StorageRoTx + '_>, StoreError>;
    fn begin_write(&self) -> Result<Box<dyn StorageRwTx + '_>, StoreError>;
    fn begin_locked(&self, table_name: &str) -> Result<Box<dyn StorageLocked>, StoreError>;
}

pub trait StorageRoTx {
    fn get(&self, table: &str, key: &[u8]) -> Result<Option<Vec<u8>>, StoreError>;
    fn prefix_iterator(
        &self,
        table: &str,
        prefix: &[u8],
    ) -> Result<Box<dyn Iterator<Item = PrefixResult> + '_>, StoreError>;
}

pub trait StorageRwTx: StorageRoTx {
    fn put(&self, table: &str, key: &[u8], value: &[u8]) -> Result<(), StoreError>;
    fn put_batch(&self, batch: Vec<(&str, Vec<u8>, Vec<u8>)>) -> Result<(), StoreError>;
    fn delete(&self, table: &str, key: &[u8]) -> Result<(), StoreError>;
    fn commit(self: Box<Self>) -> Result<(), StoreError>;
}

pub trait StorageLocked: Send + Sync + 'static {
    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, StoreError>;
}

TODO

  • Review API methods
  • Review all TODO and FIXME comments in the code
  • Re-enable tests related to TX EIP-1559
  • Restore previously deleted tests
  • Check features flags
  • Add documentation
  • Benchmark performance (ethrex_benchmarks, syncing, etc)

Closes #issue_number

Copy link

github-actions bot commented Sep 23, 2025

Lines of code report

Total lines added: 1437
Total lines removed: 327
Total lines changed: 1764

Detailed view
+-------------------------------------------------------+-------+------+
| File                                                  | Lines | Diff |
+-------------------------------------------------------+-------+------+
| ethrex/cmd/ethrex/initializers.rs                     | 387   | -2   |
+-------------------------------------------------------+-------+------+
| ethrex/cmd/ethrex/l2/command.rs                       | 653   | -7   |
+-------------------------------------------------------+-------+------+
| ethrex/cmd/ethrex_replay/src/cli.rs                   | 921   | +6   |
+-------------------------------------------------------+-------+------+
| ethrex/crates/blockchain/smoke_test.rs                | 242   | +2   |
+-------------------------------------------------------+-------+------+
| ethrex/crates/common/trie/node_hash.rs                | 109   | -15  |
+-------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/eth/gas_price.rs         | 93    | -21  |
+-------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/eth/gas_tip_estimator.rs | 111   | -21  |
+-------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/eth/max_priority_fee.rs  | 63    | -36  |
+-------------------------------------------------------+-------+------+
| ethrex/crates/networking/rpc/eth/mod.rs               | 174   | -9   |
+-------------------------------------------------------+-------+------+
| ethrex/crates/storage/api.rs                          | 51    | -182 |
+-------------------------------------------------------+-------+------+
| ethrex/crates/storage/backend/in_memory.rs            | 182   | +182 |
+-------------------------------------------------------+-------+------+
| ethrex/crates/storage/backend/mod.rs                  | 3     | +3   |
+-------------------------------------------------------+-------+------+
| ethrex/crates/storage/backend/rocksdb.rs              | 237   | +237 |
+-------------------------------------------------------+-------+------+
| ethrex/crates/storage/engine.rs                       | 910   | +910 |
+-------------------------------------------------------+-------+------+
| ethrex/crates/storage/error.rs                        | 37    | -3   |
+-------------------------------------------------------+-------+------+
| ethrex/crates/storage/rlp.rs                          | 38    | -15  |
+-------------------------------------------------------+-------+------+
| ethrex/crates/storage/store.rs                        | 1508  | -16  |
+-------------------------------------------------------+-------+------+
| ethrex/crates/storage/trie.rs                         | 97    | +97  |
+-------------------------------------------------------+-------+------+

Copy link

Benchmark for ac20fdb

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 35.0±0.36ms 34.8±0.24ms -0.57%
Trie/cita-trie insert 1k 3.6±0.03ms 3.5±0.01ms -2.78%
Trie/ethrex-trie insert 10k 55.3±1.19ms 54.7±0.34ms -1.08%
Trie/ethrex-trie insert 1k 6.1±0.01ms 6.1±0.04ms 0.00%

Copy link

Benchmark for 515d02c

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 34.7±2.87ms 40.7±3.12ms +17.29%
Trie/cita-trie insert 1k 3.6±0.03ms 3.6±0.02ms 0.00%
Trie/ethrex-trie insert 10k 61.4±1.55ms 57.3±1.73ms -6.68%
Trie/ethrex-trie insert 1k 6.2±0.03ms 6.2±0.21ms 0.00%

Copy link

Benchmark for 3a6e5f0

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 37.8±2.02ms 36.5±2.26ms -3.44%
Trie/cita-trie insert 1k 3.7±0.27ms 3.5±0.02ms -5.41%
Trie/ethrex-trie insert 10k 60.5±1.67ms 57.6±1.48ms -4.79%
Trie/ethrex-trie insert 1k 6.2±0.03ms 6.1±0.05ms -1.61%

Copy link

Benchmark for ff142bd

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 35.6±0.93ms 36.5±1.60ms +2.53%
Trie/cita-trie insert 1k 3.6±0.03ms 3.7±0.20ms +2.78%
Trie/ethrex-trie insert 10k 56.5±0.78ms 55.4±1.22ms -1.95%
Trie/ethrex-trie insert 1k 6.1±0.09ms 6.1±0.14ms 0.00%

Copy link

Benchmark for f30cbe6

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 39.4±1.53ms 37.6±2.02ms -4.57%
Trie/cita-trie insert 1k 3.6±0.02ms 3.7±0.20ms +2.78%
Trie/ethrex-trie insert 10k 57.2±1.26ms 55.5±0.90ms -2.97%
Trie/ethrex-trie insert 1k 6.1±0.02ms 6.2±0.02ms +1.64%

Copy link

Benchmark for 1764e7d

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 31.7±2.99ms 31.2±2.33ms -1.58%
Trie/cita-trie insert 1k 2.7±0.01ms 2.8±0.06ms +3.70%
Trie/ethrex-trie insert 10k 56.3±1.77ms 55.2±1.13ms -1.95%
Trie/ethrex-trie insert 1k 5.7±0.08ms 5.7±0.03ms 0.00%

Copy link

Benchmark for 877b67f

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 34.6±2.54ms 36.2±1.97ms +4.62%
Trie/cita-trie insert 1k 3.6±0.03ms 3.7±0.31ms +2.78%
Trie/ethrex-trie insert 10k 57.1±1.72ms 55.9±1.74ms -2.10%
Trie/ethrex-trie insert 1k 6.2±0.19ms 6.3±0.35ms +1.61%

Copy link

Benchmark for a1e0f04

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 35.9±0.63ms 35.7±0.69ms -0.56%
Trie/cita-trie insert 1k 3.6±0.01ms 3.7±0.16ms +2.78%
Trie/ethrex-trie insert 10k 55.7±0.50ms 55.5±0.67ms -0.36%
Trie/ethrex-trie insert 1k 6.3±0.02ms 6.2±0.05ms -1.59%

Copy link

Benchmark for 3181d80

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 36.8±1.44ms 36.3±1.17ms -1.36%
Trie/cita-trie insert 1k 3.5±0.02ms 3.6±0.02ms +2.86%
Trie/ethrex-trie insert 10k 55.6±0.57ms 55.7±0.59ms +0.18%
Trie/ethrex-trie insert 1k 6.1±0.01ms 6.2±0.32ms +1.64%

Copy link

Benchmark for 2d4ad73

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 30.1±1.88ms 30.3±1.63ms +0.66%
Trie/cita-trie insert 1k 2.8±0.02ms 2.8±0.02ms 0.00%
Trie/ethrex-trie insert 10k 60.0±1.50ms 62.4±3.38ms +4.00%
Trie/ethrex-trie insert 1k 5.8±0.02ms 5.8±0.19ms 0.00%

Copy link

Benchmark for d5ab0b2

Click to view benchmark
Test Base PR %
Trie/cita-trie insert 10k 38.0±1.92ms 32.7±1.26ms -13.95%
Trie/cita-trie insert 1k 3.6±0.03ms 3.7±0.03ms +2.78%
Trie/ethrex-trie insert 10k 57.8±0.92ms 58.1±0.84ms +0.52%
Trie/ethrex-trie insert 1k 6.2±0.02ms 6.3±0.23ms +1.61%

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant