Skip to content

Commit 7fe3b67

Browse files
committed
feat(misc): add tree display & remove T from Tree struct
1 parent 82c7011 commit 7fe3b67

File tree

6 files changed

+161
-72
lines changed

6 files changed

+161
-72
lines changed

bindings/python/Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mrkle/src/error.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
use crate::prelude::*;
2+
use crate::{IndexType, NodeIndex};
3+
14
/// Errors that may occur when performing operations on a [`Node`](crate::tree::Node).
25
#[derive(Debug, thiserror::Error)]
36
pub enum NodeError {
@@ -116,3 +119,14 @@ pub enum ProofError {
116119
#[error("{0}")]
117120
TreeError(#[from] TreeError),
118121
}
122+
123+
impl ProofError {
124+
#[inline]
125+
#[allow(dead_code)]
126+
pub(crate) fn out_of_bounds<Ix: IndexType>(len: usize, index: NodeIndex<Ix>) -> ProofError {
127+
ProofError::from(TreeError::IndexOutOfBounds {
128+
index: index.index(),
129+
len: len,
130+
})
131+
}
132+
}

mrkle/src/lib.rs

Lines changed: 64 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ compile_error!("must choose either the `std` or `alloc` feature");
1313

1414
#[path = "entry.rs"]
1515
mod borrowed;
16+
mod proof;
1617

1718
/// Cryptographic hash utilities and traits used in Merkle trees.
1819
pub mod hasher;
@@ -27,11 +28,12 @@ pub mod tree;
2728
/// Includes errors for tree construction, hashing, and I/O operations.
2829
pub mod error;
2930

30-
pub(crate) use crate::error::{EntryError, MrkleError, NodeError, ProofError, TreeError};
31+
pub(crate) use crate::error::{EntryError, NodeError, ProofError, TreeError};
3132
pub(crate) use crate::tree::DefaultIx;
3233

3334
pub use crate::hasher::{GenericArray, Hasher, MrkleHasher};
34-
pub use crate::tree::{IndexType, Iter, IterIdx, Node, NodeIndex, Tree, TreeView};
35+
pub use crate::proof::{MrkleProof, MrkleProofNode};
36+
pub use crate::tree::{IndexType, Iter, IterIdx, MutNode, Node, NodeIndex, Tree, TreeView};
3537
pub use borrowed::*;
3638

3739
#[allow(unused_imports, reason = "future proofing for tree features.")]
@@ -54,6 +56,7 @@ pub(crate) mod prelude {
5456
pub use std::vec::Vec;
5557
}
5658

59+
pub use core::fmt::{Debug, Display};
5760
pub use core::marker::{Copy, PhantomData};
5861
pub use core::slice::SliceIndex;
5962
pub(crate) use crypto::digest::Digest;
@@ -63,7 +66,6 @@ pub(crate) mod prelude {
6366
pub use stds::*;
6467
}
6568

66-
use crypto::digest::OutputSizeUser;
6769
use prelude::*;
6870

6971
/// A generic immutable node in a Merkle Tree.
@@ -491,7 +493,7 @@ impl<T, D: Digest, Ix: IndexType> core::fmt::Debug for MrkleNode<T, D, Ix> {
491493
}
492494

493495
// Display implementation - user-friendly representation
494-
impl<T, D: Digest, Ix: IndexType> core::fmt::Display for MrkleNode<T, D, Ix> {
496+
impl<T, D: Digest, Ix: IndexType> Display for MrkleNode<T, D, Ix> {
495497
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
496498
let hash_bytes = self.hash.as_slice();
497499
let hash_preview = if hash_bytes.len() >= 4 {
@@ -506,16 +508,7 @@ impl<T, D: Digest, Ix: IndexType> core::fmt::Display for MrkleNode<T, D, Ix> {
506508
format!("{:02x?}", hash_bytes)
507509
};
508510

509-
if self.is_leaf() {
510-
write!(f, "Leaf[hash: {}]", hash_preview)
511-
} else {
512-
write!(
513-
f,
514-
"Internal[children: {}, hash: {}]",
515-
self.children.len(),
516-
hash_preview
517-
)
518-
}
511+
write!(f, "{}", hash_preview)
519512
}
520513
}
521514

@@ -537,6 +530,22 @@ impl<T, D: Digest, Ix: IndexType> core::fmt::Display for MrkleNode<T, D, Ix> {
537530
/// * `Ix` - The index type for node references, defaults to [`DefaultIx`]
538531
///
539532
///
533+
/// # Example
534+
///
535+
/// ```
536+
/// use mrkle::MrkleTree;
537+
/// use sha1::Sha1;
538+
///
539+
/// // build basic binary merkle tree.
540+
/// let tree = MrkleTree::<&str, Sha1>::from(vec![
541+
/// "A",
542+
/// "B",
543+
/// "C",
544+
/// "D",
545+
/// "E",
546+
/// ]);
547+
/// ```
548+
///
540549
/// # Security Considerations
541550
///
542551
/// The security of a `MrkleTree` depends entirely on the cryptographic strength
@@ -551,7 +560,7 @@ pub struct MrkleTree<T, D: Digest, Ix: IndexType = DefaultIx> {
551560
/// This field is private to maintain invariants about the tree structure
552561
/// and ensure all modifications go through the proper cryptographic
553562
/// verification process.
554-
core: Tree<T, MrkleNode<T, D, Ix>, Ix>,
563+
core: Tree<MrkleNode<T, D, Ix>, Ix>,
555564
}
556565

557566
impl<T, D: Digest> Default for MrkleTree<T, D> {
@@ -567,8 +576,8 @@ where
567576
{
568577
/// Constructs a Merkle binary tree from leaf nodes using bottom-up approach.
569578
///
570-
/// # Parameters
571-
/// - `leaves`: Vector of `T` nodes to build the tree from
579+
/// # Arguments
580+
/// * `leaves` - Vector of `T` nodes to build the tree from
572581
///
573582
/// # Returns
574583
/// A generic binary [`MrkleTree`]
@@ -664,7 +673,7 @@ impl<T, D: Digest, Ix: IndexType> MrkleTree<T, D, Ix> {
664673

665674
/// Return root [`TreeView`] of the [`MrkleTree`]
666675
#[inline]
667-
pub fn view(&self) -> TreeView<'_, T, MrkleNode<T, D, Ix>, Ix> {
676+
pub fn view(&self) -> TreeView<'_, MrkleNode<T, D, Ix>, Ix> {
668677
self.core.view()
669678
}
670679

@@ -674,17 +683,17 @@ impl<T, D: Digest, Ix: IndexType> MrkleTree<T, D, Ix> {
674683
pub fn subtree_view(
675684
&self,
676685
root: NodeIndex<Ix>,
677-
) -> Option<TreeView<'_, T, MrkleNode<T, D, Ix>, Ix>> {
686+
) -> Option<TreeView<'_, MrkleNode<T, D, Ix>, Ix>> {
678687
self.core.subtree_view(root)
679688
}
680689

681690
/// Returns Iterator pattern [`Iter`] which returns a unmutable Node reference.
682-
pub fn iter(&self) -> Iter<'_, T, MrkleNode<T, D, Ix>, Ix> {
691+
pub fn iter(&self) -> Iter<'_, MrkleNode<T, D, Ix>, Ix> {
683692
self.core.iter()
684693
}
685694

686695
///Returns Iterator pattern [`IterIdx`] which returns a [`NodeIndex<Ix>`] of the node.
687-
pub fn iter_idx(&self) -> IterIdx<'_, T, MrkleNode<T, D, Ix>, Ix> {
696+
pub fn iter_idx(&self) -> IterIdx<'_, MrkleNode<T, D, Ix>, Ix> {
688697
self.core.iter_idx()
689698
}
690699
}
@@ -697,19 +706,40 @@ where
697706
pub fn subtree_from_node(
698707
&self,
699708
target: &MrkleNode<T, D, Ix>,
700-
) -> Option<TreeView<'_, T, MrkleNode<T, D, Ix>, Ix>> {
709+
) -> Option<TreeView<'_, MrkleNode<T, D, Ix>, Ix>> {
701710
self.core.subtree_from_node(target)
702711
}
703712
}
704713

705714
impl<'a, T, D: Digest, Ix: IndexType> IntoIterator for &'a MrkleTree<T, D, Ix> {
706-
type IntoIter = Iter<'a, T, MrkleNode<T, D, Ix>, Ix>;
715+
type IntoIter = Iter<'a, MrkleNode<T, D, Ix>, Ix>;
707716
type Item = &'a MrkleNode<T, D, Ix>;
708717
fn into_iter(self) -> Self::IntoIter {
709718
self.iter()
710719
}
711720
}
712721

722+
impl<T, D: Digest, Ix: IndexType> From<Vec<T>> for MrkleTree<T, D, Ix>
723+
where
724+
T: AsRef<[u8]>,
725+
{
726+
fn from(value: Vec<T>) -> Self {
727+
MrkleTree::from_leaves(value)
728+
}
729+
}
730+
731+
impl<T, D: Digest, Ix: IndexType> Display for MrkleTree<T, D, Ix> {
732+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
733+
write!(f, "{}", self.core)
734+
}
735+
}
736+
737+
impl<T, D: Digest, Ix: IndexType> Debug for MrkleTree<T, D, Ix> {
738+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
739+
write!(f, "{}", self.core)
740+
}
741+
}
742+
713743
#[cfg(test)]
714744
mod test {
715745

@@ -743,15 +773,15 @@ mod test {
743773
}
744774

745775
#[test]
746-
fn test_build_with_mrkel() {
776+
fn test_build_with_mrkle() {
747777
let hasher = MrkleHasher::<sha1::Sha1>::new();
748778
let node = MrkleNode::<_, sha1::Sha1, usize>::leaf_with_hasher(DATA_PAYLOAD, &hasher);
749779

750780
assert_eq!(node.hash, sha1::Sha1::digest(DATA_PAYLOAD))
751781
}
752782

753783
#[test]
754-
fn test_build_internal_mrkel_node() {
784+
fn test_build_internal_mrkle_node() {
755785
let hasher = MrkleHasher::<sha1::Sha1>::new();
756786
let node1 = MrkleNode::<_, sha1::Sha1, usize>::leaf_with_hasher(DATA_PAYLOAD, &hasher);
757787
let node2 = MrkleNode::<_, sha1::Sha1, usize>::leaf_with_hasher(DATA_PAYLOAD, &hasher);
@@ -794,6 +824,7 @@ mod test {
794824
fn test_building_binary_tree_base_case() {
795825
let leaves: Vec<&str> = vec!["A"];
796826
let tree = MrkleTree::<&str, sha1::Sha1>::from_leaves(leaves);
827+
assert!(tree.len() == 2)
797828
}
798829

799830
#[test]
@@ -811,4 +842,12 @@ mod test {
811842
}
812843
}
813844
}
845+
846+
#[test]
847+
#[cfg(feature = "std")]
848+
fn test_building_binary_tree_display() {
849+
let leaves: Vec<&str> = vec!["A", "B", "C", "D", "E"];
850+
let tree = MrkleTree::<&str, sha1::Sha1>::from_leaves(leaves.clone());
851+
println!("{tree}");
852+
}
814853
}

mrkle/src/tree/iter.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ use crate::{IndexType, Node, NodeIndex, TreeView};
1515
///
1616
/// This `struct` is created by the `into_iter` method on [`TreeView`]
1717
/// (provided by the [`IntoIterator`] trait).
18-
pub struct Iter<'a, T, N: Node<Ix>, Ix: IndexType> {
18+
pub struct Iter<'a, N: Node<Ix>, Ix: IndexType> {
1919
/// internal queue for node reterival.
2020
queue: VecDeque<NodeIndex<Ix>>,
2121
/// [`Tree`] reference.
22-
inner: TreeView<'a, T, N, Ix>,
22+
inner: TreeView<'a, N, Ix>,
2323
/// stopping flag initiated after root has been
2424
/// allocated to the queue.
2525
stop: bool,
2626
}
2727

28-
impl<'a, T, N: Node<Ix>, Ix: IndexType> Iter<'a, T, N, Ix> {
29-
pub(crate) fn new(tree: TreeView<'a, T, N, Ix>) -> Self {
28+
impl<'a, N: Node<Ix>, Ix: IndexType> Iter<'a, N, Ix> {
29+
pub(crate) fn new(tree: TreeView<'a, N, Ix>) -> Self {
3030
Self {
3131
queue: VecDeque::from([]),
3232
inner: tree,
@@ -35,7 +35,7 @@ impl<'a, T, N: Node<Ix>, Ix: IndexType> Iter<'a, T, N, Ix> {
3535
}
3636
}
3737

38-
impl<'a, T, N: Node<Ix>, Ix: IndexType> Iterator for Iter<'a, T, N, Ix> {
38+
impl<'a, N: Node<Ix>, Ix: IndexType> Iterator for Iter<'a, N, Ix> {
3939
type Item = &'a N;
4040
fn next(&mut self) -> Option<Self::Item> {
4141
if let Some(index) = &self.queue.pop_front() {
@@ -57,14 +57,14 @@ impl<'a, T, N: Node<Ix>, Ix: IndexType> Iterator for Iter<'a, T, N, Ix> {
5757
}
5858

5959
/// An iterator that moves Nodes Index out of a [`TreeView`].
60-
pub struct IterIdx<'a, T, N: Node<Ix>, Ix: IndexType> {
60+
pub struct IterIdx<'a, N: Node<Ix>, Ix: IndexType> {
6161
queue: VecDeque<NodeIndex<Ix>>,
62-
inner: TreeView<'a, T, N, Ix>,
62+
inner: TreeView<'a, N, Ix>,
6363
stop: bool,
6464
}
6565

66-
impl<'a, T, N: Node<Ix>, Ix: IndexType> IterIdx<'a, T, N, Ix> {
67-
pub(crate) fn new(tree: TreeView<'a, T, N, Ix>) -> Self {
66+
impl<'a, N: Node<Ix>, Ix: IndexType> IterIdx<'a, N, Ix> {
67+
pub(crate) fn new(tree: TreeView<'a, N, Ix>) -> Self {
6868
Self {
6969
queue: VecDeque::from([]),
7070
inner: tree,
@@ -73,7 +73,7 @@ impl<'a, T, N: Node<Ix>, Ix: IndexType> IterIdx<'a, T, N, Ix> {
7373
}
7474
}
7575

76-
impl<T, N: Node<Ix>, Ix: IndexType> Iterator for IterIdx<'_, T, N, Ix> {
76+
impl<N: Node<Ix>, Ix: IndexType> Iterator for IterIdx<'_, N, Ix> {
7777
type Item = NodeIndex<Ix>;
7878
fn next(&mut self) -> Option<Self::Item> {
7979
if let Some(index) = &self.queue.pop_front() {

0 commit comments

Comments
 (0)