Skip to content

Commit

Permalink
Expose graph option for fwdctl
Browse files Browse the repository at this point in the history
Dump was already dumping the keys and values, so we should keep
that, but added in the option of calling the dump() method that
produces a digraph of the trie.

Additional changes: hashes and binary values are truncated to 6
characters, followed by an ellipsis, and the graphs are rotated
so they go left-right. This makes the graphs a lot prettier.

Partial paths can still be long but truncating them seemed like
a bad idea, so they are the only long string in the boxes now.
  • Loading branch information
rkuris committed Oct 8, 2024
1 parent 34c02d2 commit e8b71ba
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 4 deletions.
14 changes: 11 additions & 3 deletions firewood/src/merkle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ macro_rules! write_attributes {
write!($writer, " val={}", string)?
}
_ => {
write!($writer, " val={}", hex::encode($value))?;
let hex = hex::encode($value);
if hex.len() > 6 {
write!($writer, " val={:.6}...", hex)?;
} else {
write!($writer, " val={}", hex)?;
}
}
}
}
Expand Down Expand Up @@ -341,7 +346,10 @@ impl<T: HashedNodeReader> Merkle<T> {
seen: &mut HashSet<LinearAddress>,
writer: &mut dyn Write,
) -> Result<(), MerkleError> {
write!(writer, " {addr}[label=\"addr:{addr:?} hash:{hash:?}")?;
write!(writer, " {addr}[label=\"addr:{addr:?}")?;
if let Some(hash) = hash {
write!(writer, " hash:{hash:.6?}...")?;
}

match &*self.read_node(addr)? {
Node::Branch(b) => {
Expand Down Expand Up @@ -378,7 +386,7 @@ impl<T: HashedNodeReader> Merkle<T> {

pub fn dump(&self) -> Result<String, MerkleError> {
let mut result = vec![];
writeln!(result, "digraph Merkle {{")?;
writeln!(result, "digraph Merkle {{\n rankdir=LR;")?;
if let Some((root_addr, root_hash)) = self.nodestore.root_address_and_hash()? {
writeln!(result, " root -> {root_addr}")?;
let mut seen = HashSet::new();
Expand Down
27 changes: 27 additions & 0 deletions fwdctl/src/graph.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (C) 2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE.md for licensing terms.

use clap::Args;
use firewood::db::{Db, DbConfig};
use firewood::v2::api;
use std::io::stdout;

#[derive(Debug, Args)]
pub struct Options {
/// The database path (if no path is provided, return an error). Defaults to firewood.
#[arg(
value_name = "DB_NAME",
default_value_t = String::from("firewood"),
help = "Name of the database"
)]
pub db: String,
}

pub(super) async fn run(opts: &Options) -> Result<(), api::Error> {
log::debug!("dump database {:?}", opts);
let cfg = DbConfig::builder().truncate(false);

let db = Db::new(opts.db.clone(), cfg.build()).await?;
db.dump(&mut stdout())?;
Ok(())
}
4 changes: 4 additions & 0 deletions fwdctl/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod create;
pub mod delete;
pub mod dump;
pub mod get;
pub mod graph;
pub mod insert;
pub mod root;

Expand Down Expand Up @@ -44,6 +45,8 @@ enum Commands {
Root(root::Options),
/// Dump contents of key/value store
Dump(dump::Options),
/// Produce a dot file of the database
Graph(graph::Options),
}

#[tokio::main]
Expand All @@ -62,5 +65,6 @@ async fn main() -> Result<(), api::Error> {
Commands::Delete(opts) => delete::run(opts).await,
Commands::Root(opts) => root::run(opts).await,
Commands::Dump(opts) => dump::run(opts).await,
Commands::Graph(opts) => graph::run(opts).await,
}
}
3 changes: 2 additions & 1 deletion storage/src/trie_hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ impl AsRef<[u8]> for TrieHash {

impl Debug for TrieHash {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
write!(f, "{}", hex::encode(self.0))
let width = f.precision().unwrap_or_default();
write!(f, "{:.*}", width, hex::encode(self.0))
}
}

Expand Down

0 comments on commit e8b71ba

Please sign in to comment.