summaryrefslogtreecommitdiffstats
path: root/src/node.rs
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2025-06-16 09:49:45 +0000
committerSanto Cariotti <santo@dcariotti.me>2025-06-16 09:49:45 +0000
commitc4eeb0db2219e63801ce566b7724e849c74e0fed (patch)
tree615815dc57a31eb323d49eb8dc41a8e7f22c1b6e /src/node.rs
parent79987ba53f228d27875c6d5e1bb38c76a40e7d0d (diff)
Remove `src/merkle` folder
Diffstat (limited to 'src/node.rs')
-rw-r--r--src/node.rs96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/node.rs b/src/node.rs
new file mode 100644
index 0000000..cef5c1f
--- /dev/null
+++ b/src/node.rs
@@ -0,0 +1,96 @@
+//! Contains node definitions for Merkle trees, including leaf and internal node structures.
+
+use crate::hasher::Hasher;
+
+/// Enum representing the type of a Merkle tree node.
+#[derive(Debug, Clone)]
+pub enum NodeType {
+ /// A leaf node that contains no children.
+ Leaf,
+ /// An internal node that has two children.
+ Internal(Box<Node>, Box<Node>),
+}
+
+impl NodeType {
+ /// Returns a reference to the left child if the node is internal.
+ pub fn left(&self) -> Option<&Node> {
+ match self {
+ NodeType::Leaf => None,
+ NodeType::Internal(l, _) => Some(l),
+ }
+ }
+
+ /// Returns a reference to the right child if the node is internal.
+ pub fn right(&self) -> Option<&Node> {
+ match self {
+ NodeType::Leaf => None,
+ NodeType::Internal(_, r) => Some(r),
+ }
+ }
+}
+
+/// Represents a node in a Merkle tree, either leaf or internal.
+#[derive(Debug, Clone)]
+pub struct Node {
+ /// Hash value stored at the node.
+ hash: String,
+ /// Type of the node: leaf or internal.
+ kind: NodeType,
+ /// Data in bytes.
+ data: Vec<u8>,
+}
+
+impl Node {
+ /// Constructs a new leaf node from input data.
+ ///
+ /// # Arguments
+ ///
+ /// * `hasher` - A reference to a hashing strategy.
+ /// * `data` - The data to be hashed and stored as a leaf.
+ pub fn new_leaf(hasher: &dyn Hasher, data: &[u8]) -> Self {
+ let hash = hasher.hash(data);
+ Self {
+ hash,
+ data: data.to_vec(),
+ kind: NodeType::Leaf,
+ }
+ }
+
+ /// Constructs a new internal node from two child nodes.
+ ///
+ /// # Arguments
+ ///
+ /// * `hasher` - A reference to a hashing strategy.
+ /// * `left` - Left child node.
+ /// * `right` - Right child node.
+ ///
+ /// # Behavior
+ ///
+ /// The internal node hash is computed as the hash of the concatenated children's hashes.
+ pub fn new_internal(hasher: &dyn Hasher, left: Node, right: Node) -> Self {
+ let mut buffer = Vec::<u8>::new();
+ buffer.extend_from_slice(left.hash().as_bytes());
+ buffer.extend_from_slice(right.hash().as_bytes());
+ let hash = hasher.hash(&buffer);
+ Self {
+ hash,
+ data: buffer,
+ kind: NodeType::Internal(Box::new(left), Box::new(right)),
+ }
+ }
+
+ /// Returns a reference to the hash of the node.
+ pub fn hash(&self) -> &str {
+ &self.hash
+ }
+
+ /// Returns the data value in bytes format.
+ pub fn data(&self) -> &[u8] {
+ &self.data
+ }
+
+ /// Returns a reference to the node's type (leaf or internal).
+ pub fn kind(&self) -> &NodeType {
+ &self.kind
+ }
+}