indexed_merkle_tree/tree.rs
1extern crate alloc;
2
3use alloc::string::ToString;
4use alloc::vec;
5use alloc::vec::Vec;
6use num_bigint::BigInt;
7use num_bigint::Sign;
8use serde::{Deserialize, Serialize};
9
10use crate::error::{MerkleTreeError, MerkleTreeResult};
11use crate::node::{InnerNode, LeafNode, Node};
12use crate::{sha256_mod, Hash};
13use anyhow::anyhow;
14
15// `MerkleProof` contains the root hash and a `Vec<Node>>` following the path from the leaf to the root.
16#[derive(Serialize, Deserialize, Debug, Clone)]
17pub struct MerkleProof {
18 // Root hash of the Merkle Tree.
19 pub root_hash: Hash,
20 // Path from the leaf to the root.
21 pub path: Vec<Node>,
22}
23
24// `NonMembershipProof` contains the `MerkleProof` of the node where the returned `missing_node: LeafNode` would be found.
25#[derive(Serialize, Deserialize, Debug, Clone)]
26pub struct NonMembershipProof {
27 // Merkle proof of the node that `missing_node` would be found between `label` and `next`.
28 pub merkle_proof: MerkleProof,
29 // Index of the node that `missing_node` would be found between `label` and `next`.
30 pub closest_index: usize,
31 // Node that would be found in the place of the node proved in `merkle_proof`.
32 pub missing_node: LeafNode,
33}
34
35// `UpdateProof` contains the old `MerkleProof` and the new `MerkleProof` after the update operation
36#[derive(Serialize, Deserialize, Debug, Clone)]
37pub struct UpdateProof {
38 // Merkle proof before the update.
39 pub old_proof: MerkleProof,
40 // Merkle proof after the update.
41 pub new_proof: MerkleProof,
42}
43
44// `InsertProof` contains the non-membership proof of the new `Node` (to guarantee uniqueness), and two `UpdateProof`s.
45#[derive(Serialize, Deserialize, Debug, Clone)]
46pub struct InsertProof {
47 // Non-membership proof of the new node.
48 pub non_membership_proof: NonMembershipProof,
49 // Update proof of the previous node's next pointer.
50 pub first_proof: UpdateProof,
51 // Update proof of the new node.
52 pub second_proof: UpdateProof,
53}
54
55impl NonMembershipProof {
56 /// Verifies the non-membership proof of a node in the indexed Merkle Tree.
57 ///
58 /// This function checks the non-membership proof of a node to ensure that the node is not present in the tree.
59 /// It verifies the proof's path and the absence of the node in the tree.
60 ///
61 /// # Returns
62 /// `true` if the proof is valid and the node is not present, `false` otherwise.
63 pub fn verify(&self) -> bool {
64 if let Some(Node::Leaf(leaf)) = self.merkle_proof.path.first() {
65 let current_label = BigInt::from_bytes_be(Sign::Plus, leaf.label.as_ref());
66 let current_next = BigInt::from_bytes_be(Sign::Plus, leaf.next.as_ref());
67 let new_label = BigInt::from_bytes_be(Sign::Plus, self.missing_node.label.as_ref());
68
69 if self.merkle_proof.verify() && new_label > current_label && new_label < current_next {
70 return true;
71 }
72 }
73 false
74 }
75}
76
77impl InsertProof {
78 /// Verifies the proofs associated with a node insertion in the indexed Merkle Tree.
79 ///
80 /// This function confirms the non-membership of the node before insertion, and then verifies
81 /// the two update proofs representing the tree's state changes due to the insertion. Essential for
82 /// validating insert operations in the tree.
83 ///
84 /// # Returns
85 /// `true` if all proofs are valid, `false` otherwise.
86 pub fn verify(&self) -> bool {
87 self.non_membership_proof.verify()
88 && self.first_proof.verify()
89 && self.second_proof.verify()
90 }
91}
92
93impl UpdateProof {
94 /// Verifies an update proof in the indexed Merkle Tree.
95 ///
96 /// This function checks both the old and new "state" proofs of a node to ensure that the update
97 /// operation has been performed correctly and the tree's integrity is maintained.
98 ///
99 /// # Returns
100 /// `true` if both proofs are valid, `false` otherwise.
101 pub fn verify(&self) -> bool {
102 self.old_proof.verify() && self.new_proof.verify()
103 }
104}
105
106impl MerkleProof {
107 /// Verifies a Merkle proof against a given root hash.
108 ///
109 /// This function takes a Merkle proof and verifies that the hashes in the proof's path, when
110 /// combined in the correct order, match the given root hash. It's critical for ensuring the integrity
111 /// and correctness of proofs in the (indexed) Merkle Tree.
112 ///
113 /// # Returns
114 /// `true` if the proof is valid and matches the root hash, `false` otherwise.
115 pub fn verify(&self) -> bool {
116 match (&self.root_hash, &self.path) {
117 (root, path) if !path.is_empty() => {
118 // Save the first hash as current_hash and skip it in the loop to start with the second
119 let mut current_hash = path[0].get_hash();
120
121 for node in path.iter().skip(1) {
122 let combined = if node.is_left_sibling() {
123 [node.get_hash().as_ref(), current_hash.as_ref()].concat()
124 } else {
125 [current_hash.as_ref(), node.get_hash().as_ref()].concat()
126 };
127 current_hash = sha256_mod(&combined);
128 }
129 ¤t_hash == root
130 }
131 _ => false,
132 }
133 }
134}
135
136/// Represents different Proof variants of an `IndexedMerkleTree`.
137///
138/// Variants:
139/// - `Update(UpdateProof)`: Represents a proof for an update operation.
140/// - `Insert(InsertProof)`: Represents a proof for an insert operation.
141#[derive(Serialize, Deserialize, Debug, Clone)]
142pub enum Proof {
143 Update(UpdateProof),
144 Insert(InsertProof),
145}
146
147/// Represents an indexed merkle tree.
148///
149/// This structure encapsulates a merkle tree where `Node`s are indexed, facilitating efficient
150/// updates and proofs, especially non-membership proofs.
151///
152/// Fields:
153/// - `nodes`: A vector of `Node` elements, representing the nodes of the indexed merkle tree.
154#[derive(Serialize, Deserialize, Clone)]
155pub struct IndexedMerkleTree {
156 pub nodes: Vec<Node>,
157}
158
159#[cfg(feature = "std")]
160impl std::fmt::Display for IndexedMerkleTree {
161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162 if f.alternate() {
163 self.fmt_mermaid(f)
164 } else {
165 self.fmt_tree(f)
166 }
167 }
168}
169
170impl IndexedMerkleTree {
171 /// Creates a new `IndexedMerkleTree` from a given `nodes` vector.
172 ///
173 /// # Arguments
174 /// * `nodes` - A vector of `Node` elements from which the Merkle tree will be built.
175 ///
176 /// # Returns
177 /// A `MerkleTreeResult<Self>` representing the initialized tree or an error.
178 pub fn new(nodes: Vec<Node>) -> MerkleTreeResult<Self> {
179 // TODO(@distractedm1nd): Issue #3
180 let parsed_nodes = set_left_sibling_status_for_nodes(nodes);
181
182 let mut tree = Self {
183 nodes: parsed_nodes,
184 };
185 tree.calculate_root()?;
186 Ok(tree)
187 }
188
189 /// Creates a new `IndexedMerkleTree` of a given size
190 ///
191 /// # Arguments
192 /// * `size` - The number of nodes in the tree.
193 ///
194 /// # Returns
195 /// A `MerkleTreeResult<Self>` representing the initialized tree or an error.
196 pub fn new_with_size(size: usize) -> MerkleTreeResult<Self> {
197 let mut nodes: Vec<Node> = Vec::with_capacity(2 * size + 1);
198 let empty_hash = Node::HEAD;
199 let tail = Node::TAIL;
200
201 let active_node = Node::new_leaf(true, empty_hash, empty_hash, tail);
202 nodes.push(active_node);
203
204 let left_inactive_node = Node::new_leaf(true, empty_hash, empty_hash, empty_hash);
205 let right_inactive_node = Node::new_leaf(false, empty_hash, empty_hash, empty_hash);
206
207 let alternates = vec![left_inactive_node, right_inactive_node]
208 .into_iter()
209 .cycle();
210
211 nodes.extend(alternates.take(size - 1)); // 'size - 1' because one node is already pushed.
212
213 IndexedMerkleTree::new(nodes)
214 }
215
216 /// Recursively creates the inner nodes to the root of the indexed merkle tree from the passed nodes.
217 ///
218 /// When called, this function expects the passed nodes to be leaf nodes.
219 /// It assumes these are the only nodes present in `self.nodes`.
220 fn rehash_inner_nodes(&mut self, current_layer: Vec<Node>) {
221 for (index, node) in current_layer.chunks(2).enumerate() {
222 let new_node = Node::Inner(InnerNode::new(node[0].clone(), node[1].clone(), index));
223 self.nodes.push(new_node);
224 }
225
226 let remaining = current_layer.len() / 2;
227 if remaining > 1 {
228 self.rehash_inner_nodes(self.nodes[self.nodes.len() - remaining..].to_vec());
229 }
230 }
231
232 /// Rehashes the inner nodes of the indexed merkle tree from the existing leaf nodes.
233 ///
234 /// This is done when first initializing the tree, as well as when nodes are updated.
235 fn rebuild_tree_from_leaves(&mut self) {
236 self.nodes.retain(|node| matches!(node, Node::Leaf(_)));
237 self.rehash_inner_nodes(self.nodes.clone());
238 }
239
240 /// Calculates the root of an IndexedMerkleTree by aggregating the tree's nodes.
241 ///
242 /// The function performs the followig (main) steps:
243 /// 1. Extracts all the leaf nodes from the tree.
244 /// 2. Resets the tree's nodes to the extracted leaves.
245 /// 3. Iteratively constructs parent nodes from pairs of child nodes until there is only one node left (the root).
246 ///
247 /// # Arguments
248 ///
249 /// * `self` - The mutable reference to the IndexedMerkleTree instance.
250 ///
251 /// # Returns
252 ///
253 /// * `Result<(), MerkleTreeError>` - A result indicating the success or failure of the operation.
254 fn calculate_root(&mut self) -> MerkleTreeResult<()> {
255 // self.rebuild_tree_from_leaves();
256 self.rebuild_tree_from_leaves();
257
258 // set root not as left sibling
259 let root = self
260 .nodes
261 .last_mut()
262 .ok_or(anyhow!(MerkleTreeError::EmptyMerkleTreeError))?; // TODO: are there possible other Errors? is it possible at all to have an empty tree at this point?
263 root.set_left_sibling_value(false);
264
265 Ok(())
266 }
267
268 /// # Returns
269 ///
270 /// The current root node of the Indexed Merkle tree.
271 pub fn get_root(&self) -> MerkleTreeResult<&Node> {
272 self.nodes
273 .last()
274 .ok_or(anyhow!(MerkleTreeError::EmptyMerkleTreeError))
275 }
276
277 /// # Returns
278 ///
279 /// The current commitment (hash of the root node) of the Indexed Merkle tree.
280 pub fn get_commitment(&self) -> MerkleTreeResult<Hash> {
281 Ok(self.get_root()?.get_hash())
282 }
283
284 /// Finds the index of a specific node in the indexed Merkle Tree.
285 ///
286 /// This function searches through the tree's nodes to find the index of a given node.
287 /// It compares leaf nodes by label and inner nodes by hash. The function returns the node's
288 /// index if found, or `None` if the node is not present in the tree.
289 ///
290 /// # Arguments
291 /// * `node` - A reference to the `Node` whose index is being searched for.
292 ///
293 /// # Returns
294 /// An `Option<usize>` indicating the index of the node if found.
295 // TODO: is it better to return a Result here and in the next function?
296 pub fn find_node_index(&self, node: &Node) -> Option<usize> {
297 self.nodes
298 .iter()
299 .enumerate()
300 .find_map(|(index, current_node)| match (current_node, node) {
301 (Node::Leaf(current_leaf), Node::Leaf(leaf)) => {
302 if current_leaf.label == leaf.label {
303 Some(index)
304 } else {
305 None
306 }
307 }
308 (Node::Inner(current_inner), Node::Inner(inner)) => {
309 if current_inner.hash == inner.hash {
310 Some(index)
311 } else {
312 None
313 }
314 }
315 _ => None,
316 })
317 }
318
319 /// Searches for a leaf node by its label in the indexed Merkle Tree.
320 ///
321 /// This function iterates through the tree's nodes to find a leaf node that matches the given label.
322 /// If a matching leaf is found, it is returned, otherwise the function returns `None`.
323 ///
324 /// # Arguments
325 /// * `label` - A reference to the string label of the leaf node to find.
326 ///
327 /// # Returns
328 /// An `Option<Node>` representing the found leaf node, if any.
329 ///
330 pub fn find_leaf_by_label(&self, label: &Hash) -> Option<Node> {
331 self.nodes.iter().find_map(|node| match node {
332 Node::Leaf(leaf) if &leaf.label == label => Some(node.clone()),
333 _ => None,
334 })
335 }
336
337 /// Doubles the size of the Merkle Tree.
338 ///
339 /// This function adds as many new inactive nodes to the tree as it currently contains,
340 /// effectively doubling its size. This is necessary when no inactive node is available for
341 /// the insertion of a new node. Each new node is marked inactive and initialized with
342 /// default values.
343 pub fn double_tree_size(&mut self) {
344 let current_size = self.nodes.len();
345 self.nodes.resize(current_size * 2 + 1, Node::default());
346 // update sibling status
347 let new_nodes = set_left_sibling_status_for_nodes(self.nodes.clone());
348 self.nodes = new_nodes;
349 }
350
351 /// Generates a membership proof for a node at a given index in the indexed merkle tree.
352 ///
353 /// This function constructs a path of hashes leading from a specific node to the root of the tree,
354 /// serving as a merkle proof of the node's membership in the tree. If the index is invalid,
355 /// it returns an error, because the node doesnt exist and cant be proved as a member.
356 ///
357 /// # Arguments
358 /// * `index` - The index of the node in the tree for which the proof is to be generated.
359 ///
360 /// # Returns
361 /// A `Result<MerkleProof, MerkleTreeError>` containing the membership proof or an error.
362 pub fn generate_membership_proof(&self, index: usize) -> MerkleTreeResult<MerkleProof> {
363 // if the index is outside of the valid range of the tree, there is no proof
364 if index >= self.nodes.len() {
365 return Err(anyhow!(MerkleTreeError::IndexError(index.to_string())));
366 }
367
368 let mut proof_path: Vec<Node> = Vec::new();
369 let mut current_index = index;
370
371 let leaf_node = self.nodes[current_index].clone();
372 proof_path.push(leaf_node);
373
374 // climb the tree until we reach the root and add each parent node sibling of the current node to the proof list
375 while current_index < self.nodes.len() - 1 {
376 // if the current node is divisible by 2, it is a left node, then the sibling is right (index + 1) and vice versa
377 let sibling_index = if current_index % 2 == 0 {
378 current_index + 1
379 } else {
380 current_index - 1
381 };
382 let sibling_node = self.nodes[sibling_index].clone();
383 proof_path.push(sibling_node);
384 // we have to round up, because if there are e.g. 15 elements (8 leaves) the parent of index 0 would be 7 (or 7.5)
385 // but the actual parent of index 0 is 8
386 current_index =
387 ((current_index as f64 + self.nodes.len() as f64) / 2.0).ceil() as usize;
388 }
389
390 Ok(MerkleProof {
391 root_hash: self.get_commitment()?,
392 path: proof_path,
393 })
394 }
395
396 /// Generates a non-membership proof for a given node in the indexed merkle tree.
397 ///
398 /// This function verifies that a node is not part of the tree. It does so by finding a place in the
399 /// tree where the given node *should* exist based on its label and proving it is not there. Suitable
400 /// for scenarios where proving the absence of data is required, e.g. important for guaranteeing uniqueness.
401 ///
402 /// # Arguments
403 /// * `node` - A reference to the `Node` for which the non-membership proof is required.
404 ///
405 /// # Returns
406 /// A `MerkleTreeResult<NonMembershipProof>` containing the non-membership proof and
407 /// the index of the "closest" valid node, or an error.
408 pub fn generate_non_membership_proof(
409 &self,
410 node: &Node,
411 ) -> MerkleTreeResult<NonMembershipProof> {
412 let given_node_as_leaf = match node {
413 Node::Leaf(leaf) => leaf,
414 _ => return Err(anyhow!(MerkleTreeError::NotFoundError("Leaf".to_string()))),
415 };
416
417 let mut found_index = None;
418 for (index, current_node) in self.nodes.iter().enumerate() {
419 if let Node::Leaf(current_leaf) = current_node {
420 let current_label = BigInt::from_bytes_be(Sign::Plus, current_leaf.label.as_ref());
421 let current_next = BigInt::from_bytes_be(Sign::Plus, current_leaf.next.as_ref());
422 let new_label =
423 BigInt::from_bytes_be(Sign::Plus, given_node_as_leaf.label.as_ref());
424
425 if current_label < new_label && new_label < current_next {
426 found_index = Some(index);
427 break;
428 }
429 }
430 }
431
432 match found_index {
433 Some(_) => Ok(NonMembershipProof {
434 merkle_proof: self.generate_membership_proof(found_index.unwrap())?,
435 closest_index: found_index.unwrap(),
436 missing_node: given_node_as_leaf.clone(),
437 }),
438 None => Err(anyhow!(MerkleTreeError::MerkleProofError)),
439 }
440 }
441
442 /// Updates the node with the given index in the merkle tree, returning the update proof.
443 ///
444 /// This function first generates a proof of membership for the old node state, updates the node,
445 /// recalculates the root, and then generates a new proof of membership for the updated node. It returns
446 /// both the old and new proofs along with the updated tree.
447 ///
448 /// # Arguments
449 /// * `index` - The index of the node to be updated.
450 /// * `new_node` - The new state of the node.
451 ///
452 /// # Returns
453 /// A `MerkleTreeResult<UpdateProof, MerkleTreeError>` containing the the old root, the old proof, the new root and the new proof.
454 pub fn update_node(&mut self, index: usize, new_node: Node) -> MerkleTreeResult<UpdateProof> {
455 // generate old proof
456 let old_proof = self.generate_membership_proof(index)?;
457
458 // update node and calculate new root
459 self.nodes[index] = new_node;
460 self.calculate_root()?;
461
462 // generate new proof
463 let new_proof = self.generate_membership_proof(index)?;
464
465 // return old and new proof
466 Ok(UpdateProof {
467 old_proof,
468 new_proof,
469 })
470 }
471
472 /// Inserts a node into the merkle tree, returning the insertion proof.
473 ///
474 /// This function starts with a non-membership check to ensure that the index (i.e. the label) does not yet exist in the tree
475 /// and thus to determine the index of the node to be changed.
476 /// It then generates two update proofs: one for updating the next pointer of the existing node, and another
477 /// for the actual insertion of the new node, i.e. updating an inactive and therefore empty leaf node.
478 /// If there are no more empty leaf nodes, the capacity in the tree is doubled.
479 ///
480 /// # Arguments
481 /// * `new_node` - The new node to be inserted.
482 ///
483 /// # Returns
484 /// A `MerkleTreeResult<InsertProof>` containing the non-membership proof and two update proofs.
485 pub fn insert_node(&mut self, new_node: &mut Node) -> MerkleTreeResult<InsertProof> {
486 // perform non-membership check in order to return the index of the node to be changed
487 let non_membership_proof = self.generate_non_membership_proof(new_node)?;
488
489 if non_membership_proof.merkle_proof.path.first().is_none() {
490 return Err(anyhow!(MerkleTreeError::MerkleProofError));
491 }
492
493 // generate first update proof, changing only the next pointer from the old node
494 let mut new_old_node = self.nodes[non_membership_proof.closest_index].clone();
495
496 // set the next pointer of the new node to the next pointer of the old node
497 new_node.set_next(new_old_node.get_next());
498
499 Node::update_next_pointer(&mut new_old_node, new_node);
500 new_old_node.generate_hash();
501 let first_proof =
502 self.update_node(non_membership_proof.closest_index, new_old_node.clone())?;
503
504 // we checked if the found index in the non-membership is from an incative node, if not we have to search for another inactive node to update and if we cant find one, we have to double the tree
505 let mut new_index = None;
506 for (i, node) in self.nodes.iter().enumerate() {
507 if !node.is_active() {
508 new_index = Some(i);
509 break;
510 }
511 }
512
513 let new_index = match new_index {
514 Some(index) => index,
515 None => {
516 // double the tree
517 self.double_tree_size();
518 // take the first inactive node
519 self.nodes
520 .iter_mut()
521 .enumerate()
522 .find(|(_, node)| !node.is_active())
523 .map(|(i, _)| i)
524 .expect("New inactive node not found after doubling the tree.")
525 }
526 };
527
528 // set the sibling status of the new node
529 new_node.set_left_sibling_value(new_index % 2 == 0);
530 new_node.generate_hash();
531
532 // generate second update proof
533 let second_proof = self.update_node(new_index, new_node.clone())?;
534
535 Ok(InsertProof {
536 non_membership_proof,
537 first_proof,
538 second_proof,
539 })
540 }
541
542 #[cfg(feature = "std")]
543 fn fmt_tree(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
544 fn write_node(
545 f: &mut std::fmt::Formatter<'_>,
546 node: &Node,
547 _depth: usize,
548 is_last: bool,
549 prefix: &str,
550 ) -> std::fmt::Result {
551 let indent = if is_last { "└── " } else { "├── " };
552 let node_prefix = format!("{}{}", prefix, indent);
553
554 match node {
555 Node::Inner(inner) => {
556 writeln!(f, "{}Inner Node (Hash: {})", node_prefix, inner.hash)?;
557 let new_prefix = format!("{}{} ", prefix, if is_last { " " } else { "│" });
558 write_node(f, &inner.left, _depth + 1, false, &new_prefix)?;
559 write_node(f, &inner.right, _depth + 1, true, &new_prefix)?;
560 }
561 Node::Leaf(leaf) => {
562 writeln!(
563 f,
564 "{}Leaf Node (Hash: {}, Active: {}, Label: {}, Value: {}, Next: {})",
565 node_prefix,
566 leaf.hash,
567 leaf.is_active(),
568 leaf.label,
569 leaf.value,
570 leaf.next
571 )?;
572 }
573 }
574 Ok(())
575 }
576
577 writeln!(f, "Indexed Merkle Tree:")?;
578 if let Some(root) = self.nodes.last() {
579 write_node(f, root, 0, true, "")?;
580 } else {
581 writeln!(f, "(Empty Tree)")?;
582 }
583 Ok(())
584 }
585
586 #[cfg(feature = "std")]
587 fn fmt_mermaid(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
588 writeln!(f, "graph TD")?;
589
590 let mut node_id = 0;
591
592 fn write_node(
593 f: &mut std::fmt::Formatter<'_>,
594 node: &Node,
595 parent_id: Option<usize>,
596 node_id: &mut usize,
597 ) -> std::fmt::Result {
598 let current_id = *node_id;
599 *node_id += 1;
600
601 match node {
602 Node::Inner(inner) => {
603 writeln!(
604 f,
605 " N{current_id}[Inner {:.6}]",
606 &inner.hash.to_string()[..8]
607 )?;
608 if let Some(pid) = parent_id {
609 writeln!(f, " N{pid} --> N{current_id}")?;
610 }
611 write_node(f, &inner.left, Some(current_id), node_id)?;
612 write_node(f, &inner.right, Some(current_id), node_id)?;
613 }
614 Node::Leaf(leaf) => {
615 writeln!(
616 f,
617 " N{current_id}[Hash: n{:.6}...\\nNext: {:.6}...\\nLabel: {:.6}...\\nValue: {:.6}...\\n]",
618 &leaf.hash.to_string()[..8], &leaf.next.to_string()[..8], &leaf.label.to_string()[..8], &leaf.value.to_string()[..8]
619 )?;
620 if let Some(pid) = parent_id {
621 writeln!(f, " N{pid} --> N{current_id}")?;
622 }
623 }
624 }
625 Ok(())
626 }
627
628 if let Some(root) = self.nodes.last() {
629 write_node(f, root, None, &mut node_id)?;
630 } else {
631 writeln!(f, " N0[Empty Tree]")?;
632 }
633
634 // Add styling
635 writeln!(
636 f,
637 " classDef inner fill:#87CEFA,stroke:#4682B4,stroke-width:2px,color:black;"
638 )?;
639 writeln!(
640 f,
641 " classDef active fill:#98FB98,stroke:#006400,stroke-width:2px,color:black;"
642 )?;
643 writeln!(
644 f,
645 " classDef inactive fill:#FFA07A,stroke:#8B0000,stroke-width:2px,color:black;"
646 )?;
647 writeln!(f, " class N0 inner;")?;
648 for i in 1..node_id {
649 writeln!(
650 f,
651 " class N{} {};",
652 i,
653 if i < self.nodes.len() / 2 {
654 "inner"
655 } else if self.nodes[i].is_active() {
656 "active"
657 } else {
658 "inactive"
659 }
660 )?;
661 }
662
663 Ok(())
664 }
665}
666
667/// Updates the position attributes of nodes in a vector.
668///
669/// This function iterates over a vector of nodes, updating each node's left sibling status
670/// based on its index. It's crucial for correctly setting up the structural properties of the nodes
671/// in the tree, especially after modifications that might alter the node order.
672///
673/// # Arguments
674/// * `nodes` - A vector of `Node` elements to update.
675///
676/// # Returns
677/// A `Vec<Node>` with updated left sibling status for each node.
678pub fn set_left_sibling_status_for_nodes(nodes: Vec<Node>) -> Vec<Node> {
679 let new: Vec<Node> = nodes
680 .into_iter()
681 .enumerate()
682 .map(|(i, mut node)| {
683 let is_left_sibling = i % 2 == 0;
684 node.set_left_sibling_value(is_left_sibling);
685 node
686 })
687 .collect();
688 new
689}
690
691/// Resorts based on a specified input order.
692///
693/// This function rearranges a given vector of nodes to match an input order defined by a vector of labels.
694/// It filters out inner nodes and so it sorts only leaf nodes based on their label's position in the input vector.
695///
696/// # Arguments
697/// * `nodes` - A vector of `Node` elements to be sorted.
698/// * `input_order` - A vector of strings representing the desired order of leaf labels.
699///
700/// # Returns
701/// A `MerkleTreeResult<Vec<Node>>` representing the sorted nodes or an error.
702pub fn resort_nodes_by_input_order(
703 nodes: Vec<Node>,
704 input_order: Vec<Hash>,
705) -> MerkleTreeResult<Vec<Node>> {
706 let valid_nodes: Vec<_> = nodes
707 .into_iter()
708 .filter_map(|node| {
709 let label = match &node {
710 Node::Inner(_) => None,
711 Node::Leaf(leaf) => Some(leaf.label),
712 };
713
714 label.and_then(|l| {
715 input_order
716 .iter()
717 .position(|k| k == &l)
718 .map(|index| (index, node))
719 })
720 })
721 .collect();
722
723 let mut sorted_nodes = valid_nodes;
724 sorted_nodes.sort_by_key(|(index, _)| *index); // sort by the index
725 let sorted_nodes = sorted_nodes.into_iter().map(|(_, node)| node).collect(); // remove the index from the tuple, we want the list of nodes
726
727 Ok(sorted_nodes)
728}
729
730#[cfg(test)]
731mod tests {
732 use super::*;
733 use crate::node::Node;
734
735 fn create_test_hash(value: u8) -> Hash {
736 Hash::new([value; 32])
737 }
738
739 #[test]
740 fn test_new_indexed_merkle_tree() {
741 let nodes = vec![
742 Node::new_leaf(
743 true,
744 create_test_hash(1),
745 create_test_hash(2),
746 create_test_hash(3),
747 ),
748 Node::new_leaf(
749 false,
750 create_test_hash(4),
751 create_test_hash(5),
752 create_test_hash(6),
753 ),
754 ];
755 let tree = IndexedMerkleTree::new(nodes).unwrap();
756 assert_eq!(tree.nodes.len(), 3); // 2 leaf nodes + 1 root node
757 }
758
759 #[test]
760 fn test_new_with_size() {
761 let tree = IndexedMerkleTree::new_with_size(4).unwrap();
762 assert_eq!(tree.nodes.len(), 7); // 4 leaf nodes + 3 inner nodes
763 }
764
765 #[test]
766 fn test_get_root() {
767 let tree = IndexedMerkleTree::new_with_size(4).unwrap();
768 let root = tree.get_root().unwrap();
769 assert!(matches!(root, Node::Inner(_)));
770 }
771
772 #[test]
773 fn test_get_commitment() {
774 let tree = IndexedMerkleTree::new_with_size(4).unwrap();
775 let commitment = tree.get_commitment().unwrap();
776 assert_eq!(commitment.as_ref().len(), 32);
777 }
778
779 #[test]
780 fn test_find_node_index() {
781 let mut tree = IndexedMerkleTree::new_with_size(4).unwrap();
782 let new_leaf = Node::new_leaf(
783 true,
784 create_test_hash(1),
785 create_test_hash(2),
786 create_test_hash(3),
787 );
788 tree.nodes[0] = new_leaf.clone();
789 assert_eq!(tree.find_node_index(&new_leaf), Some(0));
790 }
791
792 #[test]
793 fn test_find_leaf_by_label() {
794 let mut tree = IndexedMerkleTree::new_with_size(4).unwrap();
795 let label = create_test_hash(1);
796 let new_leaf = Node::new_leaf(true, label, create_test_hash(2), create_test_hash(3));
797 tree.nodes[0] = new_leaf.clone();
798 assert_eq!(tree.find_leaf_by_label(&label), Some(new_leaf));
799 }
800
801 #[test]
802 fn test_double_tree_size() {
803 let mut tree = IndexedMerkleTree::new_with_size(4).unwrap();
804 let original_size = tree.nodes.len();
805 tree.double_tree_size();
806 assert_eq!(tree.nodes.len(), original_size * 2 + 1);
807 }
808
809 #[test]
810 fn test_generate_membership_proof() {
811 let mut tree = IndexedMerkleTree::new_with_size(4).unwrap();
812 let new_leaf = Node::new_leaf(
813 true,
814 create_test_hash(1),
815 create_test_hash(2),
816 create_test_hash(3),
817 );
818 tree.nodes[0] = new_leaf;
819 let proof = tree.generate_membership_proof(0).unwrap();
820 assert_eq!(proof.path.len(), 3); // leaf + 2 inner nodes
821 }
822
823 #[test]
824 fn test_generate_non_membership_proof() {
825 let mut tree = IndexedMerkleTree::new_with_size(4).unwrap();
826 let mut existing_leaf = Node::new_leaf(
827 true,
828 create_test_hash(1),
829 create_test_hash(2),
830 create_test_hash(3),
831 );
832 let insert_proof = tree.insert_node(&mut existing_leaf);
833 assert!(insert_proof.is_ok());
834
835 let non_existent_leaf = Node::new_leaf(
836 true,
837 create_test_hash(4),
838 create_test_hash(5),
839 create_test_hash(6),
840 );
841
842 let proof = tree
843 .generate_non_membership_proof(&non_existent_leaf)
844 .unwrap();
845
846 assert_eq!(proof.closest_index, 1);
847 }
848
849 #[test]
850 fn test_update_node() {
851 let mut tree = IndexedMerkleTree::new_with_size(4).unwrap();
852 let original_leaf = Node::new_leaf(
853 true,
854 create_test_hash(1),
855 create_test_hash(2),
856 create_test_hash(3),
857 );
858 tree.nodes[0] = original_leaf.clone();
859 let new_leaf = Node::new_leaf(
860 true,
861 create_test_hash(4),
862 create_test_hash(5),
863 create_test_hash(6),
864 );
865 let update_proof = tree.update_node(0, new_leaf.clone()).unwrap();
866 assert_eq!(tree.nodes[0], new_leaf);
867 assert!(update_proof.old_proof.path[0] == original_leaf);
868 assert!(update_proof.new_proof.path[0] == new_leaf);
869 }
870
871 #[test]
872 fn test_insert_node() {
873 let mut tree = IndexedMerkleTree::new_with_size(4).unwrap();
874 let mut new_leaf = Node::new_leaf(
875 true,
876 create_test_hash(1),
877 create_test_hash(2),
878 create_test_hash(3),
879 );
880 let insert_proof = tree.insert_node(&mut new_leaf).unwrap();
881 assert!(tree.nodes.iter().any(|node| node == &new_leaf));
882 assert_eq!(
883 insert_proof.non_membership_proof.missing_node.label,
884 new_leaf.get_label()
885 );
886 }
887}