mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-02-19 03:04:27 -05:00
feat(cli): add --rocksdb.* flags for RocksDB table routing (#21191)
This commit is contained in:
@@ -10,7 +10,8 @@ use reth_node_builder::NodeBuilder;
|
||||
use reth_node_core::{
|
||||
args::{
|
||||
DatabaseArgs, DatadirArgs, DebugArgs, DevArgs, EngineArgs, EraArgs, MetricArgs,
|
||||
NetworkArgs, PayloadBuilderArgs, PruningArgs, RpcServerArgs, StaticFilesArgs, TxPoolArgs,
|
||||
NetworkArgs, PayloadBuilderArgs, PruningArgs, RocksDbArgs, RpcServerArgs, StaticFilesArgs,
|
||||
TxPoolArgs,
|
||||
},
|
||||
node_config::NodeConfig,
|
||||
version,
|
||||
@@ -102,6 +103,10 @@ pub struct NodeCommand<C: ChainSpecParser, Ext: clap::Args + fmt::Debug = NoArgs
|
||||
#[command(flatten)]
|
||||
pub pruning: PruningArgs,
|
||||
|
||||
/// All `RocksDB` table routing arguments
|
||||
#[command(flatten)]
|
||||
pub rocksdb: RocksDbArgs,
|
||||
|
||||
/// Engine cli arguments
|
||||
#[command(flatten, next_help_heading = "Engine")]
|
||||
pub engine: EngineArgs,
|
||||
@@ -166,12 +171,16 @@ where
|
||||
db,
|
||||
dev,
|
||||
pruning,
|
||||
rocksdb,
|
||||
engine,
|
||||
era,
|
||||
static_files,
|
||||
ext,
|
||||
} = self;
|
||||
|
||||
// Validate RocksDB arguments
|
||||
rocksdb.validate()?;
|
||||
|
||||
// set up node config
|
||||
let mut node_config = NodeConfig {
|
||||
datadir,
|
||||
@@ -187,6 +196,7 @@ where
|
||||
db,
|
||||
dev,
|
||||
pruning,
|
||||
rocksdb,
|
||||
engine,
|
||||
era,
|
||||
static_files,
|
||||
|
||||
@@ -80,5 +80,9 @@ pub use era::{DefaultEraHost, EraArgs, EraSourceArgs};
|
||||
mod static_files;
|
||||
pub use static_files::{StaticFilesArgs, MINIMAL_BLOCKS_PER_FILE};
|
||||
|
||||
/// `RocksDbArgs` for configuring RocksDB table routing.
|
||||
mod rocksdb;
|
||||
pub use rocksdb::{RocksDbArgs, RocksDbArgsError};
|
||||
|
||||
mod error;
|
||||
pub mod types;
|
||||
|
||||
122
crates/node/core/src/args/rocksdb.rs
Normal file
122
crates/node/core/src/args/rocksdb.rs
Normal 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")));
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
use crate::{
|
||||
args::{
|
||||
DatabaseArgs, DatadirArgs, DebugArgs, DevArgs, EngineArgs, NetworkArgs, PayloadBuilderArgs,
|
||||
PruningArgs, RpcServerArgs, StaticFilesArgs, TxPoolArgs,
|
||||
PruningArgs, RocksDbArgs, RpcServerArgs, StaticFilesArgs, TxPoolArgs,
|
||||
},
|
||||
dirs::{ChainPath, DataDirPath},
|
||||
utils::get_single_header,
|
||||
@@ -21,6 +21,7 @@ use reth_primitives_traits::SealedHeader;
|
||||
use reth_stages_types::StageId;
|
||||
use reth_storage_api::{
|
||||
BlockHashReader, DatabaseProviderFactory, HeaderProvider, StageCheckpointReader,
|
||||
StorageSettings,
|
||||
};
|
||||
use reth_storage_errors::provider::ProviderResult;
|
||||
use reth_transaction_pool::TransactionPool;
|
||||
@@ -150,6 +151,9 @@ pub struct NodeConfig<ChainSpec> {
|
||||
|
||||
/// All static files related arguments
|
||||
pub static_files: StaticFilesArgs,
|
||||
|
||||
/// All `RocksDB` table routing arguments
|
||||
pub rocksdb: RocksDbArgs,
|
||||
}
|
||||
|
||||
impl NodeConfig<ChainSpec> {
|
||||
@@ -181,6 +185,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
|
||||
engine: EngineArgs::default(),
|
||||
era: EraArgs::default(),
|
||||
static_files: StaticFilesArgs::default(),
|
||||
rocksdb: RocksDbArgs::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,6 +260,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
|
||||
engine,
|
||||
era,
|
||||
static_files,
|
||||
rocksdb,
|
||||
..
|
||||
} = self;
|
||||
NodeConfig {
|
||||
@@ -274,6 +280,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
|
||||
engine,
|
||||
era,
|
||||
static_files,
|
||||
rocksdb,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,6 +357,22 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
|
||||
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
|
||||
/// necessary
|
||||
pub async fn max_block<Provider, Client>(
|
||||
@@ -544,6 +567,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
|
||||
engine: self.engine,
|
||||
era: self.era,
|
||||
static_files: self.static_files,
|
||||
rocksdb: self.rocksdb,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,6 +609,7 @@ impl<ChainSpec> Clone for NodeConfig<ChainSpec> {
|
||||
engine: self.engine.clone(),
|
||||
era: self.era.clone(),
|
||||
static_files: self.static_files,
|
||||
rocksdb: self.rocksdb,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,6 +897,27 @@ Pruning:
|
||||
--prune.bodies.before <BLOCK_NUMBER>
|
||||
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.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.
|
||||
|
||||
@@ -897,6 +897,27 @@ Pruning:
|
||||
--prune.bodies.before <BLOCK_NUMBER>
|
||||
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.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.
|
||||
|
||||
Reference in New Issue
Block a user