chore: cleaned up the docs

This commit is contained in:
Anton Suprunchuk
2021-09-27 14:11:03 +03:00
parent 2b10dbb325
commit b090d86eff
2 changed files with 76 additions and 67 deletions

View File

@@ -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()
}

View File

@@ -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);
}
}