mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(cli): drop execution stage (#1854)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
committed by
GitHub
parent
8673e95d0a
commit
876df20cac
@ -4,7 +4,7 @@ use std::str::FromStr;
|
||||
use crate::{
|
||||
chain, db,
|
||||
dirs::{LogsDir, PlatformPath},
|
||||
dump_stage, node, p2p,
|
||||
drop_stage, dump_stage, node, p2p,
|
||||
runner::CliRunner,
|
||||
stage, test_eth_chain, test_vectors,
|
||||
};
|
||||
@ -31,6 +31,7 @@ pub fn run() -> eyre::Result<()> {
|
||||
Commands::Db(command) => runner.run_until_ctrl_c(command.execute()),
|
||||
Commands::Stage(command) => runner.run_until_ctrl_c(command.execute()),
|
||||
Commands::DumpStage(command) => runner.run_until_ctrl_c(command.execute()),
|
||||
Commands::DropStage(command) => runner.run_until_ctrl_c(command.execute()),
|
||||
Commands::P2P(command) => runner.run_until_ctrl_c(command.execute()),
|
||||
Commands::TestVectors(command) => runner.run_until_ctrl_c(command.execute()),
|
||||
Commands::TestEthChain(command) => runner.run_until_ctrl_c(command.execute()),
|
||||
@ -63,6 +64,9 @@ pub enum Commands {
|
||||
/// Dumps a stage from a range into a new database.
|
||||
#[command(name = "dump-stage")]
|
||||
DumpStage(dump_stage::Command),
|
||||
/// Drops a stage's tables from the database.
|
||||
#[command(name = "drop-stage")]
|
||||
DropStage(drop_stage::Command),
|
||||
/// P2P Debugging utilities
|
||||
#[command(name = "p2p")]
|
||||
P2P(p2p::Command),
|
||||
|
||||
@ -1,20 +1,14 @@
|
||||
//! Database debugging tool
|
||||
use crate::dirs::{DbPath, PlatformPath};
|
||||
use crate::{
|
||||
dirs::{DbPath, PlatformPath},
|
||||
utils::DbTool,
|
||||
};
|
||||
use clap::{Parser, Subcommand};
|
||||
use comfy_table::{Cell, Row, Table as ComfyTable};
|
||||
use eyre::{Result, WrapErr};
|
||||
use eyre::WrapErr;
|
||||
use human_bytes::human_bytes;
|
||||
use reth_db::{
|
||||
cursor::{DbCursorRO, Walker},
|
||||
database::Database,
|
||||
table::Table,
|
||||
tables,
|
||||
transaction::DbTx,
|
||||
};
|
||||
use reth_interfaces::test_utils::generators::random_block_range;
|
||||
use reth_provider::insert_canonical_block;
|
||||
use std::collections::BTreeMap;
|
||||
use tracing::{error, info};
|
||||
use reth_db::{database::Database, tables};
|
||||
use tracing::error;
|
||||
|
||||
/// DB List TUI
|
||||
mod tui;
|
||||
@ -189,55 +183,3 @@ impl Command {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper over DB that implements many useful DB queries.
|
||||
pub(crate) struct DbTool<'a, DB: Database> {
|
||||
pub(crate) db: &'a DB,
|
||||
}
|
||||
|
||||
impl<'a, DB: Database> DbTool<'a, DB> {
|
||||
/// Takes a DB where the tables have already been created.
|
||||
pub(crate) fn new(db: &'a DB) -> eyre::Result<Self> {
|
||||
Ok(Self { db })
|
||||
}
|
||||
|
||||
/// Seeds the database with some random data, only used for testing
|
||||
fn seed(&mut self, len: u64) -> Result<()> {
|
||||
info!(target: "reth::cli", "Generating random block range from 0 to {len}");
|
||||
let chain = random_block_range(0..len, Default::default(), 0..64);
|
||||
|
||||
self.db.update(|tx| {
|
||||
chain.into_iter().try_for_each(|block| {
|
||||
insert_canonical_block(tx, block, None, true)?;
|
||||
Ok::<_, eyre::Error>(())
|
||||
})
|
||||
})??;
|
||||
|
||||
info!(target: "reth::cli", "Database seeded with {len} blocks");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Grabs the contents of the table within a certain index range and places the
|
||||
/// entries into a [`HashMap`][std::collections::HashMap].
|
||||
fn list<T: Table>(&mut self, start: usize, len: usize) -> Result<BTreeMap<T::Key, T::Value>> {
|
||||
let data = self.db.view(|tx| {
|
||||
let mut cursor = tx.cursor_read::<T>().expect("Was not able to obtain a cursor.");
|
||||
|
||||
// TODO: Upstream this in the DB trait.
|
||||
let start_walker = cursor.current().transpose();
|
||||
let walker = Walker::new(&mut cursor, start_walker);
|
||||
|
||||
walker.skip(start).take(len).collect::<Vec<_>>()
|
||||
})?;
|
||||
|
||||
data.into_iter()
|
||||
.collect::<Result<BTreeMap<T::Key, T::Value>, _>>()
|
||||
.map_err(|e| eyre::eyre!(e))
|
||||
}
|
||||
|
||||
fn drop(&mut self, path: &PlatformPath<DbPath>) -> Result<()> {
|
||||
info!(target: "reth::cli", "Dropping db at {}", path);
|
||||
std::fs::remove_dir_all(path).wrap_err("Dropping the database failed")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
82
bin/reth/src/drop_stage.rs
Normal file
82
bin/reth/src/drop_stage.rs
Normal file
@ -0,0 +1,82 @@
|
||||
//! Database debugging tool
|
||||
use crate::{
|
||||
dirs::{DbPath, PlatformPath},
|
||||
utils::DbTool,
|
||||
StageEnum,
|
||||
};
|
||||
use clap::Parser;
|
||||
use reth_db::{
|
||||
database::Database,
|
||||
mdbx::{Env, WriteMap},
|
||||
tables,
|
||||
transaction::DbTxMut,
|
||||
};
|
||||
use reth_primitives::ChainSpec;
|
||||
use reth_staged_sync::utils::{chainspec::genesis_value_parser, init::insert_genesis_state};
|
||||
use reth_stages::stages::EXECUTION;
|
||||
use std::sync::Arc;
|
||||
use tracing::info;
|
||||
|
||||
/// `reth drop-stage` command
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Command {
|
||||
/// The path to the database folder.
|
||||
///
|
||||
/// Defaults to the OS-specific data directory:
|
||||
///
|
||||
/// - Linux: `$XDG_DATA_HOME/reth/db` or `$HOME/.local/share/reth/db`
|
||||
/// - Windows: `{FOLDERID_RoamingAppData}/reth/db`
|
||||
/// - macOS: `$HOME/Library/Application Support/reth/db`
|
||||
#[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>,
|
||||
|
||||
stage: StageEnum,
|
||||
}
|
||||
|
||||
impl Command {
|
||||
/// Execute `db` command
|
||||
pub async fn execute(&self) -> eyre::Result<()> {
|
||||
std::fs::create_dir_all(&self.db)?;
|
||||
|
||||
let db = Env::<WriteMap>::open(self.db.as_ref(), reth_db::mdbx::EnvKind::RW)?;
|
||||
|
||||
let tool = DbTool::new(&db)?;
|
||||
|
||||
match &self.stage {
|
||||
StageEnum::Execution => {
|
||||
tool.db.update(|tx| {
|
||||
tx.clear::<tables::PlainAccountState>()?;
|
||||
tx.clear::<tables::PlainStorageState>()?;
|
||||
tx.clear::<tables::AccountChangeSet>()?;
|
||||
tx.clear::<tables::StorageChangeSet>()?;
|
||||
tx.clear::<tables::Bytecodes>()?;
|
||||
tx.put::<tables::SyncStage>(EXECUTION.0.to_string(), 0)?;
|
||||
insert_genesis_state::<Env<WriteMap>>(tx, self.chain.genesis())?;
|
||||
Ok::<_, eyre::Error>(())
|
||||
})??;
|
||||
}
|
||||
_ => {
|
||||
info!("Nothing to do for stage {:?}", self.stage);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
db::DbTool,
|
||||
dirs::{DbPath, PlatformPath},
|
||||
dump_stage::setup,
|
||||
utils::DbTool,
|
||||
};
|
||||
use eyre::Result;
|
||||
use reth_db::{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
db::DbTool,
|
||||
dirs::{DbPath, PlatformPath},
|
||||
dump_stage::setup,
|
||||
utils::DbTool,
|
||||
};
|
||||
use eyre::Result;
|
||||
use reth_db::{database::Database, table::TableImporter, tables, transaction::DbTx};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
db::DbTool,
|
||||
dirs::{DbPath, PlatformPath},
|
||||
dump_stage::setup,
|
||||
utils::DbTool,
|
||||
};
|
||||
use eyre::Result;
|
||||
use reth_db::{database::Database, table::TableImporter, tables};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
db::DbTool,
|
||||
dirs::{DbPath, PlatformPath},
|
||||
dump_stage::setup,
|
||||
utils::DbTool,
|
||||
};
|
||||
use eyre::Result;
|
||||
use reth_db::{database::Database, table::TableImporter, tables, transaction::DbTx};
|
||||
|
||||
@ -12,8 +12,8 @@ mod merkle;
|
||||
use merkle::dump_merkle_stage;
|
||||
|
||||
use crate::{
|
||||
db::DbTool,
|
||||
dirs::{DbPath, PlatformPath},
|
||||
utils::DbTool,
|
||||
};
|
||||
use clap::Parser;
|
||||
use reth_db::{
|
||||
|
||||
@ -12,6 +12,7 @@ pub mod chain;
|
||||
pub mod cli;
|
||||
pub mod db;
|
||||
pub mod dirs;
|
||||
pub mod drop_stage;
|
||||
pub mod dump_stage;
|
||||
pub mod node;
|
||||
pub mod p2p;
|
||||
@ -21,3 +22,11 @@ pub mod stage;
|
||||
pub mod test_eth_chain;
|
||||
pub mod test_vectors;
|
||||
pub mod utils;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, clap::ValueEnum)]
|
||||
enum StageEnum {
|
||||
Headers,
|
||||
Bodies,
|
||||
Senders,
|
||||
Execution,
|
||||
}
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
use crate::{
|
||||
args::NetworkArgs,
|
||||
dirs::{ConfigPath, DbPath, PlatformPath},
|
||||
prometheus_exporter,
|
||||
prometheus_exporter, StageEnum,
|
||||
};
|
||||
use clap::{Parser, ValueEnum};
|
||||
use clap::Parser;
|
||||
use reth_beacon_consensus::BeaconConsensus;
|
||||
use reth_downloaders::bodies::bodies::BodiesDownloaderBuilder;
|
||||
use reth_primitives::ChainSpec;
|
||||
@ -86,14 +86,6 @@ pub struct Command {
|
||||
network: NetworkArgs,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, ValueEnum)]
|
||||
enum StageEnum {
|
||||
Headers,
|
||||
Bodies,
|
||||
Senders,
|
||||
Execution,
|
||||
}
|
||||
|
||||
impl Command {
|
||||
/// Execute `stage` command
|
||||
pub async fn execute(&self) -> eyre::Result<()> {
|
||||
|
||||
@ -1,12 +1,25 @@
|
||||
//! Common CLI utility functions.
|
||||
|
||||
use reth_interfaces::p2p::{
|
||||
download::DownloadClient,
|
||||
headers::client::{HeadersClient, HeadersRequest},
|
||||
priority::Priority,
|
||||
use crate::dirs::{DbPath, PlatformPath};
|
||||
use eyre::{Result, WrapErr};
|
||||
use reth_db::{
|
||||
cursor::{DbCursorRO, Walker},
|
||||
database::Database,
|
||||
table::Table,
|
||||
transaction::{DbTx, DbTxMut},
|
||||
};
|
||||
use reth_interfaces::{
|
||||
p2p::{
|
||||
download::DownloadClient,
|
||||
headers::client::{HeadersClient, HeadersRequest},
|
||||
priority::Priority,
|
||||
},
|
||||
test_utils::generators::random_block_range,
|
||||
};
|
||||
use reth_network::FetchClient;
|
||||
use reth_primitives::{BlockHashOrNumber, HeadersDirection, SealedHeader};
|
||||
use reth_provider::insert_canonical_block;
|
||||
use std::collections::BTreeMap;
|
||||
use tracing::info;
|
||||
|
||||
/// Get a single header from network
|
||||
pub async fn get_single_header(
|
||||
@ -41,3 +54,66 @@ pub async fn get_single_header(
|
||||
|
||||
Ok(header)
|
||||
}
|
||||
|
||||
/// Wrapper over DB that implements many useful DB queries.
|
||||
pub struct DbTool<'a, DB: Database> {
|
||||
pub(crate) db: &'a DB,
|
||||
}
|
||||
|
||||
impl<'a, DB: Database> DbTool<'a, DB> {
|
||||
/// Takes a DB where the tables have already been created.
|
||||
pub(crate) fn new(db: &'a DB) -> eyre::Result<Self> {
|
||||
Ok(Self { db })
|
||||
}
|
||||
|
||||
/// Seeds the database with some random data, only used for testing
|
||||
pub fn seed(&mut self, len: u64) -> Result<()> {
|
||||
info!(target: "reth::cli", "Generating random block range from 0 to {len}");
|
||||
let chain = random_block_range(0..len, Default::default(), 0..64);
|
||||
|
||||
self.db.update(|tx| {
|
||||
chain.into_iter().try_for_each(|block| {
|
||||
insert_canonical_block(tx, block, None, true)?;
|
||||
Ok::<_, eyre::Error>(())
|
||||
})
|
||||
})??;
|
||||
|
||||
info!(target: "reth::cli", "Database seeded with {len} blocks");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Grabs the contents of the table within a certain index range and places the
|
||||
/// entries into a [`HashMap`][std::collections::HashMap].
|
||||
pub fn list<T: Table>(
|
||||
&mut self,
|
||||
start: usize,
|
||||
len: usize,
|
||||
) -> Result<BTreeMap<T::Key, T::Value>> {
|
||||
let data = self.db.view(|tx| {
|
||||
let mut cursor = tx.cursor_read::<T>().expect("Was not able to obtain a cursor.");
|
||||
|
||||
// TODO: Upstream this in the DB trait.
|
||||
let start_walker = cursor.current().transpose();
|
||||
let walker = Walker::new(&mut cursor, start_walker);
|
||||
|
||||
walker.skip(start).take(len).collect::<Vec<_>>()
|
||||
})?;
|
||||
|
||||
data.into_iter()
|
||||
.collect::<Result<BTreeMap<T::Key, T::Value>, _>>()
|
||||
.map_err(|e| eyre::eyre!(e))
|
||||
}
|
||||
|
||||
/// Drops the database at the given path.
|
||||
pub fn drop(&mut self, path: &PlatformPath<DbPath>) -> Result<()> {
|
||||
info!(target: "reth::cli", "Dropping db at {}", path);
|
||||
std::fs::remove_dir_all(path).wrap_err("Dropping the database failed")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Drops the provided table from the database.
|
||||
pub fn drop_table<T: Table>(&mut self) -> Result<()> {
|
||||
self.db.update(|tx| tx.clear::<T>())??;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user