Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions crates/cli/commands/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use reth_node_core::{
dirs::{ChainPath, DataDirPath},
};
use reth_provider::{
providers::{BlockchainProvider, NodeTypesForProvider, StaticFileProvider},
providers::{BlockchainProvider, NodeTypesForProvider, RocksDBProvider, StaticFileProvider},
ProviderFactory, StaticFileProviderFactory,
};
use reth_stages::{sets::DefaultStages, Pipeline, PipelineTarget};
Expand Down Expand Up @@ -75,10 +75,12 @@ impl<C: ChainSpecParser> EnvironmentArgs<C> {
let data_dir = self.datadir.clone().resolve_datadir(self.chain.chain());
let db_path = data_dir.db();
let sf_path = data_dir.static_files();
let rocksdb_path = data_dir.rocksdb();

if access.is_read_write() {
reth_fs_util::create_dir_all(&db_path)?;
reth_fs_util::create_dir_all(&sf_path)?;
reth_fs_util::create_dir_all(&rocksdb_path)?;
}

let config_path = self.config.clone().unwrap_or_else(|| data_dir.config());
Expand Down Expand Up @@ -108,8 +110,13 @@ impl<C: ChainSpecParser> EnvironmentArgs<C> {
StaticFileProvider::read_only(sf_path, false)?,
),
};
// TransactionDB only support read-write mode
let rocksdb_provider = RocksDBProvider::builder(data_dir.rocksdb())
Copy link
Copy Markdown
Contributor Author

@duyquang6 duyquang6 Dec 15, 2025

Choose a reason for hiding this comment

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

context: there is AccessRights::RW and AccessRights::RO, in case of rocksdb, there is only support read write mode, so, in AccessRights::RO, behind rocksdb will use read write mode

I'm not sure if this is what we want sir @fgimenez, as #20288 (review) suggest should remove readonly mode, so this code here adapt to it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

yes, this approach is correct, TransactionDB does not support RO and we always create RocksDB in RW no matter the value of AccessRights. AccessRights enum controls MDBX and StaticFiles access, not RocksDB.

One remaining thing, we can now remove the unused ReadOnlyRocsDBAccess error variant from crates/storage/errors/src/provider.rs, not used anywhere

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

thanks, I fixed that 💯

.with_database_log_level(self.db.log_level)
.build()?;

let provider_factory = self.create_provider_factory(&config, db, sfp, access)?;
let provider_factory =
self.create_provider_factory(&config, db, sfp, rocksdb_provider, access)?;
if access.is_read_write() {
debug!(target: "reth::cli", chain=%self.chain.chain(), genesis=?self.chain.genesis_hash(), "Initializing genesis");
init_genesis_with_settings(&provider_factory, self.static_files.to_settings())?;
Expand All @@ -128,6 +135,7 @@ impl<C: ChainSpecParser> EnvironmentArgs<C> {
config: &Config,
db: Arc<DatabaseEnv>,
static_file_provider: StaticFileProvider<N::Primitives>,
rocksdb_provider: RocksDBProvider,
access: AccessRights,
) -> eyre::Result<ProviderFactory<NodeTypesWithDBAdapter<N, Arc<DatabaseEnv>>>>
where
Expand All @@ -138,6 +146,7 @@ impl<C: ChainSpecParser> EnvironmentArgs<C> {
db,
self.chain.clone(),
static_file_provider,
rocksdb_provider,
)?
.with_prune_modes(prune_modes.clone());

Expand Down
3 changes: 2 additions & 1 deletion crates/cli/commands/src/stage/dump/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use reth_evm::ConfigureEvm;
use reth_node_builder::NodeTypesWithDB;
use reth_node_core::dirs::{ChainPath, DataDirPath};
use reth_provider::{
providers::{ProviderNodeTypes, StaticFileProvider},
providers::{ProviderNodeTypes, RocksDBProvider, StaticFileProvider},
DatabaseProviderFactory, ProviderFactory,
};
use reth_stages::{stages::ExecutionStage, Stage, StageCheckpoint, UnwindInput};
Expand Down Expand Up @@ -42,6 +42,7 @@ where
Arc::new(output_db),
db_tool.chain(),
StaticFileProvider::read_write(output_datadir.static_files())?,
RocksDBProvider::builder(output_datadir.rocksdb()).build()?,
)?,
to,
from,
Expand Down
3 changes: 2 additions & 1 deletion crates/cli/commands/src/stage/dump/hashing_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use reth_db_api::{database::Database, table::TableImporter, tables};
use reth_db_common::DbTool;
use reth_node_core::dirs::{ChainPath, DataDirPath};
use reth_provider::{
providers::{ProviderNodeTypes, StaticFileProvider},
providers::{ProviderNodeTypes, RocksDBProvider, StaticFileProvider},
DatabaseProviderFactory, ProviderFactory,
};
use reth_stages::{stages::AccountHashingStage, Stage, StageCheckpoint, UnwindInput};
Expand Down Expand Up @@ -39,6 +39,7 @@ pub(crate) async fn dump_hashing_account_stage<N: ProviderNodeTypes<DB = Arc<Dat
Arc::new(output_db),
db_tool.chain(),
StaticFileProvider::read_write(output_datadir.static_files())?,
RocksDBProvider::builder(output_datadir.rocksdb()).build()?,
)?,
to,
from,
Expand Down
3 changes: 2 additions & 1 deletion crates/cli/commands/src/stage/dump/hashing_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use reth_db_api::{database::Database, table::TableImporter, tables};
use reth_db_common::DbTool;
use reth_node_core::dirs::{ChainPath, DataDirPath};
use reth_provider::{
providers::{ProviderNodeTypes, StaticFileProvider},
providers::{ProviderNodeTypes, RocksDBProvider, StaticFileProvider},
DatabaseProviderFactory, ProviderFactory,
};
use reth_stages::{stages::StorageHashingStage, Stage, StageCheckpoint, UnwindInput};
Expand All @@ -29,6 +29,7 @@ pub(crate) async fn dump_hashing_storage_stage<N: ProviderNodeTypes<DB = Arc<Dat
Arc::new(output_db),
db_tool.chain(),
StaticFileProvider::read_write(output_datadir.static_files())?,
RocksDBProvider::builder(output_datadir.rocksdb()).build()?,
)?,
to,
from,
Expand Down
3 changes: 2 additions & 1 deletion crates/cli/commands/src/stage/dump/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use reth_evm::ConfigureEvm;
use reth_exex::ExExManagerHandle;
use reth_node_core::dirs::{ChainPath, DataDirPath};
use reth_provider::{
providers::{ProviderNodeTypes, StaticFileProvider},
providers::{ProviderNodeTypes, RocksDBProvider, StaticFileProvider},
DatabaseProviderFactory, ProviderFactory,
};
use reth_stages::{
Expand Down Expand Up @@ -62,6 +62,7 @@ where
Arc::new(output_db),
db_tool.chain(),
StaticFileProvider::read_write(output_datadir.static_files())?,
RocksDBProvider::builder(output_datadir.rocksdb()).build()?,
)?,
to,
from,
Expand Down
13 changes: 13 additions & 0 deletions crates/e2e-test-utils/src/setup_import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ pub async fn setup_engine_with_chain_import(
// Create database path and static files path
let db_path = datadir.join("db");
let static_files_path = datadir.join("static_files");
let rocksdb_dir_path = datadir.join("rocksdb");

// Initialize the database using init_db (same as CLI import command)
// Use the same database arguments as the node will use
Expand All @@ -125,6 +126,7 @@ pub async fn setup_engine_with_chain_import(
db.clone(),
chain_spec.clone(),
reth_provider::providers::StaticFileProvider::read_write(static_files_path.clone())?,
reth_provider::providers::RocksDBProvider::builder(rocksdb_dir_path).build().unwrap(),
)?;

// Initialize genesis if needed
Expand Down Expand Up @@ -311,6 +313,7 @@ mod tests {
std::fs::create_dir_all(&datadir).unwrap();
let db_path = datadir.join("db");
let static_files_path = datadir.join("static_files");
let rocksdb_dir_path = datadir.join("rocksdb");

// Import the chain
{
Expand All @@ -324,6 +327,9 @@ mod tests {
chain_spec.clone(),
reth_provider::providers::StaticFileProvider::read_write(static_files_path.clone())
.unwrap(),
reth_provider::providers::RocksDBProvider::builder(rocksdb_dir_path.clone())
.build()
.unwrap(),
)
.expect("failed to create provider factory");

Expand Down Expand Up @@ -385,6 +391,9 @@ mod tests {
chain_spec.clone(),
reth_provider::providers::StaticFileProvider::read_only(static_files_path, false)
.unwrap(),
reth_provider::providers::RocksDBProvider::builder(rocksdb_dir_path)
.build()
.unwrap(),
)
.expect("failed to create provider factory");

Expand Down Expand Up @@ -472,11 +481,15 @@ mod tests {
// Create static files path
let static_files_path = datadir.join("static_files");

// Create rocksdb path
let rocksdb_dir_path = datadir.join("rocksdb");

// Create a provider factory
let provider_factory: ProviderFactory<MockNodeTypesWithDB> = ProviderFactory::new(
db.clone(),
chain_spec.clone(),
reth_provider::providers::StaticFileProvider::read_write(static_files_path).unwrap(),
reth_provider::providers::RocksDBProvider::builder(rocksdb_dir_path).build().unwrap(),
)
.expect("failed to create provider factory");

Expand Down
3 changes: 2 additions & 1 deletion crates/ethereum/node/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,14 @@ impl EthereumNode {
/// use reth_chainspec::ChainSpecBuilder;
/// use reth_db::open_db_read_only;
/// use reth_node_ethereum::EthereumNode;
/// use reth_provider::providers::StaticFileProvider;
/// use reth_provider::providers::{RocksDBProvider, StaticFileProvider};
/// use std::sync::Arc;
///
/// let factory = EthereumNode::provider_factory_builder()
/// .db(Arc::new(open_db_read_only("db", Default::default()).unwrap()))
/// .chainspec(ChainSpecBuilder::mainnet().build().into())
/// .static_file(StaticFileProvider::read_only("db/static_files", false).unwrap())
/// .rocksdb_provider(RocksDBProvider::builder("db/rocksdb").build().unwrap())
/// .build_provider_factory();
/// ```
pub fn provider_factory_builder() -> ProviderFactoryBuilder<Self> {
Expand Down
1 change: 1 addition & 0 deletions crates/ethereum/node/tests/it/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ async fn testing_rpc_build_block_works() -> eyre::Result<()> {
datadir: MaybePlatformPath::<DataDirPath>::from_str(tempdir.path().to_str().unwrap())
.expect("valid datadir"),
static_files_path: Some(tempdir.path().join("static")),
rocksdb_path: Some(tempdir.path().join("rocksdb")),
};
let config = NodeConfig::test().with_datadir_args(datadir_args).with_rpc(rpc_args);
let db = create_test_rw_db();
Expand Down
8 changes: 6 additions & 2 deletions crates/exex/test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ use futures_util::FutureExt;
use reth_chainspec::{ChainSpec, MAINNET};
use reth_consensus::test_utils::TestConsensus;
use reth_db::{
test_utils::{create_test_rw_db, create_test_static_files_dir, TempDatabase},
test_utils::{
create_test_rocksdb_dir, create_test_rw_db, create_test_static_files_dir, TempDatabase,
},
DatabaseEnv,
};
use reth_db_common::init::init_genesis;
Expand Down Expand Up @@ -50,7 +52,7 @@ use reth_node_ethereum::{
use reth_payload_builder::noop::NoopPayloadBuilderService;
use reth_primitives_traits::{Block as _, RecoveredBlock};
use reth_provider::{
providers::{BlockchainProvider, StaticFileProvider},
providers::{BlockchainProvider, RocksDBProvider, StaticFileProvider},
BlockReader, EthStorage, ProviderFactory,
};
use reth_tasks::TaskManager;
Expand Down Expand Up @@ -239,11 +241,13 @@ pub async fn test_exex_context_with_chain_spec(
let consensus = Arc::new(TestConsensus::default());

let (static_dir, _) = create_test_static_files_dir();
let (rocksdb_dir, _) = create_test_rocksdb_dir();
let db = create_test_rw_db();
let provider_factory = ProviderFactory::<NodeTypesWithDBAdapter<TestNode, _>>::new(
db,
chain_spec.clone(),
StaticFileProvider::read_write(static_dir.keep()).expect("static file provider"),
RocksDBProvider::builder(rocksdb_dir.keep()).build().unwrap(),
)?;

let genesis_hash = init_genesis(&provider_factory)?;
Expand Down
18 changes: 14 additions & 4 deletions crates/node/builder/src/launch/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ use reth_node_metrics::{
version::VersionInfo,
};
use reth_provider::{
providers::{NodeTypesForProvider, ProviderNodeTypes, StaticFileProvider},
providers::{NodeTypesForProvider, ProviderNodeTypes, RocksDBProvider, StaticFileProvider},
BlockHashReader, BlockNumReader, ProviderError, ProviderFactory, ProviderResult,
StageCheckpointReader, StaticFileProviderBuilder, StaticFileProviderFactory,
};
Expand Down Expand Up @@ -485,9 +485,19 @@ where
.with_blocks_per_file_for_segments(static_files_config.as_blocks_per_file_map())
.build()?;

let factory =
ProviderFactory::new(self.right().clone(), self.chain_spec(), static_file_provider)?
.with_prune_modes(self.prune_modes());
// Initialize RocksDB provider with metrics and statistics enabled
let rocksdb_provider = RocksDBProvider::builder(self.data_dir().rocksdb())
.with_metrics()
.with_statistics()
.build()?;

let factory = ProviderFactory::new(
self.right().clone(),
self.chain_spec(),
static_file_provider,
rocksdb_provider,
)?
.with_prune_modes(self.prune_modes());

// Check for consistency between database and static files. If it fails, it unwinds to
// the first block that's consistent between database and static files.
Expand Down
4 changes: 4 additions & 0 deletions crates/node/core/src/args/datadir_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ pub struct DatadirArgs {
verbatim_doc_comment
)]
pub static_files_path: Option<PathBuf>,

/// The absolute path to store `RocksDB` database in.
#[arg(long = "datadir.rocksdb", value_name = "PATH", verbatim_doc_comment)]
pub rocksdb_path: Option<PathBuf>,
}

impl DatadirArgs {
Expand Down
12 changes: 12 additions & 0 deletions crates/node/core/src/dirs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,18 @@ impl<D> ChainPath<D> {
}
}

/// Returns the path to the `RocksDB` database directory for this chain.
///
/// `<DIR>/<CHAIN_ID>/rocksdb`
pub fn rocksdb(&self) -> PathBuf {
let datadir_args = &self.2;
if let Some(rocksdb_path) = &datadir_args.rocksdb_path {
rocksdb_path.clone()
} else {
self.data_dir().join("rocksdb")
}
}

/// Returns the path to the reth p2p secret key for this chain.
///
/// `<DIR>/<CHAIN_ID>/discovery-secret`
Expand Down
3 changes: 2 additions & 1 deletion crates/optimism/node/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,13 +218,14 @@ impl OpNode {
/// use reth_db::open_db_read_only;
/// use reth_optimism_chainspec::OpChainSpecBuilder;
/// use reth_optimism_node::OpNode;
/// use reth_provider::providers::StaticFileProvider;
/// use reth_provider::providers::{RocksDBProvider, StaticFileProvider};
/// use std::sync::Arc;
///
/// let factory = OpNode::provider_factory_builder()
/// .db(Arc::new(open_db_read_only("db", Default::default()).unwrap()))
/// .chainspec(OpChainSpecBuilder::base_mainnet().build().into())
/// .static_file(StaticFileProvider::read_only("db/static_files", false).unwrap())
/// .rocksdb_provider(RocksDBProvider::builder("db/rocksdb").build().unwrap())
/// .build_provider_factory();
/// ```
pub fn provider_factory_builder() -> ProviderFactoryBuilder<Self> {
Expand Down
9 changes: 6 additions & 3 deletions crates/stages/api/src/stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,11 +324,13 @@ impl<Provider, S: Stage<Provider> + ?Sized> StageExt<Provider> for S {}
#[cfg(test)]
mod tests {
use reth_chainspec::MAINNET;
use reth_db::test_utils::{create_test_rw_db, create_test_static_files_dir};
use reth_db::test_utils::{
create_test_rocksdb_dir, create_test_rw_db, create_test_static_files_dir,
};
use reth_db_api::{models::StoredBlockBodyIndices, tables, transaction::DbTxMut};
use reth_provider::{
test_utils::MockNodeTypesWithDB, ProviderFactory, StaticFileProviderBuilder,
StaticFileProviderFactory, StaticFileSegment,
providers::RocksDBProvider, test_utils::MockNodeTypesWithDB, ProviderFactory,
StaticFileProviderBuilder, StaticFileProviderFactory, StaticFileSegment,
};
use reth_stages_types::StageCheckpoint;
use reth_testing_utils::generators::{self, random_signed_tx};
Expand All @@ -346,6 +348,7 @@ mod tests {
.with_blocks_per_file(1)
.build()
.unwrap(),
RocksDBProvider::builder(create_test_rocksdb_dir().0.keep()).build().unwrap(),
)
.unwrap();

Expand Down
13 changes: 11 additions & 2 deletions crates/stages/stages/src/test_utils/test_db.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use alloy_primitives::{keccak256, Address, BlockNumber, TxHash, TxNumber, B256};
use reth_chainspec::MAINNET;
use reth_db::{
test_utils::{create_test_rw_db, create_test_rw_db_with_path, create_test_static_files_dir},
test_utils::{
create_test_rocksdb_dir, create_test_rw_db, create_test_rw_db_with_path,
create_test_static_files_dir,
},
DatabaseEnv,
};
use reth_db_api::{
Expand All @@ -17,7 +20,9 @@ use reth_db_api::{
use reth_ethereum_primitives::{Block, EthPrimitives, Receipt};
use reth_primitives_traits::{Account, SealedBlock, SealedHeader, StorageEntry};
use reth_provider::{
providers::{StaticFileProvider, StaticFileProviderRWRefMut, StaticFileWriter},
providers::{
RocksDBProvider, StaticFileProvider, StaticFileProviderRWRefMut, StaticFileWriter,
},
test_utils::MockNodeTypesWithDB,
HistoryWriter, ProviderError, ProviderFactory, StaticFileProviderFactory, StatsReader,
};
Expand All @@ -38,12 +43,14 @@ impl Default for TestStageDB {
/// Create a new instance of [`TestStageDB`]
fn default() -> Self {
let (static_dir, static_dir_path) = create_test_static_files_dir();
let (_, rocksdb_dir_path) = create_test_rocksdb_dir();
Self {
temp_static_files_dir: static_dir,
factory: ProviderFactory::new(
create_test_rw_db(),
MAINNET.clone(),
StaticFileProvider::read_write(static_dir_path).unwrap(),
RocksDBProvider::builder(rocksdb_dir_path).build().unwrap(),
)
.expect("failed to create test provider factory"),
}
Expand All @@ -53,13 +60,15 @@ impl Default for TestStageDB {
impl TestStageDB {
pub fn new(path: &Path) -> Self {
let (static_dir, static_dir_path) = create_test_static_files_dir();
let (_, rocksdb_dir_path) = create_test_rocksdb_dir();

Self {
temp_static_files_dir: static_dir,
factory: ProviderFactory::new(
create_test_rw_db_with_path(path),
MAINNET.clone(),
StaticFileProvider::read_write(static_dir_path).unwrap(),
RocksDBProvider::builder(rocksdb_dir_path).build().unwrap(),
)
.expect("failed to create test provider factory"),
}
Expand Down
Loading
Loading