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(¤t_layer_indices);
152 // Filter all nodes that do not require an additional hash to be calculated
153 let helper_indices = utils::collections::difference(&siblings, ¤t_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(¤t_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}