Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trie debug tooling #6

Merged
merged 20 commits into from
Feb 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ exclude = [

[dependencies]
bytes = "1.4.0"
enum-as-inner = "0.5.1"
enum-as-inner = "0.6.0"
ethereum-types = "0.14.1"
hex = "0.4.3"
keccak-hash = "0.10.0"
Expand All @@ -30,13 +30,17 @@ rlp = "0.5.2"
serde = { version = "1.0.160", features = ["derive", "rc"] }

[dev-dependencies]
eth_trie = "0.1.0"
pretty_env_logger = "0.4.0"
eth_trie = "0.4.0"
pretty_env_logger = "0.5.0"
rand = "0.8.5"
rlp-derive = "0.1.0"
serde = { version = "1.0.160", features = ["derive"] }
serde_json = "1.0.96"

[features]
default = ["trie_debug"]
trie_debug = []

[lib]
doc-scrape-examples = true

Expand Down
127 changes: 127 additions & 0 deletions src/debug_tools/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
use std::fmt::{self, Display};

use crate::{
nibbles::{Nibble, Nibbles},
partial_trie::{Node, PartialTrie},
utils::TrieNodeType,
};

#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub(super) enum PathSegment {
Empty,
Hash,
Branch(Nibble),
Extension(Nibbles),
Leaf(Nibbles),
}

impl Display for PathSegment {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PathSegment::Empty => write!(f, "Empty"),
PathSegment::Hash => write!(f, "Hash"),
PathSegment::Branch(nib) => write!(f, "Branch({})", nib),
PathSegment::Extension(nibs) => write!(f, "Extension({})", nibs),
PathSegment::Leaf(nibs) => write!(f, "Leaf({})", nibs),
Nashtare marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

impl PathSegment {
pub(super) fn node_type(&self) -> TrieNodeType {
match self {
PathSegment::Empty => TrieNodeType::Empty,
PathSegment::Hash => TrieNodeType::Hash,
PathSegment::Branch(_) => TrieNodeType::Branch,
PathSegment::Extension(_) => TrieNodeType::Extension,
PathSegment::Leaf(_) => TrieNodeType::Leaf,
}
}

pub(super) fn get_key_piece_from_seg_if_present(&self) -> Option<Nibbles> {
match self {
PathSegment::Empty | PathSegment::Hash => None,
PathSegment::Branch(nib) => Some(Nibbles::from_nibble(*nib)),
PathSegment::Extension(nibs) | PathSegment::Leaf(nibs) => Some(*nibs),
}
}
}

pub(super) fn get_segment_from_node_and_key_piece<T: PartialTrie>(
n: &Node<T>,
k_piece: &Nibbles,
) -> PathSegment {
match TrieNodeType::from(n) {
TrieNodeType::Empty => PathSegment::Empty,
TrieNodeType::Hash => PathSegment::Hash,
TrieNodeType::Branch => PathSegment::Branch(k_piece.get_nibble(0)),
TrieNodeType::Extension => PathSegment::Extension(*k_piece),
TrieNodeType::Leaf => PathSegment::Leaf(*k_piece),
}
}

/// Get the key piece from the given node if applicable.
///
/// Note that there is no specific [`Nibble`] associated with a branch like
/// there are [`Nibbles`] with [Extension][`Node::Extension`] and
/// [Leaf][`Node::Leaf`] nodes, and the only way to get the `Nibble`
/// "associated" with a branch is to look at the next `Nibble` in the current
/// key as we traverse down it.
pub(super) fn get_key_piece_from_node_pulling_from_key_for_branches<T: PartialTrie>(
n: &Node<T>,
curr_key: &Nibbles,
) -> Nibbles {
match n {
Node::Empty | Node::Hash(_) => Nibbles::default(),
Node::Branch { .. } => curr_key.get_next_nibbles(1),
Node::Extension { nibbles, child: _ } | Node::Leaf { nibbles, value: _ } => *nibbles,
}
}

/// Get the key piece from the given node if applicable. Note that
/// [branch][`Node::Branch`]s have no [`Nibble`] directly associated with them.
pub(super) fn get_key_piece_from_node<T: PartialTrie>(n: &Node<T>) -> Nibbles {
match n {
Node::Empty | Node::Hash(_) | Node::Branch { .. } => Nibbles::default(),
Node::Extension { nibbles, child: _ } | Node::Leaf { nibbles, value: _ } => *nibbles,
}
}

#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
pub struct NodePath(pub(super) Vec<PathSegment>);

impl NodePath {
pub(super) fn dup_and_append(&self, seg: PathSegment) -> Self {
let mut duped_vec = self.0.clone();
duped_vec.push(seg);

Self(duped_vec)
}

pub(super) fn append(&mut self, seg: PathSegment) {
self.0.push(seg);
}

fn write_elem(f: &mut fmt::Formatter<'_>, seg: &PathSegment) -> fmt::Result {
write!(f, "{}", seg)
}
}

impl Display for NodePath {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let num_elems = self.0.len();

// For everything but the last elem.
for seg in self.0.iter().take(num_elems.saturating_sub(1)) {
Self::write_elem(f, seg)?;
write!(f, " --> ")?;
}

// Avoid the extra `-->` for the last elem.
if let Some(seg) = self.0.last() {
Self::write_elem(f, seg)?;
}

Ok(())
}
}
Loading