diff --git a/bin/reth/src/commands/db/checksum.rs b/bin/reth/src/commands/db/checksum.rs index 4e172fe5cd36..cca78ad77217 100644 --- a/bin/reth/src/commands/db/checksum.rs +++ b/bin/reth/src/commands/db/checksum.rs @@ -43,7 +43,8 @@ impl Command { start_key: self.start_key, end_key: self.end_key, limit: self.limit, - }) + })?; + Ok(()) } } @@ -58,8 +59,12 @@ impl ChecksumViewer<'_, DB> { pub(crate) const fn new(tool: &'_ DbTool) -> ChecksumViewer<'_, DB> { ChecksumViewer { tool, start_key: None, end_key: None, limit: None } } +} + +impl TableViewer<(u64, Duration)> for ChecksumViewer<'_, DB> { + type Error = eyre::Report; - pub(crate) fn get_checksum(&self) -> Result<(u64, Duration), eyre::Report> { + fn view(&self) -> Result<(u64, Duration), Self::Error> { let provider = self.tool.provider_factory.provider()?.disable_long_read_transaction_safety(); let tx = provider.tx_ref(); @@ -124,17 +129,8 @@ impl ChecksumViewer<'_, DB> { let checksum = hasher.finish(); let elapsed = start_time.elapsed(); - Ok((checksum, elapsed)) - } -} - -impl TableViewer<()> for ChecksumViewer<'_, DB> { - type Error = eyre::Report; - - fn view(&self) -> Result<(), Self::Error> { - let (checksum, elapsed) = self.get_checksum::()?; info!("Checksum for table `{}`: {:#x} (elapsed: {:?})", T::NAME, checksum, elapsed); - Ok(()) + Ok((checksum, elapsed)) } } diff --git a/bin/reth/src/commands/db/diff.rs b/bin/reth/src/commands/db/diff.rs index 5ef4f6c7ff0b..162797d814e4 100644 --- a/bin/reth/src/commands/db/diff.rs +++ b/bin/reth/src/commands/db/diff.rs @@ -5,13 +5,8 @@ use crate::{ }; use clap::Parser; use reth_db::{ - cursor::DbCursorRO, database::Database, open_db_read_only, table::Table, transaction::DbTx, - AccountChangeSets, AccountsHistory, AccountsTrie, BlockBodyIndices, BlockOmmers, BlockRequests, - BlockWithdrawals, Bytecodes, CanonicalHeaders, DatabaseEnv, HashedAccounts, HashedStorages, - HeaderNumbers, HeaderTerminalDifficulties, Headers, PlainAccountState, PlainStorageState, - PruneCheckpoints, Receipts, StageCheckpointProgresses, StageCheckpoints, StorageChangeSets, - StoragesHistory, StoragesTrie, Tables, TransactionBlocks, TransactionHashNumbers, - TransactionSenders, Transactions, VersionHistory, + cursor::DbCursorRO, database::Database, open_db_read_only, table::Table, tables_to_generic, + transaction::DbTx, DatabaseEnv, Tables, }; use std::{ collections::HashMap, @@ -78,86 +73,11 @@ impl Command { secondary_tx.disable_long_read_transaction_safety(); let output_dir = self.output.clone(); - match table { - Tables::CanonicalHeaders => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::HeaderTerminalDifficulties => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::HeaderNumbers => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::Headers => find_diffs::(primary_tx, secondary_tx, output_dir)?, - Tables::BlockBodyIndices => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::BlockOmmers => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::BlockWithdrawals => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::BlockRequests => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::TransactionBlocks => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::Transactions => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::TransactionHashNumbers => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::Receipts => find_diffs::(primary_tx, secondary_tx, output_dir)?, - Tables::PlainAccountState => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::PlainStorageState => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::Bytecodes => find_diffs::(primary_tx, secondary_tx, output_dir)?, - Tables::AccountsHistory => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::StoragesHistory => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::AccountChangeSets => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::StorageChangeSets => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::HashedAccounts => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::HashedStorages => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::AccountsTrie => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::StoragesTrie => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::TransactionSenders => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::StageCheckpoints => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::StageCheckpointProgresses => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::PruneCheckpoints => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - Tables::VersionHistory => { - find_diffs::(primary_tx, secondary_tx, output_dir)? - } - }; + tables_to_generic!(table, |Table| find_diffs::( + primary_tx, + secondary_tx, + output_dir + ))?; } Ok(()) diff --git a/bin/reth/src/commands/db/stats.rs b/bin/reth/src/commands/db/stats.rs index d38c0e21af55..8ea473e8fe6b 100644 --- a/bin/reth/src/commands/db/stats.rs +++ b/bin/reth/src/commands/db/stats.rs @@ -1,5 +1,3 @@ -use std::time::Duration; - use crate::{commands::db::checksum::ChecksumViewer, utils::DbTool}; use clap::Parser; use comfy_table::{Cell, Row, Table as ComfyTable}; @@ -7,19 +5,13 @@ use eyre::WrapErr; use human_bytes::human_bytes; use itertools::Itertools; use reth_db::{ - database::Database, mdbx, static_file::iter_static_files, AccountChangeSets, AccountsHistory, - AccountsTrie, BlockBodyIndices, BlockOmmers, BlockRequests, BlockWithdrawals, Bytecodes, - CanonicalHeaders, DatabaseEnv, HashedAccounts, HashedStorages, HeaderNumbers, - HeaderTerminalDifficulties, Headers, PlainAccountState, PlainStorageState, PruneCheckpoints, - Receipts, StageCheckpointProgresses, StageCheckpoints, StorageChangeSets, StoragesHistory, - StoragesTrie, Tables, TransactionBlocks, TransactionHashNumbers, TransactionSenders, - Transactions, VersionHistory, + database::Database, mdbx, static_file::iter_static_files, DatabaseEnv, TableViewer, Tables, }; use reth_fs_util as fs; use reth_node_core::dirs::{ChainPath, DataDirPath}; use reth_primitives::static_file::{find_fixed_range, SegmentRangeInclusive}; use reth_provider::providers::StaticFileProvider; -use tracing::info; +use std::time::Duration; #[derive(Parser, Debug)] /// The arguments for the `reth db stats` command @@ -322,46 +314,8 @@ impl Command { let db_tables = Tables::ALL; let mut total_elapsed = Duration::default(); - for db_table in db_tables { - info!("Calculating checksum for table: {}", db_table); - - let viewer = ChecksumViewer::new(tool); - let (checksum, elapsed) = match db_table { - Tables::AccountsHistory => viewer.get_checksum::().unwrap(), - Tables::AccountChangeSets => viewer.get_checksum::().unwrap(), - Tables::AccountsTrie => viewer.get_checksum::().unwrap(), - Tables::BlockBodyIndices => viewer.get_checksum::().unwrap(), - Tables::BlockOmmers => viewer.get_checksum::().unwrap(), - Tables::BlockWithdrawals => viewer.get_checksum::().unwrap(), - Tables::BlockRequests => viewer.get_checksum::().unwrap(), - Tables::Bytecodes => viewer.get_checksum::().unwrap(), - Tables::CanonicalHeaders => viewer.get_checksum::().unwrap(), - Tables::HashedAccounts => viewer.get_checksum::().unwrap(), - Tables::HashedStorages => viewer.get_checksum::().unwrap(), - Tables::HeaderNumbers => viewer.get_checksum::().unwrap(), - Tables::HeaderTerminalDifficulties => { - viewer.get_checksum::().unwrap() - } - Tables::Headers => viewer.get_checksum::().unwrap(), - Tables::PlainAccountState => viewer.get_checksum::().unwrap(), - Tables::PlainStorageState => viewer.get_checksum::().unwrap(), - Tables::PruneCheckpoints => viewer.get_checksum::().unwrap(), - Tables::Receipts => viewer.get_checksum::().unwrap(), - Tables::StageCheckpointProgresses => { - viewer.get_checksum::().unwrap() - } - Tables::StageCheckpoints => viewer.get_checksum::().unwrap(), - Tables::StorageChangeSets => viewer.get_checksum::().unwrap(), - Tables::StoragesHistory => viewer.get_checksum::().unwrap(), - Tables::StoragesTrie => viewer.get_checksum::().unwrap(), - Tables::TransactionBlocks => viewer.get_checksum::().unwrap(), - Tables::TransactionHashNumbers => { - viewer.get_checksum::().unwrap() - } - Tables::TransactionSenders => viewer.get_checksum::().unwrap(), - Tables::Transactions => viewer.get_checksum::().unwrap(), - Tables::VersionHistory => viewer.get_checksum::().unwrap(), - }; + for &db_table in db_tables { + let (checksum, elapsed) = ChecksumViewer::new(tool).view_rt(db_table).unwrap(); // increment duration for final report total_elapsed += elapsed; diff --git a/crates/storage/db/src/lib.rs b/crates/storage/db/src/lib.rs index 102374c3bc34..6a9c44a7fa3b 100644 --- a/crates/storage/db/src/lib.rs +++ b/crates/storage/db/src/lib.rs @@ -82,6 +82,7 @@ pub mod mdbx { pub use abstraction::*; pub use reth_storage_errors::db::{DatabaseError, DatabaseWriteOperation}; +pub use table::*; pub use tables::*; pub use utils::is_database_empty; diff --git a/crates/storage/db/src/tables/mod.rs b/crates/storage/db/src/tables/mod.rs index cc420fabcc93..4f81e16e5605 100644 --- a/crates/storage/db/src/tables/mod.rs +++ b/crates/storage/db/src/tables/mod.rs @@ -90,6 +90,11 @@ pub trait TableViewer { /// The error type returned by the viewer. type Error; + /// Calls `view` with the correct table type. + fn view_rt(&self, table: Tables) -> Result { + table.view(self) + } + /// Operate on the table in a generic way. fn view(&self) -> Result; @@ -101,8 +106,8 @@ pub trait TableViewer { } } -#[macro_export] /// Defines all the tables in the database. +#[macro_export] macro_rules! tables { (@bool) => { false }; (@bool $($t:tt)+) => { true }; @@ -196,7 +201,7 @@ macro_rules! tables { /// Allows to operate on specific table type pub fn view(&self, visitor: &T) -> Result where - T: TableViewer, + T: ?Sized + TableViewer, { match self { $( @@ -240,6 +245,33 @@ macro_rules! tables { pub(super) const $name: &'static str = stringify!($name); )* } + + /// Maps a run-time [`Tables`] enum value to its corresponding compile-time [`Table`] type. + /// + /// This is a simpler alternative to [`TableViewer`]. + /// + /// # Examples + /// + /// ``` + /// use reth_db::{Table, Tables, tables_to_generic}; + /// + /// let table = Tables::Headers; + /// let result = tables_to_generic!(table, |GenericTable| GenericTable::TABLE); + /// assert_eq!(result, table); + /// ``` + #[macro_export] + macro_rules! tables_to_generic { + ($table:expr, |$generic_name:ident| $e:expr) => { + match $table { + $( + Tables::$name => { + use $crate::tables::$name as $generic_name; + $e + }, + )* + } + }; + } }; }