From 80c0d618b48c73c12e4238cbed5ff25b230afd6f Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 30 May 2024 19:56:35 +0200 Subject: [PATCH] fix: make reth-db compile without default features (#8509) --- crates/storage/db/src/abstraction/common.rs | 6 +- .../storage/db/src/implementation/mdbx/tx.rs | 2 +- crates/storage/db/src/lib.rs | 92 ++----------------- crates/storage/db/src/mdbx.rs | 58 ++++++++++++ crates/storage/db/src/metrics.rs | 10 +- 5 files changed, 76 insertions(+), 92 deletions(-) create mode 100644 crates/storage/db/src/mdbx.rs diff --git a/crates/storage/db/src/abstraction/common.rs b/crates/storage/db/src/abstraction/common.rs index eef412935..408259a4c 100644 --- a/crates/storage/db/src/abstraction/common.rs +++ b/crates/storage/db/src/abstraction/common.rs @@ -20,7 +20,7 @@ pub type ValueOnlyResult = Result::Value>, DatabaseError> // Sealed trait helper to prevent misuse of the Database API. mod sealed { - use crate::{database::Database, mock::DatabaseMock, DatabaseEnv}; + use crate::{database::Database, mock::DatabaseMock}; use std::sync::Arc; /// Sealed trait to limit the implementers of the Database trait. @@ -28,7 +28,9 @@ mod sealed { impl Sealed for &DB {} impl Sealed for Arc {} - impl Sealed for DatabaseEnv {} + + #[cfg(feature = "mdbx")] + impl Sealed for crate::DatabaseEnv {} impl Sealed for DatabaseMock {} #[cfg(any(test, feature = "test-utils"))] diff --git a/crates/storage/db/src/implementation/mdbx/tx.rs b/crates/storage/db/src/implementation/mdbx/tx.rs index 962051832..f930a122c 100644 --- a/crates/storage/db/src/implementation/mdbx/tx.rs +++ b/crates/storage/db/src/implementation/mdbx/tx.rs @@ -52,7 +52,7 @@ impl Tx { /// Creates new `Tx` object with a `RO` or `RW` transaction and optionally enables metrics. #[inline] #[track_caller] - pub fn new_with_metrics( + pub(crate) fn new_with_metrics( inner: Transaction, env_metrics: Option>, ) -> reth_libmdbx::Result { diff --git a/crates/storage/db/src/lib.rs b/crates/storage/db/src/lib.rs index 102374c3b..4d5f0dd5c 100644 --- a/crates/storage/db/src/lib.rs +++ b/crates/storage/db/src/lib.rs @@ -74,11 +74,7 @@ mod utils; pub mod version; #[cfg(feature = "mdbx")] -/// Bindings for [MDBX](https://libmdbx.dqdkfa.ru/). -pub mod mdbx { - pub use crate::implementation::mdbx::*; - pub use reth_libmdbx::*; -} +pub mod mdbx; pub use abstraction::*; pub use reth_storage_errors::db::{DatabaseError, DatabaseWriteOperation}; @@ -86,85 +82,7 @@ pub use tables::*; pub use utils::is_database_empty; #[cfg(feature = "mdbx")] -pub use mdbx::{DatabaseEnv, DatabaseEnvKind}; - -use crate::mdbx::DatabaseArguments; -use eyre::WrapErr; -use std::path::Path; - -/// Creates a new database at the specified path if it doesn't exist. Does NOT create tables. Check -/// [`init_db`]. -pub fn create_db>(path: P, args: DatabaseArguments) -> eyre::Result { - use crate::version::{check_db_version_file, create_db_version_file, DatabaseVersionError}; - - let rpath = path.as_ref(); - if is_database_empty(rpath) { - reth_fs_util::create_dir_all(rpath) - .wrap_err_with(|| format!("Could not create database directory {}", rpath.display()))?; - create_db_version_file(rpath)?; - } else { - match check_db_version_file(rpath) { - Ok(_) => (), - Err(DatabaseVersionError::MissingFile) => create_db_version_file(rpath)?, - Err(err) => return Err(err.into()), - } - } - - #[cfg(feature = "mdbx")] - { - Ok(DatabaseEnv::open(rpath, DatabaseEnvKind::RW, args)?) - } - #[cfg(not(feature = "mdbx"))] - { - unimplemented!(); - } -} - -/// Opens up an existing database or creates a new one at the specified path. Creates tables if -/// necessary. Read/Write mode. -pub fn init_db>(path: P, args: DatabaseArguments) -> eyre::Result { - #[cfg(feature = "mdbx")] - { - let client_version = args.client_version().clone(); - let db = create_db(path, args)?; - db.create_tables()?; - db.record_client_version(client_version)?; - Ok(db) - } - #[cfg(not(feature = "mdbx"))] - { - unimplemented!(); - } -} - -/// Opens up an existing database. Read only mode. It doesn't create it or create tables if missing. -pub fn open_db_read_only(path: &Path, args: DatabaseArguments) -> eyre::Result { - #[cfg(feature = "mdbx")] - { - DatabaseEnv::open(path, DatabaseEnvKind::RO, args) - .with_context(|| format!("Could not open database at path: {}", path.display())) - } - #[cfg(not(feature = "mdbx"))] - { - unimplemented!(); - } -} - -/// Opens up an existing database. Read/Write mode with WriteMap enabled. It doesn't create it or -/// create tables if missing. -pub fn open_db(path: &Path, args: DatabaseArguments) -> eyre::Result { - #[cfg(feature = "mdbx")] - { - let db = DatabaseEnv::open(path, DatabaseEnvKind::RW, args.clone()) - .with_context(|| format!("Could not open database at path: {}", path.display()))?; - db.record_client_version(args.client_version().clone())?; - Ok(db) - } - #[cfg(not(feature = "mdbx"))] - { - unimplemented!(); - } -} +pub use mdbx::{create_db, init_db, open_db, open_db_read_only, DatabaseEnv, DatabaseEnvKind}; /// Collection of database test utilities #[cfg(any(test, feature = "test-utils"))] @@ -173,11 +91,15 @@ pub mod test_utils { use crate::{ database::Database, database_metrics::{DatabaseMetadata, DatabaseMetadataValue, DatabaseMetrics}, + mdbx::DatabaseArguments, models::client_version::ClientVersion, }; use reth_fs_util; use reth_libmdbx::MaxReadTransactionDuration; - use std::{path::PathBuf, sync::Arc}; + use std::{ + path::{Path, PathBuf}, + sync::Arc, + }; use tempfile::TempDir; /// Error during database open diff --git a/crates/storage/db/src/mdbx.rs b/crates/storage/db/src/mdbx.rs new file mode 100644 index 000000000..33dd4882b --- /dev/null +++ b/crates/storage/db/src/mdbx.rs @@ -0,0 +1,58 @@ +//! Bindings for [MDBX](https://libmdbx.dqdkfa.ru/). + +pub use crate::implementation::mdbx::*; +pub use reth_libmdbx::*; + +use crate::is_database_empty; +use eyre::Context; +use std::path::Path; + +/// Creates a new database at the specified path if it doesn't exist. Does NOT create tables. Check +/// [`init_db`]. +pub fn create_db>(path: P, args: DatabaseArguments) -> eyre::Result { + use crate::version::{check_db_version_file, create_db_version_file, DatabaseVersionError}; + + let rpath = path.as_ref(); + if is_database_empty(rpath) { + reth_fs_util::create_dir_all(rpath) + .wrap_err_with(|| format!("Could not create database directory {}", rpath.display()))?; + create_db_version_file(rpath)?; + } else { + match check_db_version_file(rpath) { + Ok(_) => (), + Err(DatabaseVersionError::MissingFile) => create_db_version_file(rpath)?, + Err(err) => return Err(err.into()), + } + } + + Ok(DatabaseEnv::open(rpath, DatabaseEnvKind::RW, args)?) +} + +/// Opens up an existing database or creates a new one at the specified path. Creates tables if +/// necessary. Read/Write mode. +pub fn init_db>(path: P, args: DatabaseArguments) -> eyre::Result { + { + let client_version = args.client_version().clone(); + let db = create_db(path, args)?; + db.create_tables()?; + db.record_client_version(client_version)?; + Ok(db) + } +} + +/// Opens up an existing database. Read only mode. It doesn't create it or create tables if missing. +pub fn open_db_read_only(path: &Path, args: DatabaseArguments) -> eyre::Result { + { + DatabaseEnv::open(path, DatabaseEnvKind::RO, args) + .with_context(|| format!("Could not open database at path: {}", path.display())) + } +} + +/// Opens up an existing database. Read/Write mode with WriteMap enabled. It doesn't create it or +/// create tables if missing. +pub fn open_db(path: &Path, args: DatabaseArguments) -> eyre::Result { + let db = DatabaseEnv::open(path, DatabaseEnvKind::RW, args.clone()) + .with_context(|| format!("Could not open database at path: {}", path.display()))?; + db.record_client_version(args.client_version().clone())?; + Ok(db) +} diff --git a/crates/storage/db/src/metrics.rs b/crates/storage/db/src/metrics.rs index 2dd4be2ac..e38884623 100644 --- a/crates/storage/db/src/metrics.rs +++ b/crates/storage/db/src/metrics.rs @@ -1,6 +1,5 @@ use crate::Tables; use metrics::{Gauge, Histogram}; -use reth_libmdbx::CommitLatency; use reth_metrics::{metrics::Counter, Metrics}; use rustc_hash::{FxHashMap, FxHasher}; use std::{ @@ -18,7 +17,7 @@ const LARGE_VALUE_THRESHOLD_BYTES: usize = 4096; /// Requires a metric recorder to be registered before creating an instance of this struct. /// Otherwise, metric recording will no-op. #[derive(Debug)] -pub struct DatabaseEnvMetrics { +pub(crate) struct DatabaseEnvMetrics { /// Caches OperationMetrics handles for each table and operation tuple. operations: FxHashMap<(Tables, Operation), OperationMetrics>, /// Caches TransactionMetrics handles for counters grouped by only transaction mode. @@ -124,13 +123,14 @@ impl DatabaseEnvMetrics { } /// Record metrics for closing a database transactions. + #[cfg(feature = "mdbx")] pub(crate) fn record_closed_transaction( &self, mode: TransactionMode, outcome: TransactionOutcome, open_duration: Duration, close_duration: Option, - commit_latency: Option, + commit_latency: Option, ) { self.transactions .get(&mode) @@ -152,6 +152,7 @@ pub(crate) enum TransactionMode { /// Read-write transaction mode. ReadWrite, } + impl TransactionMode { /// Returns the transaction mode as a string. pub(crate) const fn as_str(&self) -> &'static str { @@ -304,11 +305,12 @@ pub(crate) struct TransactionOutcomeMetrics { impl TransactionOutcomeMetrics { /// Record transaction closing with the duration it was open and the duration it took to close /// it. + #[cfg(feature = "mdbx")] pub(crate) fn record( &self, open_duration: Duration, close_duration: Option, - commit_latency: Option, + commit_latency: Option, ) { self.open_duration_seconds.record(open_duration);