feat: append chain network to db directory (#1846)

This commit is contained in:
Christoph Kieslich
2023-04-12 06:00:49 +02:00
committed by GitHub
parent 9e8d9883d1
commit c9eeb181a5
8 changed files with 175 additions and 26 deletions

View File

@ -14,7 +14,7 @@ use reth_downloaders::{
use reth_interfaces::{
consensus::Consensus, p2p::headers::client::NoopStatusUpdater, sync::SyncStateUpdater,
};
use reth_primitives::{ChainSpec, H256};
use reth_primitives::{Chain, ChainSpec, H256};
use reth_staged_sync::{
utils::{
chainspec::genesis_value_parser,
@ -77,11 +77,14 @@ impl ImportCommand {
pub async fn execute(self) -> eyre::Result<()> {
info!(target: "reth::cli", "reth {} starting", crate_version!());
let config: Config = self.load_config()?;
info!(target: "reth::cli", path = %self.db, "Configuration loaded");
let config: Config = self.load_config_with_chain(self.chain.chain)?;
info!(target: "reth::cli", path = %self.config.with_chain(self.chain.chain), "Configuration loaded");
info!(target: "reth::cli", path = %self.db, "Opening database");
let db = Arc::new(init_db(&self.db)?);
// add network name to db directory
let db_path = self.db.with_chain(self.chain.chain);
info!(target: "reth::cli", path = ?db_path, "Opening database");
let db = Arc::new(init_db(db_path)?);
info!(target: "reth::cli", "Database opened");
debug!(target: "reth::cli", chain=%self.chain.chain, genesis=?self.chain.genesis_hash(), "Initializing genesis");
@ -169,8 +172,12 @@ impl ImportCommand {
Ok((pipeline, events))
}
fn load_config(&self) -> eyre::Result<Config> {
confy::load_path::<Config>(&self.config).wrap_err("Could not load config")
/// Loads the reth config based on the intended chain
fn load_config_with_chain(&self, chain: Chain) -> eyre::Result<Config> {
// add network name to config directory
let config_path = self.config.with_chain(chain);
confy::load_path::<Config>(config_path.clone())
.wrap_err_with(|| format!("Could not load config file {}", config_path))
}
}

View File

@ -44,8 +44,11 @@ impl InitCommand {
pub async fn execute(&self) -> eyre::Result<()> {
info!(target: "reth::cli", "reth init starting");
info!(target: "reth::cli", path = %self.db, "Opening database");
let db = Arc::new(init_db(&self.db)?);
// add network name to db directory
let db_path = self.db.with_chain(self.chain.chain);
info!(target: "reth::cli", path = %db_path, "Opening database");
let db = Arc::new(init_db(&db_path)?);
info!(target: "reth::cli", "Database opened");
info!(target: "reth::cli", "Writing genesis block");

View File

@ -1,4 +1,6 @@
//! Database debugging tool
use std::sync::Arc;
use crate::{
dirs::{DbPath, PlatformPath},
utils::DbTool,
@ -8,6 +10,8 @@ use comfy_table::{Cell, Row, Table as ComfyTable};
use eyre::WrapErr;
use human_bytes::human_bytes;
use reth_db::{database::Database, tables};
use reth_primitives::ChainSpec;
use reth_staged_sync::utils::chainspec::genesis_value_parser;
use tracing::error;
/// DB List TUI
@ -26,6 +30,23 @@ pub struct Command {
#[arg(global = true, long, value_name = "PATH", verbatim_doc_comment, default_value_t)]
db: PlatformPath<DbPath>,
/// The chain this node is running.
///
/// Possible values are either a built-in chain or the path to a chain specification file.
///
/// Built-in chains:
/// - mainnet
/// - goerli
/// - sepolia
#[arg(
long,
value_name = "CHAIN_OR_PATH",
verbatim_doc_comment,
default_value = "mainnet",
value_parser = genesis_value_parser
)]
chain: Arc<ChainSpec>,
#[clap(subcommand)]
command: Subcommands,
}
@ -65,11 +86,14 @@ pub struct ListArgs {
impl Command {
/// Execute `db` command
pub async fn execute(&self) -> eyre::Result<()> {
std::fs::create_dir_all(&self.db)?;
// add network name to db directory
let db_path = self.db.with_chain(self.chain.chain);
std::fs::create_dir_all(&db_path)?;
// TODO: Auto-impl for Database trait
let db = reth_db::mdbx::Env::<reth_db::mdbx::WriteMap>::open(
self.db.as_ref(),
db_path.as_ref(),
reth_db::mdbx::EnvKind::RW,
)?;

View File

@ -1,4 +1,5 @@
//! reth data directories.
use reth_primitives::Chain;
use reth_staged_sync::utils::parse_path;
use std::{
env::VarError,
@ -7,6 +8,19 @@ use std::{
str::FromStr,
};
/// Constructs a string to be used as a path for configuration and db paths.
pub fn build_config_path_prefix(chain: Chain) -> String {
if chain == Chain::mainnet() {
"mainnet".to_string()
} else if chain == Chain::goerli() {
"goerli".to_string()
} else if chain == Chain::sepolia() {
"sepolia".to_string()
} else {
chain.id().to_string()
}
}
/// Returns the path to the reth data directory.
///
/// Refer to [dirs_next::data_dir] for cross-platform behavior.
@ -204,3 +218,69 @@ impl<D> From<PlatformPath<D>> for PathBuf {
value.0
}
}
impl<D> PlatformPath<D> {
/// Returns the path joined with another path
pub fn join<P: AsRef<Path>>(&self, path: P) -> PathBuf {
self.0.join(path)
}
}
impl<D> PlatformPath<D> {
/// Converts the path to a `ChainPath` with the given `Chain`.
///
/// If the inner path type refers to a file, the chain will be inserted between the parent
/// directory and the file name. If the inner path type refers to a directory, the chain will be
/// inserted between the parent directory and the directory name.
pub fn with_chain(&self, chain: Chain) -> ChainPath<D> {
// extract the parent and final component
let parent = self.0.parent().expect("Could not get parent of path");
let final_component = self.0.file_name().expect("Could not get file name of path");
// put the chain part in the middle
let chain_name = build_config_path_prefix(chain);
let mut path = PathBuf::from(parent);
path.push(chain_name);
path.push(final_component);
let platform_path = PlatformPath::<D>(path, std::marker::PhantomData);
ChainPath::new(platform_path, chain)
}
}
/// Wrapper type around PlatformPath that includes a `Chain`, used for separating reth data for
/// different networks.
///
/// If the chain is either mainnet, goerli, or sepolia, then the path will be:
/// * mainnet: `<DIR>/mainnet`
/// * goerli: `<DIR>/goerli`
/// * sepolia: `<DIR>/sepolia`
/// Otherwise, the path will be dependent on the chain ID:
/// * `<DIR>/<CHAIN_ID>`
#[derive(Clone, Debug, PartialEq)]
pub struct ChainPath<D>(PlatformPath<D>, Chain);
impl<D> ChainPath<D> {
/// Returns a new `ChainPath` given a `PlatformPath` and a `Chain`.
pub fn new(path: PlatformPath<D>, chain: Chain) -> Self {
Self(path, chain)
}
}
impl<D> AsRef<Path> for ChainPath<D> {
fn as_ref(&self) -> &Path {
self.0.as_ref()
}
}
impl<D> Display for ChainPath<D> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl<D> From<ChainPath<D>> for PathBuf {
fn from(value: ChainPath<D>) -> Self {
value.0.into()
}
}

View File

@ -53,9 +53,12 @@ pub struct Command {
impl Command {
/// Execute `db` command
pub async fn execute(&self) -> eyre::Result<()> {
std::fs::create_dir_all(&self.db)?;
// add network name to db directory
let db_path = self.db.with_chain(self.chain.chain);
let db = Env::<WriteMap>::open(self.db.as_ref(), reth_db::mdbx::EnvKind::RW)?;
std::fs::create_dir_all(&db_path)?;
let db = Env::<WriteMap>::open(db_path.as_ref(), reth_db::mdbx::EnvKind::RW)?;
let tool = DbTool::new(&db)?;

View File

@ -1,5 +1,7 @@
//! Database debugging tool
mod hashing_storage;
use std::sync::Arc;
use hashing_storage::dump_hashing_storage_stage;
mod hashing_account;
@ -10,6 +12,7 @@ use execution::dump_execution_stage;
mod merkle;
use merkle::dump_merkle_stage;
use reth_primitives::ChainSpec;
use crate::{
dirs::{DbPath, PlatformPath},
@ -19,7 +22,7 @@ use clap::Parser;
use reth_db::{
cursor::DbCursorRO, database::Database, table::TableImporter, tables, transaction::DbTx,
};
use reth_staged_sync::utils::init::init_db;
use reth_staged_sync::utils::{chainspec::genesis_value_parser, init::init_db};
use tracing::info;
/// `reth dump-stage` command
@ -35,6 +38,23 @@ pub struct Command {
#[arg(long, value_name = "PATH", verbatim_doc_comment, default_value_t)]
db: PlatformPath<DbPath>,
/// The chain this node is running.
///
/// Possible values are either a built-in chain or the path to a chain specification file.
///
/// Built-in chains:
/// - mainnet
/// - goerli
/// - sepolia
#[arg(
long,
value_name = "CHAIN_OR_PATH",
verbatim_doc_comment,
default_value = "mainnet",
value_parser = genesis_value_parser
)]
chain: Arc<ChainSpec>,
#[clap(subcommand)]
command: Stages,
}
@ -79,11 +99,14 @@ pub struct StageCommand {
impl Command {
/// Execute `dump-stage` command
pub async fn execute(&self) -> eyre::Result<()> {
std::fs::create_dir_all(&self.db)?;
// add network name to db directory
let db_path = self.db.with_chain(self.chain.chain);
std::fs::create_dir_all(&db_path)?;
// TODO: Auto-impl for Database trait
let db = reth_db::mdbx::Env::<reth_db::mdbx::WriteMap>::open(
self.db.as_ref(),
db_path.as_ref(),
reth_db::mdbx::EnvKind::RW,
)?;

View File

@ -39,7 +39,7 @@ use reth_interfaces::{
use reth_miner::TestPayloadStore;
use reth_network::{error::NetworkError, NetworkConfig, NetworkHandle, NetworkManager};
use reth_network_api::NetworkInfo;
use reth_primitives::{BlockHashOrNumber, ChainSpec, Head, Header, SealedHeader, H256};
use reth_primitives::{BlockHashOrNumber, Chain, ChainSpec, Head, Header, SealedHeader, H256};
use reth_provider::{BlockProvider, HeaderProvider, ShareableDatabase};
use reth_revm::Factory;
use reth_revm_inspectors::stack::Hook;
@ -144,11 +144,14 @@ impl Command {
// Does not do anything on windows.
raise_fd_limit();
let mut config: Config = self.load_config()?;
info!(target: "reth::cli", path = %self.config, "Configuration loaded");
let mut config: Config = self.load_config_with_chain(self.chain.chain)?;
info!(target: "reth::cli", path = %self.config.with_chain(self.chain.chain), "Configuration loaded");
info!(target: "reth::cli", path = %self.db, "Opening database");
let db = Arc::new(init_db(&self.db)?);
// add network name to db directory
let db_path = self.db.with_chain(self.chain.chain);
info!(target: "reth::cli", path = %db_path, "Opening database");
let db = Arc::new(init_db(&db_path)?);
let shareable_db = ShareableDatabase::new(Arc::clone(&db), Arc::clone(&self.chain));
info!(target: "reth::cli", "Database opened");
@ -174,6 +177,7 @@ impl Command {
info!(target: "reth::cli", "Test transaction pool initialized");
info!(target: "reth::cli", "Connecting to P2P network");
// let secret_key_path = self.p2p_secret_key.join(chain_prefix);
let secret_key = get_secret_key(&self.p2p_secret_key)?;
let network_config = self.load_network_config(
&config,
@ -401,10 +405,12 @@ impl Command {
Ok(pipeline)
}
fn load_config(&self) -> eyre::Result<Config> {
confy::load_path::<Config>(&self.config).wrap_err_with(|| {
format!("Could not load config file {}", self.config.as_ref().display())
})
/// Loads the reth config based on the intended chain
fn load_config_with_chain(&self, chain: Chain) -> eyre::Result<Config> {
// add network name to config directory
let config_path = self.config.with_chain(chain);
confy::load_path::<Config>(config_path.clone())
.wrap_err_with(|| format!("Could not load config file {}", config_path))
}
fn init_trusted_nodes(&self, config: &mut Config) {

View File

@ -109,7 +109,10 @@ impl Command {
let unwind = UnwindInput { stage_progress: self.to, unwind_to: self.from, bad_block: None };
let db = Arc::new(init_db(&self.db)?);
// add network name to db directory
let db_path = self.db.with_chain(self.chain.chain);
let db = Arc::new(init_db(db_path)?);
let mut tx = Transaction::new(db.as_ref())?;
if let Some(listen_addr) = self.metrics {