feat(cli): add --rocksdb.* flags for RocksDB table routing (#21191)

This commit is contained in:
YK
2026-01-20 20:29:05 +01:00
committed by GitHub
parent ff8f434dcd
commit bc79cc44c9
6 changed files with 205 additions and 2 deletions

View File

@@ -10,7 +10,8 @@ use reth_node_builder::NodeBuilder;
use reth_node_core::{ use reth_node_core::{
args::{ args::{
DatabaseArgs, DatadirArgs, DebugArgs, DevArgs, EngineArgs, EraArgs, MetricArgs, DatabaseArgs, DatadirArgs, DebugArgs, DevArgs, EngineArgs, EraArgs, MetricArgs,
NetworkArgs, PayloadBuilderArgs, PruningArgs, RpcServerArgs, StaticFilesArgs, TxPoolArgs, NetworkArgs, PayloadBuilderArgs, PruningArgs, RocksDbArgs, RpcServerArgs, StaticFilesArgs,
TxPoolArgs,
}, },
node_config::NodeConfig, node_config::NodeConfig,
version, version,
@@ -102,6 +103,10 @@ pub struct NodeCommand<C: ChainSpecParser, Ext: clap::Args + fmt::Debug = NoArgs
#[command(flatten)] #[command(flatten)]
pub pruning: PruningArgs, pub pruning: PruningArgs,
/// All `RocksDB` table routing arguments
#[command(flatten)]
pub rocksdb: RocksDbArgs,
/// Engine cli arguments /// Engine cli arguments
#[command(flatten, next_help_heading = "Engine")] #[command(flatten, next_help_heading = "Engine")]
pub engine: EngineArgs, pub engine: EngineArgs,
@@ -166,12 +171,16 @@ where
db, db,
dev, dev,
pruning, pruning,
rocksdb,
engine, engine,
era, era,
static_files, static_files,
ext, ext,
} = self; } = self;
// Validate RocksDB arguments
rocksdb.validate()?;
// set up node config // set up node config
let mut node_config = NodeConfig { let mut node_config = NodeConfig {
datadir, datadir,
@@ -187,6 +196,7 @@ where
db, db,
dev, dev,
pruning, pruning,
rocksdb,
engine, engine,
era, era,
static_files, static_files,

View File

@@ -80,5 +80,9 @@ pub use era::{DefaultEraHost, EraArgs, EraSourceArgs};
mod static_files; mod static_files;
pub use static_files::{StaticFilesArgs, MINIMAL_BLOCKS_PER_FILE}; pub use static_files::{StaticFilesArgs, MINIMAL_BLOCKS_PER_FILE};
/// `RocksDbArgs` for configuring RocksDB table routing.
mod rocksdb;
pub use rocksdb::{RocksDbArgs, RocksDbArgsError};
mod error; mod error;
pub mod types; pub mod types;

View File

@@ -0,0 +1,122 @@
//! clap [Args](clap::Args) for `RocksDB` table routing configuration
use clap::{ArgAction, Args};
/// Parameters for `RocksDB` table routing configuration.
///
/// These flags control which database tables are stored in `RocksDB` instead of MDBX.
/// All flags are genesis-initialization-only: changing them after genesis requires a re-sync.
#[derive(Debug, Args, PartialEq, Eq, Default, Clone, Copy)]
#[command(next_help_heading = "RocksDB")]
pub struct RocksDbArgs {
/// Route all supported tables to `RocksDB` instead of MDBX.
///
/// This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables.
/// Cannot be combined with individual flags set to false.
#[arg(long = "rocksdb.all", action = ArgAction::SetTrue)]
pub all: bool,
/// Route tx hash -> number table to `RocksDB` instead of MDBX.
#[arg(long = "rocksdb.tx-hash", action = ArgAction::Set)]
pub tx_hash: Option<bool>,
/// Route storages history tables to `RocksDB` instead of MDBX.
#[arg(long = "rocksdb.storages-history", action = ArgAction::Set)]
pub storages_history: Option<bool>,
/// Route account history tables to `RocksDB` instead of MDBX.
#[arg(long = "rocksdb.account-history", action = ArgAction::Set)]
pub account_history: Option<bool>,
}
impl RocksDbArgs {
/// Validates the `RocksDB` arguments.
///
/// Returns an error if `--rocksdb.all` is used with any individual flag set to `false`.
pub fn validate(&self) -> Result<(), RocksDbArgsError> {
if self.all {
if self.tx_hash == Some(false) {
return Err(RocksDbArgsError::ConflictingFlags("tx-hash"));
}
if self.storages_history == Some(false) {
return Err(RocksDbArgsError::ConflictingFlags("storages-history"));
}
if self.account_history == Some(false) {
return Err(RocksDbArgsError::ConflictingFlags("account-history"));
}
}
Ok(())
}
}
/// Error type for `RocksDB` argument validation.
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum RocksDbArgsError {
/// `--rocksdb.all` cannot be combined with an individual flag set to false.
#[error("--rocksdb.all cannot be combined with --rocksdb.{0}=false")]
ConflictingFlags(&'static str),
}
#[cfg(test)]
mod tests {
use super::*;
use clap::Parser;
#[derive(Parser)]
struct CommandParser<T: Args> {
#[command(flatten)]
args: T,
}
#[test]
fn test_default_rocksdb_args() {
let args = CommandParser::<RocksDbArgs>::parse_from(["reth"]).args;
assert_eq!(args, RocksDbArgs::default());
}
#[test]
fn test_parse_all_flag() {
let args = CommandParser::<RocksDbArgs>::parse_from(["reth", "--rocksdb.all"]).args;
assert!(args.all);
assert_eq!(args.tx_hash, None);
}
#[test]
fn test_parse_individual_flags() {
let args = CommandParser::<RocksDbArgs>::parse_from([
"reth",
"--rocksdb.tx-hash=true",
"--rocksdb.storages-history=false",
"--rocksdb.account-history=true",
])
.args;
assert!(!args.all);
assert_eq!(args.tx_hash, Some(true));
assert_eq!(args.storages_history, Some(false));
assert_eq!(args.account_history, Some(true));
}
#[test]
fn test_validate_all_alone_ok() {
let args = RocksDbArgs { all: true, ..Default::default() };
assert!(args.validate().is_ok());
}
#[test]
fn test_validate_all_with_true_ok() {
let args = RocksDbArgs { all: true, tx_hash: Some(true), ..Default::default() };
assert!(args.validate().is_ok());
}
#[test]
fn test_validate_all_with_false_errors() {
let args = RocksDbArgs { all: true, tx_hash: Some(false), ..Default::default() };
assert_eq!(args.validate(), Err(RocksDbArgsError::ConflictingFlags("tx-hash")));
let args = RocksDbArgs { all: true, storages_history: Some(false), ..Default::default() };
assert_eq!(args.validate(), Err(RocksDbArgsError::ConflictingFlags("storages-history")));
let args = RocksDbArgs { all: true, account_history: Some(false), ..Default::default() };
assert_eq!(args.validate(), Err(RocksDbArgsError::ConflictingFlags("account-history")));
}
}

View File

@@ -3,7 +3,7 @@
use crate::{ use crate::{
args::{ args::{
DatabaseArgs, DatadirArgs, DebugArgs, DevArgs, EngineArgs, NetworkArgs, PayloadBuilderArgs, DatabaseArgs, DatadirArgs, DebugArgs, DevArgs, EngineArgs, NetworkArgs, PayloadBuilderArgs,
PruningArgs, RpcServerArgs, StaticFilesArgs, TxPoolArgs, PruningArgs, RocksDbArgs, RpcServerArgs, StaticFilesArgs, TxPoolArgs,
}, },
dirs::{ChainPath, DataDirPath}, dirs::{ChainPath, DataDirPath},
utils::get_single_header, utils::get_single_header,
@@ -21,6 +21,7 @@ use reth_primitives_traits::SealedHeader;
use reth_stages_types::StageId; use reth_stages_types::StageId;
use reth_storage_api::{ use reth_storage_api::{
BlockHashReader, DatabaseProviderFactory, HeaderProvider, StageCheckpointReader, BlockHashReader, DatabaseProviderFactory, HeaderProvider, StageCheckpointReader,
StorageSettings,
}; };
use reth_storage_errors::provider::ProviderResult; use reth_storage_errors::provider::ProviderResult;
use reth_transaction_pool::TransactionPool; use reth_transaction_pool::TransactionPool;
@@ -150,6 +151,9 @@ pub struct NodeConfig<ChainSpec> {
/// All static files related arguments /// All static files related arguments
pub static_files: StaticFilesArgs, pub static_files: StaticFilesArgs,
/// All `RocksDB` table routing arguments
pub rocksdb: RocksDbArgs,
} }
impl NodeConfig<ChainSpec> { impl NodeConfig<ChainSpec> {
@@ -181,6 +185,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
engine: EngineArgs::default(), engine: EngineArgs::default(),
era: EraArgs::default(), era: EraArgs::default(),
static_files: StaticFilesArgs::default(), static_files: StaticFilesArgs::default(),
rocksdb: RocksDbArgs::default(),
} }
} }
@@ -255,6 +260,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
engine, engine,
era, era,
static_files, static_files,
rocksdb,
.. ..
} = self; } = self;
NodeConfig { NodeConfig {
@@ -274,6 +280,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
engine, engine,
era, era,
static_files, static_files,
rocksdb,
} }
} }
@@ -350,6 +357,22 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
self.pruning.prune_config(&self.chain) self.pruning.prune_config(&self.chain)
} }
/// Returns the effective storage settings derived from static-file and `RocksDB` CLI args.
pub fn storage_settings(&self) -> StorageSettings {
let tx_hash = self.rocksdb.all || self.rocksdb.tx_hash.unwrap_or(false);
let storages_history = self.rocksdb.all || self.rocksdb.storages_history.unwrap_or(false);
let account_history = self.rocksdb.all || self.rocksdb.account_history.unwrap_or(false);
StorageSettings {
receipts_in_static_files: self.static_files.receipts,
transaction_senders_in_static_files: self.static_files.transaction_senders,
account_changesets_in_static_files: self.static_files.account_changesets,
transaction_hash_numbers_in_rocksdb: tx_hash,
storages_history_in_rocksdb: storages_history,
account_history_in_rocksdb: account_history,
}
}
/// Returns the max block that the node should run to, looking it up from the network if /// Returns the max block that the node should run to, looking it up from the network if
/// necessary /// necessary
pub async fn max_block<Provider, Client>( pub async fn max_block<Provider, Client>(
@@ -544,6 +567,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
engine: self.engine, engine: self.engine,
era: self.era, era: self.era,
static_files: self.static_files, static_files: self.static_files,
rocksdb: self.rocksdb,
} }
} }
@@ -585,6 +609,7 @@ impl<ChainSpec> Clone for NodeConfig<ChainSpec> {
engine: self.engine.clone(), engine: self.engine.clone(),
era: self.era.clone(), era: self.era.clone(),
static_files: self.static_files, static_files: self.static_files,
rocksdb: self.rocksdb,
} }
} }
} }

View File

@@ -897,6 +897,27 @@ Pruning:
--prune.bodies.before <BLOCK_NUMBER> --prune.bodies.before <BLOCK_NUMBER>
Prune storage history before the specified block number. The specified block number is not pruned Prune storage history before the specified block number. The specified block number is not pruned
RocksDB:
--rocksdb.all
Route all supported tables to `RocksDB` instead of MDBX.
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
--rocksdb.tx-hash <TX_HASH>
Route tx hash -> number table to `RocksDB` instead of MDBX
[possible values: true, false]
--rocksdb.storages-history <STORAGES_HISTORY>
Route storages history tables to `RocksDB` instead of MDBX
[possible values: true, false]
--rocksdb.account-history <ACCOUNT_HISTORY>
Route account history tables to `RocksDB` instead of MDBX
[possible values: true, false]
Engine: Engine:
--engine.persistence-threshold <PERSISTENCE_THRESHOLD> --engine.persistence-threshold <PERSISTENCE_THRESHOLD>
Configure persistence threshold for the engine. This determines how many canonical blocks must be in-memory, ahead of the last persisted block, before flushing canonical blocks to disk again. Configure persistence threshold for the engine. This determines how many canonical blocks must be in-memory, ahead of the last persisted block, before flushing canonical blocks to disk again.

View File

@@ -897,6 +897,27 @@ Pruning:
--prune.bodies.before <BLOCK_NUMBER> --prune.bodies.before <BLOCK_NUMBER>
Prune storage history before the specified block number. The specified block number is not pruned Prune storage history before the specified block number. The specified block number is not pruned
RocksDB:
--rocksdb.all
Route all supported tables to `RocksDB` instead of MDBX.
This enables `RocksDB` for `tx-hash`, `storages-history`, and `account-history` tables. Cannot be combined with individual flags set to false.
--rocksdb.tx-hash <TX_HASH>
Route tx hash -> number table to `RocksDB` instead of MDBX
[possible values: true, false]
--rocksdb.storages-history <STORAGES_HISTORY>
Route storages history tables to `RocksDB` instead of MDBX
[possible values: true, false]
--rocksdb.account-history <ACCOUNT_HISTORY>
Route account history tables to `RocksDB` instead of MDBX
[possible values: true, false]
Engine: Engine:
--engine.persistence-threshold <PERSISTENCE_THRESHOLD> --engine.persistence-threshold <PERSISTENCE_THRESHOLD>
Configure persistence threshold for the engine. This determines how many canonical blocks must be in-memory, ahead of the last persisted block, before flushing canonical blocks to disk again. Configure persistence threshold for the engine. This determines how many canonical blocks must be in-memory, ahead of the last persisted block, before flushing canonical blocks to disk again.