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                &current_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}