mirror of
https://github.com/tlsnotary/rs-merkle.git
synced 2026-01-09 23:08:00 -05:00
chore: cleaned up the docs
This commit is contained in:
@@ -2,7 +2,7 @@ use crate::{utils, MerkleProof, Hasher};
|
||||
use crate::utils::indices::{parent_indices, proof_indices};
|
||||
use crate::partial_tree::PartialTree;
|
||||
|
||||
/// `MerkleTree` is a Merkle Tree that is well suited for both basic and advanced usage.
|
||||
/// [`MerkleTree`] is a Merkle Tree that is well suited for both basic and advanced usage.
|
||||
///
|
||||
/// Basic features include creation and verification of merkle proofs from a set of leaves.
|
||||
/// This is often done in various cryptocurrencies.
|
||||
@@ -41,50 +41,54 @@ use crate::partial_tree::PartialTree;
|
||||
///
|
||||
/// let leaf_values = ["a", "b", "c", "d", "e", "f"];
|
||||
/// let expected_root_hex = "1f7379539707bcaea00564168d1d4d626b09b73f8a2a365234c62d763f854da2";
|
||||
/// let leaves = leaf_values
|
||||
/// .iter()
|
||||
/// .map(|x| Sha256::hash(x.as_bytes().to_vec().as_ref()))
|
||||
/// .collect();
|
||||
///
|
||||
/// let mut merkle_tree = MerkleTree::<Sha256>::from_leaves(&leaves);
|
||||
///
|
||||
/// // Adding leaves
|
||||
/// merkle_tree.append(leaf_hashes.clone().as_mut());
|
||||
/// let root = merkle_tree.uncommitted_root_hex().unwrap();
|
||||
///
|
||||
/// assert_eq!(root, expected_root);
|
||||
///
|
||||
/// let expected_uncommitted_root = "e2a80e0e872a6c6eaed37b4c1f220e1935004805585b5f99617e48e9c8fe4034";
|
||||
/// let leaf = Sha256::hash("g".as_bytes().to_vec().as_ref());
|
||||
/// merkle_tree.insert(leaf);
|
||||
///
|
||||
/// assert_eq!(merkle_tree.uncommitted_root_hex().unwrap(), String::from(expected_uncommitted_root));
|
||||
/// let leaves: Vec<[u8; 32]> = leaf_values
|
||||
/// .iter()
|
||||
/// .map(|x| Sha256::hash(x.as_bytes().to_vec().as_ref()))
|
||||
/// .collect();
|
||||
///
|
||||
/// let mut merkle_tree: MerkleTree<Sha256> = MerkleTree::new();
|
||||
/// merkle_tree.append(leaves.clone().as_mut());
|
||||
/// // No changes were committed just yet, tree is empty
|
||||
/// assert_eq!(merkle_tree.root(), None);
|
||||
///
|
||||
/// merkle_tree.commit();
|
||||
///
|
||||
/// let mut new_leaves = vec![
|
||||
/// Sha256::hash("h".as_bytes().to_vec().as_ref()),
|
||||
/// Sha256::hash("k".as_bytes().to_vec().as_ref()),
|
||||
/// ];
|
||||
/// merkle_tree.append(&mut new_leaves);
|
||||
/// assert_eq!(merkle_tree.uncommitted_root_hex().unwrap(), String::from("1f7379539707bcaea00564168d1d4d626b09b73f8a2a365234c62d763f854da2"));
|
||||
///
|
||||
/// assert_eq!(merkle_tree.root_hex().unwrap(), String::from("e2a80e0e872a6c6eaed37b4c1f220e1935004805585b5f99617e48e9c8fe4034"));
|
||||
/// assert_eq!(merkle_tree.uncommitted_root_hex().unwrap(), String::from("09b6890b23e32e607f0e5f670ab224e36af8f6599cbe88b468f4b0f761802dd6"));
|
||||
/// // Adding a new leaf
|
||||
/// merkle_tree.insert(Sha256::hash("g".as_bytes().to_vec().as_ref()));
|
||||
///
|
||||
/// // Uncommitted root must reflect the insert
|
||||
/// assert_eq!(merkle_tree.uncommitted_root_hex().unwrap(), String::from("e2a80e0e872a6c6eaed37b4c1f220e1935004805585b5f99617e48e9c8fe4034"));
|
||||
///
|
||||
/// merkle_tree.commit();
|
||||
///
|
||||
/// // After calling commit, uncommitted root will become committed
|
||||
/// assert_eq!(merkle_tree.root_hex().unwrap(), String::from("e2a80e0e872a6c6eaed37b4c1f220e1935004805585b5f99617e48e9c8fe4034"));
|
||||
///
|
||||
/// // Adding some more leaves
|
||||
/// merkle_tree.append(vec![
|
||||
/// Sha256::hash("h".as_bytes().to_vec().as_ref()),
|
||||
/// Sha256::hash("k".as_bytes().to_vec().as_ref()),
|
||||
/// ].as_mut());
|
||||
///
|
||||
/// // Checking that the uncommitted root has changed, but the committed one hasn't
|
||||
/// assert_eq!(merkle_tree.uncommitted_root_hex().unwrap(), String::from("09b6890b23e32e607f0e5f670ab224e36af8f6599cbe88b468f4b0f761802dd6"));
|
||||
/// assert_eq!(merkle_tree.root_hex().unwrap(), String::from("e2a80e0e872a6c6eaed37b4c1f220e1935004805585b5f99617e48e9c8fe4034"));
|
||||
///
|
||||
/// merkle_tree.commit();
|
||||
///
|
||||
/// // Checking committed changes again
|
||||
/// assert_eq!(merkle_tree.root_hex().unwrap(), String::from("09b6890b23e32e607f0e5f670ab224e36af8f6599cbe88b468f4b0f761802dd6"));
|
||||
///
|
||||
/// merkle_tree.rollback();
|
||||
///
|
||||
/// // Check that we rolled one commit back
|
||||
/// assert_eq!(merkle_tree.root_hex().unwrap(), String::from("e2a80e0e872a6c6eaed37b4c1f220e1935004805585b5f99617e48e9c8fe4034"));
|
||||
///
|
||||
/// merkle_tree.rollback();
|
||||
///
|
||||
/// // Rolling back to the initial state
|
||||
/// // Rolling back to the state after the very first commit
|
||||
/// assert_eq!(merkle_tree.root_hex().unwrap(), expected_root_hex);
|
||||
/// ```
|
||||
#[derive(Clone)]
|
||||
@@ -199,7 +203,7 @@ impl<T: Hasher> MerkleTree<T> {
|
||||
self.current_working_tree.layer_nodes()
|
||||
}
|
||||
|
||||
/// Same as `layers`, but serializes each hash as a hex string
|
||||
/// Same as [`layers`](MerkleTree::layers), but serializes each hash as a hex string
|
||||
pub fn layers_hex(&self) -> Vec<Vec<String>> {
|
||||
self.layers()
|
||||
.iter()
|
||||
@@ -208,8 +212,8 @@ impl<T: Hasher> MerkleTree<T> {
|
||||
}
|
||||
|
||||
/// Inserts a new leaf. Please note it won't modify the root just yet; For the changes
|
||||
/// to be applied to the root, `.commit()` method should be called first. To get the root
|
||||
/// of the new tree without applying the changes, you can use `.uncommitted_root`
|
||||
/// to be applied to the root, [`commit`](MerkleTree::commit) method should be called first. To get the root
|
||||
/// of the new tree without applying the changes, you can use [`uncommitted_root`](MerkleTree::uncommitted_root)
|
||||
///
|
||||
/// # Example
|
||||
/// // TODO
|
||||
@@ -217,13 +221,14 @@ impl<T: Hasher> MerkleTree<T> {
|
||||
self.uncommitted_leaves.push(leaf)
|
||||
}
|
||||
|
||||
/// Appends leaves to the tree. Behaves similarly to `commit`, but for a list of items.
|
||||
/// Takes ownership of the elements of the `Vec<T>`, similarly to `append` of a `Vec<T>`
|
||||
/// Appends leaves to the tree. Behaves similarly to [`commit`](MerkleTree::commit), but for a list of items.
|
||||
/// Takes ownership of the elements of the [`std::vec::Vec<T>`], similarly to [`append`](std::vec::Vec::append) of a [`std::vec::Vec<T>`]
|
||||
pub fn append(&mut self, leaves: &mut Vec<T::Hash>) {
|
||||
self.uncommitted_leaves.append(leaves)
|
||||
}
|
||||
|
||||
/// Calculates the root of the uncommitted changes as if they were committed
|
||||
/// Calculates the root of the uncommitted changes as if they were committed.
|
||||
/// Will return the same hash as [`root`](MerkleTree::root) after [`commit`](MerkleTree::commit)
|
||||
pub fn uncommitted_root(&self) -> Option<T::Hash> {
|
||||
let shadow_tree = self.uncommitted_diff()?;
|
||||
shadow_tree.root().cloned()
|
||||
@@ -235,8 +240,9 @@ impl<T: Hasher> MerkleTree<T> {
|
||||
Some(utils::collections::to_hex_string(&root))
|
||||
}
|
||||
|
||||
/// Commits changes made by `insert` and `append` and modifies the root by rebuilding the tree.
|
||||
/// Commits the change to a history, so the tree can be rolled back to any of previous commits.
|
||||
/// Commits changes made by [`insert`](MerkleTree::insert) and [`append`](MerkleTree::append)
|
||||
/// and modifies the root.
|
||||
/// Commits changes to the history, so the tree can be rolled back to any previous commit.
|
||||
pub fn commit(&mut self) {
|
||||
if let Some(diff) = self.uncommitted_diff() {
|
||||
self.history.push(diff.clone());
|
||||
@@ -244,7 +250,8 @@ impl<T: Hasher> MerkleTree<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Aborts all uncommitted `insert` and `append` operations without applying them to the tree.
|
||||
/// Aborts all uncommitted [`insert`](MerkleTree::insert) and [`append`](MerkleTree::append)
|
||||
/// operations without applying them to the tree.
|
||||
pub fn abort_uncommitted(&mut self) {
|
||||
self.uncommitted_leaves.clear()
|
||||
}
|
||||
|
||||
@@ -110,54 +110,56 @@ pub mod rollback {
|
||||
use rs_merkle::{MerkleTree, algorithms::Sha256, Hasher};
|
||||
|
||||
pub fn should_rollback_previous_commit() {
|
||||
let test_data = common::setup();
|
||||
let expected_root = test_data.expected_root_hex.clone();
|
||||
let leaf_hashes = &test_data.leaf_hashes;
|
||||
// let indices_to_prove = vec![3, 4];
|
||||
// let leaves_to_prove = indices_to_prove.iter().cloned().map(|i| leaf_hashes.get(i).unwrap().clone()).collect();
|
||||
let vec = Vec::<[u8;32]>::new();
|
||||
|
||||
// Passing empty vec to create an empty tree
|
||||
let mut merkle_tree = MerkleTree::<Sha256>::from_leaves(&vec);
|
||||
let mut merkle_tree2 = MerkleTree::<Sha256>::from_leaves(&leaf_hashes);
|
||||
// Adding leaves
|
||||
merkle_tree.append(leaf_hashes.clone().as_mut());
|
||||
let root = merkle_tree.uncommitted_root_hex().unwrap();
|
||||
|
||||
assert_eq!(merkle_tree2.root_hex().unwrap(), expected_root);
|
||||
assert_eq!(root, expected_root);
|
||||
|
||||
let expected_uncommitted_root = "e2a80e0e872a6c6eaed37b4c1f220e1935004805585b5f99617e48e9c8fe4034";
|
||||
let leaf = Sha256::hash("g".as_bytes().to_vec().as_ref());
|
||||
merkle_tree.insert(leaf);
|
||||
|
||||
assert_eq!(merkle_tree.uncommitted_root_hex().unwrap(), String::from(expected_uncommitted_root));
|
||||
let leaf_values = ["a", "b", "c", "d", "e", "f"];
|
||||
let expected_root_hex = "1f7379539707bcaea00564168d1d4d626b09b73f8a2a365234c62d763f854da2";
|
||||
let leaves: Vec<[u8; 32]> = leaf_values
|
||||
.iter()
|
||||
.map(|x| Sha256::hash(x.as_bytes().to_vec().as_ref()))
|
||||
.collect();
|
||||
|
||||
let mut merkle_tree: MerkleTree<Sha256> = MerkleTree::new();
|
||||
merkle_tree.append(leaves.clone().as_mut());
|
||||
// No changes were committed just yet, tree is empty
|
||||
assert_eq!(merkle_tree.root(), None);
|
||||
|
||||
merkle_tree.commit();
|
||||
|
||||
let mut new_leaves = vec![
|
||||
Sha256::hash("h".as_bytes().to_vec().as_ref()),
|
||||
Sha256::hash("k".as_bytes().to_vec().as_ref()),
|
||||
];
|
||||
merkle_tree.append(&mut new_leaves);
|
||||
assert_eq!(merkle_tree.uncommitted_root_hex().unwrap(), String::from("1f7379539707bcaea00564168d1d4d626b09b73f8a2a365234c62d763f854da2"));
|
||||
|
||||
assert_eq!(merkle_tree.root_hex().unwrap(), String::from("e2a80e0e872a6c6eaed37b4c1f220e1935004805585b5f99617e48e9c8fe4034"));
|
||||
assert_eq!(merkle_tree.uncommitted_root_hex().unwrap(), String::from("09b6890b23e32e607f0e5f670ab224e36af8f6599cbe88b468f4b0f761802dd6"));
|
||||
// Adding a new leaf
|
||||
merkle_tree.insert(Sha256::hash("g".as_bytes().to_vec().as_ref()));
|
||||
|
||||
// Uncommitted root must reflect the insert
|
||||
assert_eq!(merkle_tree.uncommitted_root_hex().unwrap(), String::from("e2a80e0e872a6c6eaed37b4c1f220e1935004805585b5f99617e48e9c8fe4034"));
|
||||
|
||||
merkle_tree.commit();
|
||||
|
||||
// After calling commit, uncommitted root will become committed
|
||||
assert_eq!(merkle_tree.root_hex().unwrap(), String::from("e2a80e0e872a6c6eaed37b4c1f220e1935004805585b5f99617e48e9c8fe4034"));
|
||||
|
||||
// Adding some more leaves
|
||||
merkle_tree.append(vec![
|
||||
Sha256::hash("h".as_bytes().to_vec().as_ref()),
|
||||
Sha256::hash("k".as_bytes().to_vec().as_ref()),
|
||||
].as_mut());
|
||||
|
||||
// Checking that the uncommitted root has changed, but the committed one hasn't
|
||||
assert_eq!(merkle_tree.uncommitted_root_hex().unwrap(), String::from("09b6890b23e32e607f0e5f670ab224e36af8f6599cbe88b468f4b0f761802dd6"));
|
||||
assert_eq!(merkle_tree.root_hex().unwrap(), String::from("e2a80e0e872a6c6eaed37b4c1f220e1935004805585b5f99617e48e9c8fe4034"));
|
||||
|
||||
merkle_tree.commit();
|
||||
|
||||
// Checking committed changes again
|
||||
assert_eq!(merkle_tree.root_hex().unwrap(), String::from("09b6890b23e32e607f0e5f670ab224e36af8f6599cbe88b468f4b0f761802dd6"));
|
||||
|
||||
merkle_tree.rollback();
|
||||
|
||||
// Check that we rolled one commit back
|
||||
assert_eq!(merkle_tree.root_hex().unwrap(), String::from("e2a80e0e872a6c6eaed37b4c1f220e1935004805585b5f99617e48e9c8fe4034"));
|
||||
|
||||
merkle_tree.rollback();
|
||||
|
||||
// Rolling back to the initial state
|
||||
assert_eq!(merkle_tree.root_hex().unwrap(), expected_root);
|
||||
// Rolling back to the state after the very first commit
|
||||
assert_eq!(merkle_tree.root_hex().unwrap(), expected_root_hex);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user