mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
fix(cli): remove usage of StageDB on DbTool (#448)
* use view and update instead of StageDB * change DbTool docs * clippy
This commit is contained in:
@ -4,7 +4,7 @@
|
||||
//! Database debugging tool
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
use eyre::Result;
|
||||
use eyre::{Result, WrapErr};
|
||||
use reth_db::{
|
||||
cursor::{DbCursorRO, Walker},
|
||||
database::Database,
|
||||
@ -14,7 +14,6 @@ use reth_db::{
|
||||
};
|
||||
use reth_interfaces::test_utils::generators::random_block_range;
|
||||
use reth_provider::insert_canonical_block;
|
||||
use reth_stages::StageDB;
|
||||
use std::path::Path;
|
||||
use tracing::info;
|
||||
|
||||
@ -71,35 +70,40 @@ impl Command {
|
||||
expanded_db_path,
|
||||
reth_db::mdbx::EnvKind::RW,
|
||||
)?;
|
||||
db.create_tables()?;
|
||||
|
||||
let mut tool = DbTool::new(&db)?;
|
||||
|
||||
match &self.command {
|
||||
// TODO: We'll need to add this on the DB trait.
|
||||
Subcommands::Stats { .. } => {
|
||||
// Get the env from MDBX
|
||||
let env = &tool.db.inner().inner;
|
||||
let tx = env.begin_ro_txn()?;
|
||||
for table in tables::TABLES.iter().map(|(_, name)| name) {
|
||||
let table_db = tx.open_db(Some(table))?;
|
||||
let stats = tx.db_stat(&table_db)?;
|
||||
tool.db.view(|tx| {
|
||||
for table in tables::TABLES.iter().map(|(_, name)| name) {
|
||||
let table_db =
|
||||
tx.inner.open_db(Some(table)).wrap_err("Could not open db.")?;
|
||||
|
||||
// Defaults to 16KB right now but we should
|
||||
// re-evaluate depending on the DB we end up using
|
||||
// (e.g. REDB does not have these options as configurable intentionally)
|
||||
let page_size = stats.page_size() as usize;
|
||||
let leaf_pages = stats.leaf_pages();
|
||||
let branch_pages = stats.branch_pages();
|
||||
let overflow_pages = stats.overflow_pages();
|
||||
let num_pages = leaf_pages + branch_pages + overflow_pages;
|
||||
let table_size = page_size * num_pages;
|
||||
tracing::info!(
|
||||
"Table {} has {} entries (total size: {} KB)",
|
||||
table,
|
||||
stats.entries(),
|
||||
table_size / 1024
|
||||
);
|
||||
}
|
||||
let stats = tx
|
||||
.inner
|
||||
.db_stat(&table_db)
|
||||
.wrap_err(format!("Could not find table: {table}"))?;
|
||||
|
||||
// Defaults to 16KB right now but we should
|
||||
// re-evaluate depending on the DB we end up using
|
||||
// (e.g. REDB does not have these options as configurable intentionally)
|
||||
let page_size = stats.page_size() as usize;
|
||||
let leaf_pages = stats.leaf_pages();
|
||||
let branch_pages = stats.branch_pages();
|
||||
let overflow_pages = stats.overflow_pages();
|
||||
let num_pages = leaf_pages + branch_pages + overflow_pages;
|
||||
let table_size = page_size * num_pages;
|
||||
tracing::info!(
|
||||
"Table {} has {} entries (total size: {} KB)",
|
||||
table,
|
||||
stats.entries(),
|
||||
table_size / 1024
|
||||
);
|
||||
}
|
||||
Ok::<(), eyre::Report>(())
|
||||
})??;
|
||||
}
|
||||
Subcommands::Seed { len } => {
|
||||
tool.seed(*len)?;
|
||||
@ -113,28 +117,29 @@ impl Command {
|
||||
}
|
||||
}
|
||||
|
||||
/// Abstraction over StageDB for writing/reading from/to the DB
|
||||
/// Wraps over the StageDB and derefs to a transaction.
|
||||
/// Wrapper over DB that implements many useful DB queries.
|
||||
struct DbTool<'a, DB: Database> {
|
||||
// TODO: StageDB derefs to Tx, is this weird or not?
|
||||
pub(crate) db: StageDB<'a, DB>,
|
||||
pub(crate) db: &'a DB,
|
||||
}
|
||||
|
||||
impl<'a, DB: Database> DbTool<'a, DB> {
|
||||
/// Takes a DB where the tables have already been created
|
||||
/// Takes a DB where the tables have already been created.
|
||||
fn new(db: &'a DB) -> eyre::Result<Self> {
|
||||
Ok(Self { db: StageDB::new(db)? })
|
||||
Ok(Self { db })
|
||||
}
|
||||
|
||||
/// Seeds the database with some random data, only used for testing
|
||||
fn seed(&mut self, len: u64) -> Result<()> {
|
||||
tracing::info!("generating random block range from 0 to {len}");
|
||||
let chain = random_block_range(0..len, Default::default());
|
||||
chain.iter().try_for_each(|block| {
|
||||
insert_canonical_block(&*self.db, block, true)?;
|
||||
Ok::<_, eyre::Error>(())
|
||||
})?;
|
||||
self.db.commit()?;
|
||||
|
||||
self.db.update(|tx| {
|
||||
chain.iter().try_for_each(|block| {
|
||||
insert_canonical_block(tx, block, true)?;
|
||||
Ok::<_, eyre::Error>(())
|
||||
})
|
||||
})??;
|
||||
|
||||
info!("Database committed with {len} blocks");
|
||||
|
||||
Ok(())
|
||||
@ -143,6 +148,9 @@ impl<'a, DB: Database> DbTool<'a, DB> {
|
||||
/// Lists the given table data
|
||||
fn list(&mut self, args: &ListArgs) -> Result<()> {
|
||||
match args.table.as_str() {
|
||||
"canonical_headers" => {
|
||||
self.list_table::<tables::CanonicalHeaders>(args.start, args.len)?
|
||||
}
|
||||
"headers" => self.list_table::<tables::Headers>(args.start, args.len)?,
|
||||
"txs" => self.list_table::<tables::Transactions>(args.start, args.len)?,
|
||||
_ => panic!(),
|
||||
@ -151,18 +159,21 @@ impl<'a, DB: Database> DbTool<'a, DB> {
|
||||
}
|
||||
|
||||
fn list_table<T: Table>(&mut self, start: usize, len: usize) -> Result<()> {
|
||||
let mut cursor = self.db.cursor::<T>()?;
|
||||
let data = self.db.view(|tx| {
|
||||
let mut cursor = tx.cursor::<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 {
|
||||
cursor: &mut cursor,
|
||||
start: start_walker,
|
||||
_tx_phantom: std::marker::PhantomData,
|
||||
};
|
||||
// TODO: Upstream this in the DB trait.
|
||||
let start_walker = cursor.current().transpose();
|
||||
let walker = Walker {
|
||||
cursor: &mut cursor,
|
||||
start: start_walker,
|
||||
_tx_phantom: std::marker::PhantomData,
|
||||
};
|
||||
|
||||
let data = walker.skip(start).take(len).collect::<Vec<_>>();
|
||||
dbg!(&data);
|
||||
walker.skip(start).take(len).collect::<Vec<_>>()
|
||||
})?;
|
||||
|
||||
println!("{data:?}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user