Skip to content

Conversation

@MegaRedHand
Copy link
Collaborator

@MegaRedHand MegaRedHand commented Dec 10, 2025

Motivation

We're currently opening the Store backend before checking the DB schema version matches. This can lead to data loss in case the RocksDB schema is changed.

Description

This PR changes the metadata to be stored in JSON format in a backend-agnostic way. This allows for inspecting the DB version without starting ethrex. Example:

$ cat "~/.local/share/ethrex/metadata.json"
{
  "schema_version": 1
}

It also allows for more easily extending the check with more validations, for example, for backend type.

Additionally, it also fails with a clear error when trying to run a new ethrex version on an old DB without this versioning scheme:

2025-12-11T14:33:47.045029Z  INFO Opening storage engine engine=RocksDB path="/Users/mega/Library/Application Support/ethrex"
Error: Incompatible DB Version: found 0, expected 1. Please run `ethrex removedb` and restart node

Location:
    /Users/mega/execution/ethrex/cmd/ethrex/initializers.rs:400:24

Closes #5541

Copilot AI review requested due to automatic review settings December 10, 2025 19:34
@MegaRedHand MegaRedHand requested a review from a team as a code owner December 10, 2025 19:34
@github-actions github-actions bot added the L1 Ethereum client label Dec 10, 2025
@MegaRedHand MegaRedHand moved this to In Review in ethrex_l1 Dec 10, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the schema version validation mechanism to use a backend-agnostic JSON metadata file instead of storing the version inside the database. This change allows checking the schema version before opening the database, preventing potential data loss from incompatible schema versions.

Key changes:

  • Schema version is now stored in a metadata.json file in the store directory
  • Validation occurs before opening any database backend
  • Error messages now include both found and expected schema versions for clarity

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
crates/storage/store.rs Added JSON-based metadata validation function and StoreMetadata struct; moved validation before store initialization
crates/storage/error.rs Enhanced error type with structured fields showing both found and expected versions; added I/O and JSON serialization error variants
crates/storage/api.rs Removed set_store_schema_version and get_store_schema_version methods from StoreEngine trait
crates/storage/store_db/rocksdb.rs Removed RocksDB-specific schema version implementation and unused write_sync helper method
crates/storage/store_db/in_memory.rs Removed no-op schema version methods that were irrelevant for in-memory storage
cmd/ethrex/initializers.rs Updated error handling to use new structured IncompatibleDBVersion error format

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link

github-actions bot commented Dec 10, 2025

Lines of code report

Total lines added: 44
Total lines removed: 37
Total lines changed: 81

Detailed view
+---------------------------------------------+-------+------+
| File                                        | Lines | Diff |
+---------------------------------------------+-------+------+
| ethrex/cmd/ethrex/initializers.rs           | 456   | +1   |
+---------------------------------------------+-------+------+
| ethrex/crates/storage/api.rs                | 247   | -2   |
+---------------------------------------------+-------+------+
| ethrex/crates/storage/error.rs              | 49    | +6   |
+---------------------------------------------+-------+------+
| ethrex/crates/storage/lib.rs                | 16    | +1   |
+---------------------------------------------+-------+------+
| ethrex/crates/storage/store.rs              | 1545  | +36  |
+---------------------------------------------+-------+------+
| ethrex/crates/storage/store_db/in_memory.rs | 622   | -6   |
+---------------------------------------------+-------+------+
| ethrex/crates/storage/store_db/rocksdb.rs   | 1736  | -29  |
+---------------------------------------------+-------+------+

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +399 to +400
Err(err @ StoreError::IncompatibleDBVersion { .. })
| Err(err @ StoreError::NotFoundDBVersion { .. }) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We start at 1 so we can treat 0 and missing as equivalent, so I don't think the new error kind is necessary.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes the distinction clear and also simplifies the formatting of the error here.

pub const STORE_SCHEMA_VERSION: u64 = 1;

/// Name of the file storing the metadata about the database
pub const STORE_METADATA_FILENAME: &str = "metadata.json";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the place for the schema versioning is the DB. Decoupling it is asking for trouble. E.g., I don't see the removedb command deleting this properly.
If we don't want it to be data, we may follow a scheme similar to what Postgres does, which is encoding versioning in file names (e.g., the internal directory might be data-{schema_version}, with failure indicating incompatibility).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removedb removes the whole datadir, including the metadata file, so there should be no problem there.

The main reason to move the schema versioning to another file is to make it backend-agnostic. Keeping it inside the DB means we need to open a Store before checking if we support its version. Right now, this means we may have some data loss due to unknown columns being dropped by RocksDB. This can be solved, but it would require the backend itself to check the version.

It also has the benefit that we can include more information, like the engine type we're using, and we can easily inspect it because we use plaintext. Having it in filenames is a good alternative, but I don't see the benefits in moving to that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

L1 Ethereum client

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

Check datadir schema matches before initializing Store

5 participants