ex3_merkle/
merkle_tree.rs

1use crate::prelude::*;
2use crate::{partial_tree::PartialTree, utils, utils::indices, Hasher, MerkleProof};
3
4/// [`MerkleTree`] is a Merkle Tree that is well suited for both basic and advanced usage.
5///
6/// Basic features include the creation and verification of Merkle proofs from a set of leaves.
7/// This is often done in various cryptocurrencies.
8///
9/// Advanced features include being able to make transactional changes to a tree with being able to
10/// roll back to any previously committed state of the tree. This scenario is similar to Git and
11/// can be found in databases and file systems.
12#[derive(Clone)]
13pub struct MerkleTree<T: Hasher> {
14    current_working_tree: PartialTree<T>,
15    history: Vec<PartialTree<T>>,
16    uncommitted_leaves: Vec<T::Hash>,
17}
18
19impl<T: Hasher> Default for MerkleTree<T> {
20    fn default() -> Self {
21        Self::new()
22    }
23}
24
25impl<T: Hasher> MerkleTree<T> {
26    /// Creates a new instance of Merkle Tree. Requires a hash algorithm to be specified.
27    ///
28    /// # Examples
29    ///
30    /// ```
31    /// use rs_merkle::{MerkleTree, algorithms::Sha256};
32    ///
33    /// let merkle_tree: MerkleTree<Sha256> = MerkleTree::new();
34    ///
35    /// let another_merkle_tree = MerkleTree::<Sha256>::new();
36    /// ```
37    pub fn new() -> Self {
38        Self {
39            current_working_tree: PartialTree::new(),
40            history: Vec::new(),
41            uncommitted_leaves: Vec::new(),
42        }
43    }
44
45    /// Clones the leaves and builds the tree from them
46    ///
47    /// ## Examples
48    ///
49    /// ```
50    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
51    /// # use std::convert::TryFrom;
52    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
53    /// let leaves = [
54    ///     Sha256::hash("a".as_bytes()),
55    ///     Sha256::hash("b".as_bytes()),
56    ///     Sha256::hash("c".as_bytes()),
57    /// ];
58    ///
59    /// let merkle_tree = MerkleTree::<Sha256>::from_leaves(&leaves);
60    /// # Ok(())
61    /// # }
62    pub fn from_leaves(leaves: &[T::Hash]) -> Self {
63        let mut tree = Self::new();
64        tree.append(leaves.to_vec().as_mut());
65        tree.commit();
66        tree
67    }
68
69    /// Returns the tree root - the top hash of the tree. Used in the inclusion proof verification.
70    ///
71    /// ## Examples
72    ///
73    /// ```
74    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
75    /// # use std::convert::TryFrom;
76    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
77    /// let leaves = [
78    ///     Sha256::hash("a".as_bytes()),
79    ///     Sha256::hash("b".as_bytes()),
80    ///     Sha256::hash("c".as_bytes()),
81    /// ];
82    ///
83    /// let merkle_tree = MerkleTree::<Sha256>::from_leaves(&leaves);
84    ///
85    /// let indices_to_prove = vec![0, 1];
86    /// let leaves_to_prove = leaves.get(0..2).ok_or("can't get leaves to prove")?;
87    ///
88    /// let proof = merkle_tree.proof(&indices_to_prove);
89    /// let root = merkle_tree.root().ok_or("couldn't get the merkle root")?;
90    ///
91    /// assert!(proof.verify(root, &indices_to_prove, leaves_to_prove, leaves.len()));
92    /// # Ok(())
93    /// # }
94    /// ```
95    pub fn root(&self) -> Option<T::Hash> {
96        Some(self.layer_tuples().last()?.first()?.1)
97    }
98
99    /// Similar to [`MerkleTree::root`], but returns a hex encoded string instead of
100    /// [`Hasher::Hash`].
101    ///
102    /// ## Examples
103    ///
104    /// ```
105    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
106    /// # use std::convert::TryFrom;
107    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
108    /// let leaves = [
109    ///     Sha256::hash("a".as_bytes()),
110    ///     Sha256::hash("b".as_bytes()),
111    ///     Sha256::hash("c".as_bytes()),
112    /// ];
113    ///
114    /// let merkle_tree = MerkleTree::<Sha256>::from_leaves(&leaves);
115    /// let root = merkle_tree.root_hex().ok_or("couldn't get the merkle root")?;
116    ///
117    /// assert_eq!(
118    ///     root,
119    ///     "7075152d03a5cd92104887b476862778ec0c87be5c2fa1c0a90f87c49fad6eff".to_string()
120    /// );
121    /// # Ok(())
122    /// # }
123    /// ```
124    pub fn root_hex(&self) -> Option<String> {
125        let root = self.root()?;
126        Some(utils::collections::to_hex_string(&root))
127    }
128
129    /// Returns helper nodes required to build a partial tree for the given indices
130    /// to be able to extract a root from it. Useful in constructing Merkle proofs
131    fn helper_nodes(&self, leaf_indices: &[usize]) -> Vec<T::Hash> {
132        let mut helper_nodes = Vec::<T::Hash>::new();
133
134        for layer in self.helper_node_tuples(leaf_indices) {
135            for (_index, hash) in layer {
136                helper_nodes.push(hash)
137            }
138        }
139
140        helper_nodes
141    }
142
143    /// Gets all helper nodes required to build a partial merkle tree for the given indices,
144    /// cloning all required hashes into the resulting vector.
145    fn helper_node_tuples(&self, leaf_indices: &[usize]) -> Vec<Vec<(usize, T::Hash)>> {
146        let mut current_layer_indices = leaf_indices.to_vec();
147        let mut helper_nodes: Vec<Vec<(usize, T::Hash)>> = Vec::new();
148
149        for tree_layer in self.layer_tuples() {
150            let mut helpers_layer = Vec::new();
151            let siblings = utils::indices::sibling_indices(&current_layer_indices);
152            // Filter all nodes that do not require an additional hash to be calculated
153            let helper_indices = utils::collections::difference(&siblings, &current_layer_indices);
154
155            for index in helper_indices {
156                if let Some(tuple) = tree_layer.get(index) {
157                    helpers_layer.push(*tuple);
158                }
159            }
160
161            helper_nodes.push(helpers_layer);
162            current_layer_indices = indices::parent_indices(&current_layer_indices);
163        }
164
165        helper_nodes
166    }
167
168    /// Returns the Merkle proof required to prove the inclusion of items in a data set.
169    ///
170    /// ## Examples
171    ///
172    /// ```
173    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
174    /// # use std::convert::TryFrom;
175    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
176    /// let leaves: Vec<[u8; 32]> = ["a", "b", "c", "d", "e", "f"]
177    ///     .iter()
178    ///     .map(|x| Sha256::hash(x.as_bytes()))
179    ///     .collect();
180    ///
181    /// let merkle_tree = MerkleTree::<Sha256>::from_leaves(&leaves);
182    /// let indices_to_prove = vec![3, 4];
183    /// let leaves_to_prove = leaves.get(3..5).ok_or("can't get leaves to prove")?;
184    /// let merkle_proof = merkle_tree.proof(&indices_to_prove);
185    /// let merkle_root = merkle_tree.root().ok_or("couldn't get the merkle root")?;
186    /// // Serialize proof to pass it to the client
187    /// let proof_bytes = merkle_proof.to_bytes();
188    ///
189    /// // Parse proof back on the client
190    /// let proof = MerkleProof::<Sha256>::try_from(proof_bytes)?;
191    ///
192    /// assert!(proof.verify(merkle_root, &indices_to_prove, leaves_to_prove, leaves.len()));
193    /// # Ok(())
194    /// # }
195    /// ```
196    pub fn proof(&self, leaf_indices: &[usize]) -> MerkleProof<T> {
197        MerkleProof::<T>::new(self.helper_nodes(leaf_indices))
198    }
199
200    /// Inserts a new leaf. Please note it won't modify the root just yet; For the changes
201    /// to be applied to the root, [`MerkleTree::commit`] method should be called first. To get the
202    /// root of the new tree without applying the changes, you can use
203    /// [`MerkleTree::uncommitted_root`]
204    ///
205    /// # Examples
206    ///
207    /// Get the root after an insert:
208    ///
209    /// ```
210    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
211    /// # use std::convert::TryFrom;
212    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
213    /// let mut merkle_tree = MerkleTree::<Sha256>::new();
214    /// merkle_tree.insert(Sha256::hash("a".as_bytes()));
215    ///
216    /// assert_eq!(merkle_tree.root(), None);
217    ///
218    /// merkle_tree.commit();
219    /// assert_eq!(
220    ///     merkle_tree.root_hex(),
221    ///     Some("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb".to_string())
222    /// );
223    /// # Ok(())
224    /// # }
225    /// ```
226    ///
227    /// Inserts also can be chained with [`MerkleTree::commit`] for convenience:
228    ///
229    /// ```
230    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
231    /// # use std::convert::TryFrom;
232    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
233    /// let mut merkle_tree = MerkleTree::<Sha256>::new();
234    /// merkle_tree
235    ///     .insert(Sha256::hash("a".as_bytes()))
236    ///     .commit();
237    ///
238    /// assert_eq!(
239    ///     merkle_tree.root_hex(),
240    ///     Some("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb".to_string())
241    /// );
242    /// # Ok(())
243    /// # }
244    /// ```
245    pub fn insert(&mut self, leaf: T::Hash) -> &mut Self {
246        self.uncommitted_leaves.push(leaf);
247        self
248    }
249
250    /// Appends leaves to the tree. Behaves similarly to [`MerkleTree::insert`], but for a list of
251    /// items. Takes ownership of the elements of the [`std::vec::Vec<T>`],
252    /// similarly to [`std::vec::Vec::append`].
253    ///
254    /// ## Examples
255    ///
256    /// ```
257    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
258    /// # use std::convert::TryFrom;
259    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
260    /// let mut merkle_tree = MerkleTree::<Sha256>::new();
261    /// let mut leaves = vec![
262    ///     Sha256::hash("a".as_bytes()),
263    ///     Sha256::hash("b".as_bytes()),
264    /// ];
265    /// merkle_tree
266    ///     .append(&mut leaves)
267    ///     .commit();
268    ///
269    /// assert_eq!(
270    ///     merkle_tree.root_hex(),
271    ///     Some("e5a01fee14e0ed5c48714f22180f25ad8365b53f9779f79dc4a3d7e93963f94a".to_string())
272    /// );
273    /// # Ok(())
274    /// # }
275    /// ```
276    pub fn append(&mut self, leaves: &mut Vec<T::Hash>) -> &mut Self {
277        self.uncommitted_leaves.append(leaves);
278        self
279    }
280
281    /// Commits the changes made by [`MerkleTree::insert`] and [`MerkleTree::append`]
282    /// and modifies the root.
283    /// Commits are saved to the history, so the tree can be rolled back to any previous commit
284    /// using [`MerkleTree::rollback`]
285    ///
286    /// ## Examples
287    ///
288    /// ```
289    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
290    /// # use std::convert::TryFrom;
291    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
292    /// let mut merkle_tree = MerkleTree::<Sha256>::new();
293    /// let mut leaves = vec![
294    ///     Sha256::hash("a".as_bytes()),
295    ///     Sha256::hash("b".as_bytes()),
296    /// ];
297    /// merkle_tree.append(&mut leaves);
298    /// assert_eq!(
299    ///     merkle_tree.root_hex(),
300    ///     None
301    /// );
302    ///
303    /// merkle_tree.commit();
304    /// assert_eq!(
305    ///     merkle_tree.root_hex(),
306    ///     Some("e5a01fee14e0ed5c48714f22180f25ad8365b53f9779f79dc4a3d7e93963f94a".to_string())
307    /// );
308    /// # Ok(())
309    /// # }
310    /// ```
311    pub fn commit(&mut self) {
312        if let Some(diff) = self.uncommitted_diff() {
313            self.history.push(diff.clone());
314            self.current_working_tree.merge_unverified(diff);
315            self.uncommitted_leaves.clear();
316        }
317    }
318
319    /// Rolls back one commit and reverts the tree to the previous state.
320    /// Removes the most recent commit from the history.
321    ///
322    /// ## Examples
323    ///
324    /// ```
325    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
326    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
327    /// let mut merkle_tree = MerkleTree::<Sha256>::new();
328    ///
329    /// merkle_tree.insert(Sha256::hash("a".as_bytes())).commit();
330    /// assert_eq!(
331    ///     merkle_tree.root_hex(),
332    ///     Some("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb".to_string())
333    /// );
334    ///
335    /// merkle_tree.insert(Sha256::hash("b".as_bytes())).commit();
336    /// assert_eq!(
337    ///     merkle_tree.root_hex(),
338    ///     Some("e5a01fee14e0ed5c48714f22180f25ad8365b53f9779f79dc4a3d7e93963f94a".to_string())
339    /// );
340    ///
341    /// // Rollback to the previous state
342    /// merkle_tree.rollback();
343    /// assert_eq!(
344    ///     merkle_tree.root_hex(),
345    ///     Some("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb".to_string())
346    /// );
347    /// # Ok(())
348    /// # }
349    /// ```
350    pub fn rollback(&mut self) {
351        // Remove the most recent commit
352        self.history.pop();
353        // Clear working tree
354        self.current_working_tree.clear();
355        // Applying all the commits up to the removed one. This is not an
356        // efficient way of doing things, but the diff subtraction is not implemented yet on
357        // PartialMerkleTree
358        for commit in &self.history {
359            self.current_working_tree.merge_unverified(commit.clone());
360        }
361    }
362
363    /// Calculates the root of the uncommitted changes as if they were committed.
364    /// Will return the same hash as [`MerkleTree::root`] after [`MerkleTree::commit`]
365    ///
366    /// For examples, please check [`MerkleTree::uncommitted_root_hex`]
367    pub fn uncommitted_root(&self) -> Option<T::Hash> {
368        let shadow_tree = self.uncommitted_diff()?;
369        shadow_tree.root().cloned()
370    }
371
372    /// Calculates the root of the uncommitted changes as if they were committed. Serializes
373    /// the result as a hex string.
374    /// Will return the same hash as [`MerkleTree::root_hex`] after [`MerkleTree::commit`]
375    ///
376    /// ### Examples
377    ///
378    /// ```
379    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
380    /// # use std::convert::TryFrom;
381    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
382    /// let mut merkle_tree = MerkleTree::<Sha256>::new();
383    /// let mut leaves = vec![
384    ///     Sha256::hash("a".as_bytes()),
385    ///     Sha256::hash("b".as_bytes()),
386    /// ];
387    /// merkle_tree.append(&mut leaves);
388    /// assert_eq!(
389    ///     merkle_tree.root_hex(),
390    ///     None
391    /// );
392    /// assert_eq!(
393    ///      merkle_tree.uncommitted_root_hex(),
394    ///      Some("e5a01fee14e0ed5c48714f22180f25ad8365b53f9779f79dc4a3d7e93963f94a".to_string())
395    /// );
396    ///
397    /// merkle_tree.commit();
398    /// assert_eq!(
399    ///     merkle_tree.root_hex(),
400    ///     Some("e5a01fee14e0ed5c48714f22180f25ad8365b53f9779f79dc4a3d7e93963f94a".to_string())
401    /// );
402    /// # Ok(())
403    /// # }
404    /// ```
405    pub fn uncommitted_root_hex(&self) -> Option<String> {
406        let root = self.uncommitted_root()?;
407        Some(utils::collections::to_hex_string(&root))
408    }
409
410    /// Clears all uncommitted changes made by [`MerkleTree::insert`] and [`MerkleTree::append`]
411    /// operations without applying them to the tree.
412    ///
413    /// ## Examples
414    ///
415    /// ```
416    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
417    /// # use std::convert::TryFrom;
418    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
419    /// let mut merkle_tree = MerkleTree::<Sha256>::new();
420    /// let mut leaves = vec![
421    ///     Sha256::hash("a".as_bytes()),
422    ///     Sha256::hash("b".as_bytes()),
423    /// ];
424    /// assert_eq!(
425    ///     merkle_tree.root(),
426    ///     None
427    /// );
428    ///
429    /// merkle_tree.append(&mut leaves);
430    /// merkle_tree.abort_uncommitted();
431    /// merkle_tree.commit();
432    ///
433    /// assert_eq!(
434    ///     merkle_tree.root(),
435    ///     None
436    /// );
437    /// # Ok(())
438    /// # }
439    /// ```
440    pub fn abort_uncommitted(&mut self) {
441        self.uncommitted_leaves.clear()
442    }
443
444    /// Returns the tree depth. A tree depth is how many layers there is between the
445    /// leaves and the root
446    ///
447    /// ## Examples
448    ///
449    /// ```
450    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
451    /// # use std::convert::TryFrom;
452    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
453    /// let leaves = [
454    ///     Sha256::hash("a".as_bytes()),
455    ///     Sha256::hash("b".as_bytes()),
456    ///     Sha256::hash("c".as_bytes()),
457    /// ];
458    ///
459    /// let merkle_tree = MerkleTree::<Sha256>::from_leaves(&leaves);
460    /// assert_eq!(merkle_tree.depth(), 2);
461    /// # Ok(())
462    /// # }
463    /// ```
464    pub fn depth(&self) -> usize {
465        self.layer_tuples().len() - 1
466    }
467
468    /// Returns a copy of the tree leaves - the base level of the tree.
469    ///
470    /// ### Examples
471    ///
472    /// ```
473    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
474    /// # use std::convert::TryFrom;
475    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
476    /// let leaves = [
477    ///     Sha256::hash("a".as_bytes()),
478    ///     Sha256::hash("b".as_bytes()),
479    ///     Sha256::hash("c".as_bytes()),
480    /// ];
481    ///
482    /// let merkle_tree = MerkleTree::<Sha256>::from_leaves(&leaves);
483    /// assert_eq!(merkle_tree.leaves(), Some(leaves.to_vec()));
484    /// # Ok(())
485    /// # }
486    /// ```
487    pub fn leaves(&self) -> Option<Vec<T::Hash>> {
488        Some(self.layers().first()?.to_vec())
489    }
490
491    /// Returns the number of leaves in the tree.
492    ///
493    /// ## Examples
494    ///
495    /// ```
496    /// # use rs_merkle::{MerkleTree, MerkleProof, algorithms::Sha256, Hasher, Error, utils};
497    /// # use std::convert::TryFrom;
498    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
499    /// let leaves = [
500    ///     Sha256::hash("a".as_bytes()),
501    ///     Sha256::hash("b".as_bytes()),
502    ///     Sha256::hash("c".as_bytes()),
503    /// ];
504    ///
505    /// let merkle_tree = MerkleTree::<Sha256>::from_leaves(&leaves);
506    /// assert_eq!(merkle_tree.leaves_len(), 3);
507    /// # Ok(())
508    /// # }
509    /// ```
510    pub fn leaves_len(&self) -> usize {
511        if let Some(leaves) = self.leaves_tuples() {
512            return leaves.len();
513        }
514
515        0
516    }
517
518    fn leaves_tuples(&self) -> Option<&[(usize, T::Hash)]> {
519        Some(self.layer_tuples().first()?.as_slice())
520    }
521
522    /// Returns the whole tree, where the first layer is leaves and
523    /// consequent layers are nodes.
524    fn layers(&self) -> Vec<Vec<T::Hash>> {
525        self.current_working_tree.layer_nodes()
526    }
527
528    fn layer_tuples(&self) -> &[Vec<(usize, T::Hash)>] {
529        self.current_working_tree.layers()
530    }
531
532    /// Creates a diff from a changes that weren't committed to the main tree yet. Can be used
533    /// to get uncommitted root or can be merged with the main tree
534    fn uncommitted_diff(&self) -> Option<PartialTree<T>> {
535        if self.uncommitted_leaves.is_empty() {
536            return None;
537        }
538
539        let committed_leaves_count = self.leaves_len();
540
541        let shadow_indices: Vec<usize> = self
542            .uncommitted_leaves
543            .iter()
544            .enumerate()
545            .map(|(index, _)| committed_leaves_count + index)
546            .collect();
547        // Tuples (index, hash) needed to construct a partial tree, since partial tree can't
548        // maintain indices otherwise
549        let mut shadow_node_tuples: Vec<(usize, T::Hash)> = shadow_indices
550            .iter()
551            .cloned()
552            .zip(self.uncommitted_leaves.iter().cloned())
553            .collect();
554        let mut partial_tree_tuples = self.helper_node_tuples(&shadow_indices);
555
556        // Figuring what tree height would be if we've committed the changes
557        let leaves_in_new_tree = self.leaves_len() + self.uncommitted_leaves.len();
558        let uncommitted_tree_depth = utils::indices::tree_depth(leaves_in_new_tree);
559
560        match partial_tree_tuples.first_mut() {
561            Some(first_layer) => {
562                first_layer.append(&mut shadow_node_tuples);
563                first_layer.sort_by(|(a, _), (b, _)| a.cmp(b));
564            }
565            None => partial_tree_tuples.push(shadow_node_tuples),
566        }
567
568        // Building a partial tree with the changes that would be needed to the working tree
569        PartialTree::<T>::build(partial_tree_tuples, uncommitted_tree_depth).ok()
570    }
571}