feat(db): record client version history (#7119)

This commit is contained in:
Roman Krasiuk
2024-03-13 13:07:13 +01:00
committed by GitHub
parent 884fd71a01
commit 610731ced8
32 changed files with 366 additions and 119 deletions

View File

@@ -5,13 +5,13 @@ use crate::{
};
use clap::Parser;
use reth_db::{
cursor::DbCursorRO, database::Database, mdbx::DatabaseArguments, open_db_read_only,
table::Table, transaction::DbTx, AccountChangeSets, AccountsHistory, AccountsTrie,
BlockBodyIndices, BlockOmmers, BlockWithdrawals, Bytecodes, CanonicalHeaders, DatabaseEnv,
HashedAccounts, HashedStorages, HeaderNumbers, HeaderTerminalDifficulties, Headers,
PlainAccountState, PlainStorageState, PruneCheckpoints, Receipts, StageCheckpointProgresses,
StageCheckpoints, StorageChangeSets, StoragesHistory, StoragesTrie, Tables, TransactionBlocks,
TransactionHashNumbers, TransactionSenders, Transactions,
cursor::DbCursorRO, database::Database, open_db_read_only, table::Table, transaction::DbTx,
AccountChangeSets, AccountsHistory, AccountsTrie, BlockBodyIndices, BlockOmmers,
BlockWithdrawals, Bytecodes, CanonicalHeaders, DatabaseEnv, HashedAccounts, HashedStorages,
HeaderNumbers, HeaderTerminalDifficulties, Headers, PlainAccountState, PlainStorageState,
PruneCheckpoints, Receipts, StageCheckpointProgresses, StageCheckpoints, StorageChangeSets,
StoragesHistory, StoragesTrie, Tables, TransactionBlocks, TransactionHashNumbers,
TransactionSenders, Transactions, VersionHistory,
};
use std::{
collections::HashMap,
@@ -60,10 +60,7 @@ impl Command {
pub fn execute(self, tool: &DbTool<DatabaseEnv>) -> eyre::Result<()> {
// open second db
let second_db_path: PathBuf = self.secondary_datadir.join("db").into();
let second_db = open_db_read_only(
&second_db_path,
DatabaseArguments::default().log_level(self.second_db.log_level),
)?;
let second_db = open_db_read_only(&second_db_path, self.second_db.database_args())?;
let tables = match &self.table {
Some(table) => std::slice::from_ref(table),
@@ -148,6 +145,9 @@ impl Command {
Tables::PruneCheckpoints => {
find_diffs::<PruneCheckpoints>(primary_tx, secondary_tx, output_dir)?
}
Tables::VersionHistory => {
find_diffs::<VersionHistory>(primary_tx, secondary_tx, output_dir)?
}
};
}

View File

@@ -93,12 +93,13 @@ impl TableViewer<()> for ListTableViewer<'_> {
let table_db = tx.inner.open_db(Some(self.args.table.name())).wrap_err("Could not open db.")?;
let stats = tx.inner.db_stat(&table_db).wrap_err(format!("Could not find table: {}", stringify!($table)))?;
let total_entries = stats.entries();
if self.args.skip > total_entries - 1 {
let final_entry_idx = total_entries.saturating_sub(1);
if self.args.skip > final_entry_idx {
error!(
target: "reth::cli",
"Start index {start} is greater than the final entry index ({final_entry_idx}) in the table {table}",
start = self.args.skip,
final_entry_idx = total_entries - 1,
final_entry_idx = final_entry_idx,
table = self.args.table.name()
);
return Ok(())

View File

@@ -10,7 +10,6 @@ use crate::{
};
use clap::{Parser, Subcommand};
use reth_db::{
mdbx::DatabaseArguments,
open_db, open_db_read_only,
version::{get_db_version, DatabaseVersionError, DB_VERSION},
};
@@ -96,13 +95,13 @@ impl Command {
// add network name to data dir
let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain);
let db_path = data_dir.db_path();
let db_log_level = DatabaseArguments::default().log_level(self.db.log_level);
let db_args = self.db.database_args();
let static_files_path = data_dir.static_files_path();
match self.command {
// TODO: We'll need to add this on the DB trait.
Subcommands::Stats(command) => {
let db = open_db_read_only(&db_path, db_log_level)?;
let db = open_db_read_only(&db_path, db_args)?;
let provider_factory =
ProviderFactory::new(db, self.chain.clone(), static_files_path)?;
@@ -110,7 +109,7 @@ impl Command {
command.execute(data_dir, &tool)?;
}
Subcommands::List(command) => {
let db = open_db_read_only(&db_path, db_log_level)?;
let db = open_db_read_only(&db_path, db_args)?;
let provider_factory =
ProviderFactory::new(db, self.chain.clone(), static_files_path)?;
@@ -118,7 +117,7 @@ impl Command {
command.execute(&tool)?;
}
Subcommands::Diff(command) => {
let db = open_db_read_only(&db_path, db_log_level)?;
let db = open_db_read_only(&db_path, db_args)?;
let provider_factory =
ProviderFactory::new(db, self.chain.clone(), static_files_path)?;
@@ -126,7 +125,7 @@ impl Command {
command.execute(&tool)?;
}
Subcommands::Get(command) => {
let db = open_db_read_only(&db_path, db_log_level)?;
let db = open_db_read_only(&db_path, db_args)?;
let provider_factory =
ProviderFactory::new(db, self.chain.clone(), static_files_path)?;
@@ -149,7 +148,7 @@ impl Command {
}
}
let db = open_db(&db_path, db_log_level)?;
let db = open_db(&db_path, db_args)?;
let provider_factory =
ProviderFactory::new(db, self.chain.clone(), static_files_path.clone())?;
@@ -157,14 +156,14 @@ impl Command {
tool.drop(db_path, static_files_path)?;
}
Subcommands::Clear(command) => {
let db = open_db(&db_path, db_log_level)?;
let db = open_db(&db_path, db_args)?;
let provider_factory =
ProviderFactory::new(db, self.chain.clone(), static_files_path)?;
command.execute(provider_factory)?;
}
Subcommands::CreateStaticFiles(command) => {
command.execute(data_dir, self.db.log_level, self.chain.clone())?;
command.execute(data_dir, self.db.database_args(), self.chain.clone())?;
}
Subcommands::Version => {
let local_db_version = match get_db_version(&db_path) {

View File

@@ -7,7 +7,6 @@ use reth_db::{
mdbx::{DatabaseArguments, MaxReadTransactionDuration},
open_db_read_only, DatabaseEnv,
};
use reth_interfaces::db::LogLevel;
use reth_nippy_jar::{NippyJar, NippyJarCursor};
use reth_node_core::dirs::{ChainPath, DataDirPath};
use reth_primitives::{
@@ -83,7 +82,7 @@ impl Command {
pub fn execute(
self,
data_dir: ChainPath<DataDirPath>,
log_level: Option<LogLevel>,
db_args: DatabaseArguments,
chain: Arc<ChainSpec>,
) -> eyre::Result<()> {
let all_combinations = self
@@ -98,9 +97,7 @@ impl Command {
let db = open_db_read_only(
data_dir.db_path().as_path(),
DatabaseArguments::default()
.log_level(log_level)
.max_read_transaction_duration(Some(MaxReadTransactionDuration::Unbounded)),
db_args.with_max_read_transaction_duration(Some(MaxReadTransactionDuration::Unbounded)),
)?;
let provider_factory =
Arc::new(ProviderFactory::new(db, chain.clone(), data_dir.static_files_path())?);

View File

@@ -18,7 +18,7 @@ use reth_beacon_consensus::BeaconConsensus;
use reth_blockchain_tree::{
BlockchainTree, BlockchainTreeConfig, ShareableBlockchainTree, TreeExternals,
};
use reth_db::{init_db, mdbx::DatabaseArguments, DatabaseEnv};
use reth_db::{init_db, DatabaseEnv};
use reth_interfaces::{consensus::Consensus, RethResult};
use reth_node_api::PayloadBuilderAttributes;
#[cfg(not(feature = "optimism"))]
@@ -157,8 +157,7 @@ impl Command {
fs::create_dir_all(&db_path)?;
// initialize the database
let db =
Arc::new(init_db(db_path, DatabaseArguments::default().log_level(self.db.log_level))?);
let db = Arc::new(init_db(db_path, self.db.database_args())?);
let provider_factory = ProviderFactory::new(
Arc::clone(&db),
Arc::clone(&self.chain),

View File

@@ -14,7 +14,7 @@ use clap::Parser;
use futures::{stream::select as stream_select, StreamExt};
use reth_beacon_consensus::BeaconConsensus;
use reth_config::Config;
use reth_db::{database::Database, init_db, mdbx::DatabaseArguments, DatabaseEnv};
use reth_db::{database::Database, init_db, DatabaseEnv};
use reth_downloaders::{
bodies::bodies::BodiesDownloaderBuilder,
headers::reverse_headers::ReverseHeadersDownloaderBuilder,
@@ -208,8 +208,7 @@ impl Command {
let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain);
let db_path = data_dir.db_path();
fs::create_dir_all(&db_path)?;
let db =
Arc::new(init_db(db_path, DatabaseArguments::default().log_level(self.db.log_level))?);
let db = Arc::new(init_db(db_path, self.db.database_args())?);
let provider_factory =
ProviderFactory::new(db.clone(), self.chain.clone(), data_dir.static_files_path())?;

View File

@@ -13,7 +13,7 @@ use crate::{
use backon::{ConstantBuilder, Retryable};
use clap::Parser;
use reth_config::Config;
use reth_db::{init_db, mdbx::DatabaseArguments, DatabaseEnv};
use reth_db::{init_db, DatabaseEnv};
use reth_interfaces::executor::BlockValidationError;
use reth_network::NetworkHandle;
use reth_network_api::NetworkInfo;
@@ -116,8 +116,7 @@ impl Command {
fs::create_dir_all(&db_path)?;
// initialize the database
let db =
Arc::new(init_db(db_path, DatabaseArguments::default().log_level(self.db.log_level))?);
let db = Arc::new(init_db(db_path, self.db.database_args())?);
let factory = ProviderFactory::new(&db, self.chain.clone(), data_dir.static_files_path())?;
let provider = factory.provider()?;

View File

@@ -14,9 +14,7 @@ use backon::{ConstantBuilder, Retryable};
use clap::Parser;
use reth_beacon_consensus::BeaconConsensus;
use reth_config::Config;
use reth_db::{
cursor::DbCursorRO, init_db, mdbx::DatabaseArguments, tables, transaction::DbTx, DatabaseEnv,
};
use reth_db::{cursor::DbCursorRO, init_db, tables, transaction::DbTx, DatabaseEnv};
use reth_interfaces::{consensus::Consensus, p2p::full_block::FullBlockClient};
use reth_network::NetworkHandle;
use reth_network_api::NetworkInfo;
@@ -127,8 +125,7 @@ impl Command {
fs::create_dir_all(&db_path)?;
// initialize the database
let db =
Arc::new(init_db(db_path, DatabaseArguments::default().log_level(self.db.log_level))?);
let db = Arc::new(init_db(db_path, self.db.database_args())?);
let factory = ProviderFactory::new(&db, self.chain.clone(), data_dir.static_files_path())?;
let provider_rw = factory.provider_rw()?;

View File

@@ -15,7 +15,7 @@ use reth_blockchain_tree::{
BlockchainTree, BlockchainTreeConfig, ShareableBlockchainTree, TreeExternals,
};
use reth_config::Config;
use reth_db::{init_db, mdbx::DatabaseArguments, DatabaseEnv};
use reth_db::{init_db, DatabaseEnv};
use reth_interfaces::consensus::Consensus;
use reth_network::NetworkHandle;
use reth_network_api::NetworkInfo;
@@ -124,8 +124,7 @@ impl Command {
fs::create_dir_all(&db_path)?;
// Initialize the database
let db =
Arc::new(init_db(db_path, DatabaseArguments::default().log_level(self.db.log_level))?);
let db = Arc::new(init_db(db_path, self.db.database_args())?);
let provider_factory =
ProviderFactory::new(db.clone(), self.chain.clone(), data_dir.static_files_path())?;

View File

@@ -13,7 +13,7 @@ use eyre::Context;
use futures::{Stream, StreamExt};
use reth_beacon_consensus::BeaconConsensus;
use reth_config::Config;
use reth_db::{database::Database, init_db, mdbx::DatabaseArguments};
use reth_db::{database::Database, init_db};
use reth_downloaders::{
bodies::bodies::BodiesDownloaderBuilder, file_client::FileClient,
headers::reverse_headers::ReverseHeadersDownloaderBuilder,
@@ -87,8 +87,7 @@ impl ImportCommand {
let db_path = data_dir.db_path();
info!(target: "reth::cli", path = ?db_path, "Opening database");
let db =
Arc::new(init_db(db_path, DatabaseArguments::default().log_level(self.db.log_level))?);
let db = Arc::new(init_db(db_path, self.db.database_args())?);
info!(target: "reth::cli", "Database opened");
let provider_factory =
ProviderFactory::new(db.clone(), self.chain.clone(), data_dir.static_files_path())?;

View File

@@ -8,7 +8,7 @@ use crate::{
dirs::{DataDirPath, MaybePlatformPath},
};
use clap::Parser;
use reth_db::{init_db, mdbx::DatabaseArguments};
use reth_db::init_db;
use reth_node_core::init::init_genesis;
use reth_primitives::ChainSpec;
use reth_provider::ProviderFactory;
@@ -53,8 +53,7 @@ impl InitCommand {
let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain);
let db_path = data_dir.db_path();
info!(target: "reth::cli", path = ?db_path, "Opening database");
let db =
Arc::new(init_db(&db_path, DatabaseArguments::default().log_level(self.db.log_level))?);
let db = Arc::new(init_db(&db_path, self.db.database_args())?);
info!(target: "reth::cli", "Database opened");
let provider_factory =

View File

@@ -10,7 +10,7 @@ use crate::{
dirs::{DataDirPath, MaybePlatformPath},
};
use clap::{value_parser, Args, Parser};
use reth_db::{init_db, mdbx::DatabaseArguments, DatabaseEnv};
use reth_db::{init_db, DatabaseEnv};
use reth_node_builder::{InitState, NodeBuilder, WithLaunchContext};
use reth_node_core::node_config::NodeConfig;
use reth_primitives::ChainSpec;
@@ -187,10 +187,7 @@ impl<Ext: clap::Args + fmt::Debug> NodeCommand<Ext> {
let db_path = data_dir.db_path();
tracing::info!(target: "reth::cli", path = ?db_path, "Opening database");
let database = Arc::new(
init_db(db_path.clone(), DatabaseArguments::default().log_level(db.log_level))?
.with_metrics(),
);
let database = Arc::new(init_db(db_path.clone(), self.db.database_args())?.with_metrics());
if with_unused_ports {
node_config = node_config.with_unused_ports();

View File

@@ -12,7 +12,7 @@ use crate::{
use backon::{ConstantBuilder, Retryable};
use clap::{Parser, Subcommand};
use reth_config::Config;
use reth_db::{mdbx::DatabaseArguments, open_db};
use reth_db::open_db;
use reth_discv4::NatResolver;
use reth_interfaces::p2p::bodies::client::BodiesClient;
use reth_primitives::{BlockHashOrNumber, ChainSpec, NodeRecord};
@@ -100,10 +100,7 @@ impl Command {
/// Execute `p2p` command
pub async fn execute(&self) -> eyre::Result<()> {
let tempdir = tempfile::TempDir::new()?;
let noop_db = Arc::new(open_db(
&tempdir.into_path(),
DatabaseArguments::default().log_level(self.db.log_level),
)?);
let noop_db = Arc::new(open_db(&tempdir.into_path(), self.db.database_args())?);
// add network name to data dir
let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain);

View File

@@ -9,7 +9,7 @@ use reth_db::{
init_db, tables,
transaction::DbTx,
};
use reth_node_core::init::init_genesis;
use reth_node_core::{args::DatabaseArgs, init::init_genesis};
use reth_primitives::ChainSpec;
use reth_provider::{BlockNumReader, HeaderProvider, ProviderError, ProviderFactory};
use reth_trie::StateRoot;
@@ -40,6 +40,10 @@ pub struct Command {
value_parser = genesis_value_parser
)]
chain: Arc<ChainSpec>,
/// All database related arguments
#[command(flatten)]
pub db: DatabaseArgs,
}
impl Command {
@@ -48,7 +52,7 @@ impl Command {
let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain);
let db_path = data_dir.db_path();
fs::create_dir_all(&db_path)?;
let db = Arc::new(init_db(db_path, Default::default())?);
let db = Arc::new(init_db(db_path, self.db.database_args())?);
let factory = ProviderFactory::new(&db, self.chain.clone(), data_dir.static_files_path())?;

View File

@@ -11,8 +11,8 @@ use crate::{
use clap::Parser;
use itertools::Itertools;
use reth_db::{
database::Database, mdbx::DatabaseArguments, open_db, static_file::iter_static_files, tables,
transaction::DbTxMut, DatabaseEnv,
database::Database, open_db, static_file::iter_static_files, tables, transaction::DbTxMut,
DatabaseEnv,
};
use reth_node_core::init::{insert_genesis_header, insert_genesis_state};
use reth_primitives::{
@@ -60,8 +60,7 @@ impl Command {
let db_path = data_dir.db_path();
fs::create_dir_all(&db_path)?;
let db =
open_db(db_path.as_ref(), DatabaseArguments::default().log_level(self.db.log_level))?;
let db = open_db(db_path.as_ref(), self.db.database_args())?;
let provider_factory =
ProviderFactory::new(db, self.chain.clone(), data_dir.static_files_path())?;
let static_file_provider = provider_factory.static_file_provider();

View File

@@ -11,8 +11,9 @@ use crate::args::{
};
use clap::Parser;
use reth_db::{
cursor::DbCursorRO, database::Database, init_db, table::TableImporter, tables,
transaction::DbTx, DatabaseEnv,
cursor::DbCursorRO, database::Database, init_db, mdbx::DatabaseArguments,
models::client_version::ClientVersion, table::TableImporter, tables, transaction::DbTx,
DatabaseEnv,
};
use reth_node_core::dirs::PlatformPath;
use reth_primitives::ChainSpec;
@@ -31,7 +32,6 @@ use execution::dump_execution_stage;
mod merkle;
use merkle::dump_merkle_stage;
use reth_db::mdbx::DatabaseArguments;
/// `reth dump-stage` command
#[derive(Debug, Parser)]
@@ -104,8 +104,7 @@ impl Command {
let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain);
let db_path = data_dir.db_path();
info!(target: "reth::cli", path = ?db_path, "Opening database");
let db =
Arc::new(init_db(db_path, DatabaseArguments::default().log_level(self.db.log_level))?);
let db = Arc::new(init_db(db_path, self.db.database_args())?);
let provider_factory =
ProviderFactory::new(db, self.chain.clone(), data_dir.static_files_path())?;
@@ -172,7 +171,7 @@ pub(crate) fn setup<DB: Database>(
info!(target: "reth::cli", ?output_db, "Creating separate db");
let output_datadir = init_db(output_db, Default::default())?;
let output_datadir = init_db(output_db, DatabaseArguments::new(ClientVersion::default()))?;
output_datadir.update(|tx| {
tx.import_table_with_range::<tables::BlockBodyIndices, _>(

View File

@@ -15,7 +15,7 @@ use crate::{
use clap::Parser;
use reth_beacon_consensus::BeaconConsensus;
use reth_config::Config;
use reth_db::{init_db, mdbx::DatabaseArguments};
use reth_db::init_db;
use reth_downloaders::bodies::bodies::BodiesDownloaderBuilder;
use reth_node_ethereum::EthEvmConfig;
use reth_primitives::ChainSpec;
@@ -127,8 +127,7 @@ impl Command {
let db_path = data_dir.db_path();
info!(target: "reth::cli", path = ?db_path, "Opening database");
let db =
Arc::new(init_db(db_path, DatabaseArguments::default().log_level(self.db.log_level))?);
let db = Arc::new(init_db(db_path, self.db.database_args())?);
info!(target: "reth::cli", "Database opened");
let factory = ProviderFactory::new(

View File

@@ -8,10 +8,7 @@ use crate::{
dirs::{DataDirPath, MaybePlatformPath},
};
use clap::{Parser, Subcommand};
use reth_db::{
cursor::DbCursorRO, database::Database, mdbx::DatabaseArguments, open_db, tables,
transaction::DbTx,
};
use reth_db::{cursor::DbCursorRO, database::Database, open_db, tables, transaction::DbTx};
use reth_primitives::{BlockHashOrNumber, ChainSpec};
use reth_provider::{BlockExecutionWriter, ProviderFactory};
use std::{ops::RangeInclusive, sync::Arc};
@@ -59,8 +56,7 @@ impl Command {
eyre::bail!("Database {db_path:?} does not exist.")
}
let db =
open_db(db_path.as_ref(), DatabaseArguments::default().log_level(self.db.log_level))?;
let db = open_db(db_path.as_ref(), self.db.database_args())?;
let range = self.command.unwind_range(&db)?;