diff --git a/crates/cli/commands/src/common.rs b/crates/cli/commands/src/common.rs index f23fe2d5a0..20f478fc08 100644 --- a/crates/cli/commands/src/common.rs +++ b/crates/cli/commands/src/common.rs @@ -146,11 +146,24 @@ impl EnvironmentArgs { }) } }; - let rocksdb_provider = RocksDBProvider::builder(data_dir.rocksdb()) - .with_default_tables() - .with_database_log_level(self.db.log_level) - .with_read_only(!access.is_read_write()) - .build()?; + let rocksdb_provider = if !access.is_read_write() && !RocksDBProvider::exists(&rocksdb_path) + { + // RocksDB database doesn't exist yet (e.g. datadir restored from a snapshot + // or created before RocksDB storage). Create an empty one so read-only + // commands can proceed. + debug!(target: "reth::cli", ?rocksdb_path, "RocksDB not found, initializing empty database"); + reth_fs_util::create_dir_all(&rocksdb_path)?; + RocksDBProvider::builder(data_dir.rocksdb()) + .with_default_tables() + .with_database_log_level(self.db.log_level) + .build()? + } else { + RocksDBProvider::builder(data_dir.rocksdb()) + .with_default_tables() + .with_database_log_level(self.db.log_level) + .with_read_only(!access.is_read_write()) + .build()? + }; let provider_factory = self.create_provider_factory(&config, db, sfp, rocksdb_provider, access, runtime)?; diff --git a/crates/storage/provider/src/providers/rocksdb/provider.rs b/crates/storage/provider/src/providers/rocksdb/provider.rs index 7fa5cf7191..574473e49a 100644 --- a/crates/storage/provider/src/providers/rocksdb/provider.rs +++ b/crates/storage/provider/src/providers/rocksdb/provider.rs @@ -691,6 +691,14 @@ impl RocksDBProvider { RocksDBBuilder::new(path) } + /// Returns `true` if a `RocksDB` database exists at the given path. + /// + /// Checks for the presence of the `CURRENT` file, which `RocksDB` creates + /// when initializing a database. + pub fn exists(path: impl AsRef) -> bool { + path.as_ref().join("CURRENT").exists() + } + /// Returns `true` if this provider is in read-only mode. pub fn is_read_only(&self) -> bool { matches!(self.0.as_ref(), RocksDBProviderInner::ReadOnly { .. }) diff --git a/crates/storage/provider/src/providers/rocksdb_stub.rs b/crates/storage/provider/src/providers/rocksdb_stub.rs index ff84f1b17e..6b36404339 100644 --- a/crates/storage/provider/src/providers/rocksdb_stub.rs +++ b/crates/storage/provider/src/providers/rocksdb_stub.rs @@ -74,6 +74,13 @@ impl RocksDBProvider { RocksDBBuilder::new(path) } + /// Returns `true` if a `RocksDB` database exists at the given path (stub implementation). + /// + /// Always returns `false` since `RocksDB` is not available. + pub fn exists(_path: impl AsRef) -> bool { + false + } + /// Check consistency of `RocksDB` tables (stub implementation). /// /// Returns `None` since there is no `RocksDB` data to check when the feature is disabled.