Browse Source

refactor: refactor to clean up and simplify things

al-gkr-basic-workflow
tohrnii 1 year ago
parent
commit
0e0a3fda4f
6 changed files with 200 additions and 231 deletions
  1. +34
    -42
      src/merkle/merkle_tree.rs
  2. +4
    -0
      src/merkle/mod.rs
  3. +22
    -26
      src/merkle/path_set.rs
  4. +44
    -38
      src/merkle/simple_smt/tests.rs
  5. +82
    -75
      src/merkle/store/tests.rs
  6. +14
    -50
      src/merkle/tiered_smt/tests.rs

+ 34
- 42
src/merkle/merkle_tree.rs

@ -1,6 +1,6 @@
use super::{InnerNodeInfo, MerkleError, MerklePath, NodeIndex, Rpo256, RpoDigest, Vec, Word};
use crate::utils::{string::String, uninit_vector, word_to_hex};
use core::{fmt, slice};
use core::{fmt, ops::Deref, slice};
use winter_math::log2;
// MERKLE TREE
@ -117,7 +117,11 @@ impl MerkleTree {
/// Returns an iterator over the leaves of this [MerkleTree].
pub fn leaves(&self) -> impl Iterator<Item = (u64, &Word)> {
let leaves_start = self.nodes.len() / 2;
self.nodes.iter().skip(leaves_start).enumerate().map(|(i, v)| (i as u64, &**v))
self.nodes
.iter()
.skip(leaves_start)
.enumerate()
.map(|(i, v)| (i as u64, v.deref()))
}
/// Returns n iterator over every inner node of this [MerkleTree].
@ -256,29 +260,29 @@ pub fn path_to_text(path: &MerklePath) -> Result {
mod tests {
use super::*;
use crate::{
merkle::{int_to_leaf, InnerNodeInfo},
merkle::{digests_to_words, int_to_leaf, int_to_node, InnerNodeInfo},
Felt, Word, WORD_SIZE,
};
use core::mem::size_of;
use proptest::prelude::*;
const LEAVES4: [Word; WORD_SIZE] =
[int_to_leaf(1), int_to_leaf(2), int_to_leaf(3), int_to_leaf(4)];
const LEAVES8: [Word; 8] = [
int_to_leaf(1),
int_to_leaf(2),
int_to_leaf(3),
int_to_leaf(4),
int_to_leaf(5),
int_to_leaf(6),
int_to_leaf(7),
int_to_leaf(8),
const LEAVES4: [RpoDigest; WORD_SIZE] =
[int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)];
const LEAVES8: [RpoDigest; 8] = [
int_to_node(1),
int_to_node(2),
int_to_node(3),
int_to_node(4),
int_to_node(5),
int_to_node(6),
int_to_node(7),
int_to_node(8),
];
#[test]
fn build_merkle_tree() {
let tree = super::MerkleTree::new(LEAVES4.to_vec()).unwrap();
let tree = super::MerkleTree::new(digests_to_words(&LEAVES4)).unwrap();
assert_eq!(8, tree.nodes.len());
// leaves were copied correctly
@ -297,13 +301,13 @@ mod tests {
#[test]
fn get_leaf() {
let tree = super::MerkleTree::new(LEAVES4.to_vec()).unwrap();
let tree = super::MerkleTree::new(digests_to_words(&LEAVES4)).unwrap();
// check depth 2
assert_eq!(RpoDigest::from(LEAVES4[0]), tree.get_node(NodeIndex::make(2, 0)).unwrap());
assert_eq!(RpoDigest::from(LEAVES4[1]), tree.get_node(NodeIndex::make(2, 1)).unwrap());
assert_eq!(RpoDigest::from(LEAVES4[2]), tree.get_node(NodeIndex::make(2, 2)).unwrap());
assert_eq!(RpoDigest::from(LEAVES4[3]), tree.get_node(NodeIndex::make(2, 3)).unwrap());
assert_eq!(LEAVES4[0], tree.get_node(NodeIndex::make(2, 0)).unwrap());
assert_eq!(LEAVES4[1], tree.get_node(NodeIndex::make(2, 1)).unwrap());
assert_eq!(LEAVES4[2], tree.get_node(NodeIndex::make(2, 2)).unwrap());
assert_eq!(LEAVES4[3], tree.get_node(NodeIndex::make(2, 3)).unwrap());
// check depth 1
let (_, node2, node3) = compute_internal_nodes();
@ -314,27 +318,15 @@ mod tests {
#[test]
fn get_path() {
let tree = super::MerkleTree::new(LEAVES4.to_vec()).unwrap();
let tree = super::MerkleTree::new(digests_to_words(&LEAVES4)).unwrap();
let (_, node2, node3) = compute_internal_nodes();
// check depth 2
assert_eq!(
vec![RpoDigest::from(LEAVES4[1]), node3],
*tree.get_path(NodeIndex::make(2, 0)).unwrap()
);
assert_eq!(
vec![RpoDigest::from(LEAVES4[0]), node3],
*tree.get_path(NodeIndex::make(2, 1)).unwrap()
);
assert_eq!(
vec![RpoDigest::from(LEAVES4[3]), node2],
*tree.get_path(NodeIndex::make(2, 2)).unwrap()
);
assert_eq!(
vec![RpoDigest::from(LEAVES4[2]), node2],
*tree.get_path(NodeIndex::make(2, 3)).unwrap()
);
assert_eq!(vec![LEAVES4[1], node3], *tree.get_path(NodeIndex::make(2, 0)).unwrap());
assert_eq!(vec![LEAVES4[0], node3], *tree.get_path(NodeIndex::make(2, 1)).unwrap());
assert_eq!(vec![LEAVES4[3], node2], *tree.get_path(NodeIndex::make(2, 2)).unwrap());
assert_eq!(vec![LEAVES4[2], node2], *tree.get_path(NodeIndex::make(2, 3)).unwrap());
// check depth 1
assert_eq!(vec![node3], *tree.get_path(NodeIndex::make(1, 0)).unwrap());
@ -343,13 +335,13 @@ mod tests {
#[test]
fn update_leaf() {
let mut tree = super::MerkleTree::new(LEAVES8.to_vec()).unwrap();
let mut tree = super::MerkleTree::new(digests_to_words(&LEAVES8)).unwrap();
// update one leaf
let value = 3;
let new_node = int_to_leaf(9);
let mut expected_leaves = LEAVES8.to_vec();
expected_leaves[value as usize] = new_node;
let mut expected_leaves = digests_to_words(&LEAVES8);
expected_leaves[value as usize] = new_node.into();
let expected_tree = super::MerkleTree::new(expected_leaves.clone()).unwrap();
tree.update_leaf(value, new_node).unwrap();
@ -367,7 +359,7 @@ mod tests {
#[test]
fn nodes() -> Result<(), MerkleError> {
let tree = super::MerkleTree::new(LEAVES4.to_vec()).unwrap();
let tree = super::MerkleTree::new(digests_to_words(&LEAVES4)).unwrap();
let root = tree.root();
let l1n0 = tree.get_node(NodeIndex::make(1, 0))?;
let l1n1 = tree.get_node(NodeIndex::make(1, 1))?;

+ 4
- 0
src/merkle/mod.rs

@ -102,3 +102,7 @@ const fn int_to_node(value: u64) -> RpoDigest {
const fn int_to_leaf(value: u64) -> Word {
[Felt::new(value), ZERO, ZERO, ZERO]
}
pub fn digests_to_words(digests: &[RpoDigest]) -> Vec<Word> {
digests.iter().map(|d| d.into()).collect()
}

+ 22
- 26
src/merkle/path_set.rs

@ -36,7 +36,7 @@ impl MerklePathSet {
I: IntoIterator<Item = (u64, RpoDigest, MerklePath)>,
{
paths.into_iter().try_fold(self, |mut set, (index, value, path)| {
set.add_path(index, value, path)?;
set.add_path(index, value.into(), path)?;
Ok(set)
})
}
@ -151,7 +151,7 @@ impl MerklePathSet {
pub fn add_path(
&mut self,
index_value: u64,
value: RpoDigest,
value: Word,
mut path: MerklePath,
) -> Result<(), MerkleError> {
let mut index = NodeIndex::new(path.len() as u8, index_value)?;
@ -164,10 +164,10 @@ impl MerklePathSet {
// update the current path
let parity = index_value & 1;
path.insert(parity as usize, value);
path.insert(parity as usize, value.into());
// traverse to the root, updating the nodes
let root: RpoDigest = Rpo256::merge(&[path[0], path[1]]);
let root = Rpo256::merge(&[path[0], path[1]]);
let root = path.iter().skip(2).copied().fold(root, |root, hash| {
index.move_up();
Rpo256::merge(&index.build_node(root, hash))
@ -192,11 +192,7 @@ impl MerklePathSet {
/// # Errors
/// Returns an error if:
/// * Requested node does not exist in the set.
pub fn update_leaf(
&mut self,
base_index_value: u64,
value: RpoDigest,
) -> Result<(), MerkleError> {
pub fn update_leaf(&mut self, base_index_value: u64, value: Word) -> Result<(), MerkleError> {
let mut index = NodeIndex::new(self.depth(), base_index_value)?;
let parity = index.value() & 1;
let path_key = index.value() - parity;
@ -208,7 +204,7 @@ impl MerklePathSet {
// Fill old_hashes vector -----------------------------------------------------------------
let mut current_index = index;
let mut old_hashes = Vec::with_capacity(path.len().saturating_sub(2));
let mut root: RpoDigest = Rpo256::merge(&[path[0], path[1]]);
let mut root = Rpo256::merge(&[path[0], path[1]]);
for hash in path.iter().skip(2).copied() {
old_hashes.push(root);
current_index.move_up();
@ -217,10 +213,10 @@ impl MerklePathSet {
}
// Fill new_hashes vector -----------------------------------------------------------------
path[index.is_value_odd() as usize] = value;
path[index.is_value_odd() as usize] = value.into();
let mut new_hashes = Vec::with_capacity(path.len().saturating_sub(2));
let mut new_root: RpoDigest = Rpo256::merge(&[path[0], path[1]]);
let mut new_root = Rpo256::merge(&[path[0], path[1]]);
for path_hash in path.iter().skip(2).copied() {
new_hashes.push(new_root);
index.move_up();
@ -250,7 +246,7 @@ impl MerklePathSet {
#[cfg(test)]
mod tests {
use super::*;
use crate::merkle::int_to_node;
use crate::merkle::{int_to_leaf, int_to_node};
#[test]
fn get_root() {
@ -323,20 +319,20 @@ mod tests {
])
.unwrap();
let new_hash_6 = int_to_node(100);
let new_hash_5 = int_to_node(55);
let new_hash_6 = int_to_leaf(100);
let new_hash_5 = int_to_leaf(55);
set.update_leaf(index_6, new_hash_6).unwrap();
let new_path_4 = set.get_path(NodeIndex::make(depth, index_4)).unwrap();
let new_hash_67 = calculate_parent_hash(new_hash_6, 14_u64, hash_7);
let new_hash_67 = calculate_parent_hash(new_hash_6.into(), 14_u64, hash_7);
assert_eq!(new_hash_67, new_path_4[1]);
set.update_leaf(index_5, new_hash_5).unwrap();
let new_path_4 = set.get_path(NodeIndex::make(depth, index_4)).unwrap();
let new_path_6 = set.get_path(NodeIndex::make(depth, index_6)).unwrap();
let new_hash_45 = calculate_parent_hash(new_hash_5, 13_u64, hash_4);
let new_hash_45 = calculate_parent_hash(new_hash_5.into(), 13_u64, hash_4);
assert_eq!(new_hash_45, new_path_6[1]);
assert_eq!(new_hash_5, new_path_4[0]);
assert_eq!(RpoDigest::from(new_hash_5), new_path_4[0]);
}
#[test]
@ -365,30 +361,30 @@ mod tests {
let value = b;
let index = 1;
let path = MerklePath::new([a, j, n].to_vec());
set.add_path(index, value, path.clone()).unwrap();
set.add_path(index, value.into(), path.clone()).unwrap();
assert_eq!(*value, set.get_leaf(index).unwrap());
assert_eq!(RpoDigest::from(root), set.root());
assert_eq!(root, set.root());
let value = e;
let index = 4;
let path = MerklePath::new([f.into(), l.into(), m.into()].to_vec());
set.add_path(index, value, path.clone()).unwrap();
set.add_path(index, value.into(), path.clone()).unwrap();
assert_eq!(*value, set.get_leaf(index).unwrap());
assert_eq!(RpoDigest::from(root), set.root());
assert_eq!(root, set.root());
let value = a;
let index = 0;
let path = MerklePath::new([b.into(), j.into(), n.into()].to_vec());
set.add_path(index, value, path.clone()).unwrap();
set.add_path(index, value.into(), path.clone()).unwrap();
assert_eq!(*value, set.get_leaf(index).unwrap());
assert_eq!(RpoDigest::from(root), set.root());
assert_eq!(root, set.root());
let value = h;
let index = 7;
let path = MerklePath::new([g.into(), k.into(), m.into()].to_vec());
set.add_path(index, value, path.clone()).unwrap();
set.add_path(index, value.into(), path.clone()).unwrap();
assert_eq!(*value, set.get_leaf(index).unwrap());
assert_eq!(RpoDigest::from(root), set.root());
assert_eq!(root, set.root());
}
// HELPER FUNCTIONS

+ 44
- 38
src/merkle/simple_smt/tests.rs

@ -3,7 +3,7 @@ use super::{
NodeIndex, Rpo256, Vec,
};
use crate::{
merkle::{empty_roots::EMPTY_WORD, int_to_leaf},
merkle::{digests_to_words, empty_roots::EMPTY_WORD, int_to_leaf, int_to_node},
Word,
};
@ -13,17 +13,17 @@ use crate::{
const KEYS4: [u64; 4] = [0, 1, 2, 3];
const KEYS8: [u64; 8] = [0, 1, 2, 3, 4, 5, 6, 7];
const VALUES4: [Word; 4] = [int_to_leaf(1), int_to_leaf(2), int_to_leaf(3), int_to_leaf(4)];
const VALUES8: [Word; 8] = [
int_to_leaf(1),
int_to_leaf(2),
int_to_leaf(3),
int_to_leaf(4),
int_to_leaf(5),
int_to_leaf(6),
int_to_leaf(7),
int_to_leaf(8),
const VALUES4: [RpoDigest; 4] = [int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)];
const VALUES8: [RpoDigest; 8] = [
int_to_node(1),
int_to_node(2),
int_to_node(3),
int_to_node(4),
int_to_node(5),
int_to_node(6),
int_to_node(7),
int_to_node(8),
];
const ZERO_VALUES8: [Word; 8] = [int_to_leaf(0); 8];
@ -47,7 +47,7 @@ fn build_sparse_tree() {
// insert single value
let key = 6;
let new_node = int_to_leaf(7);
values[key as usize] = new_node;
values[key as usize] = new_node.into();
let old_value = smt.update_leaf(key, new_node).expect("Failed to update leaf");
let mt2 = MerkleTree::new(values.clone()).unwrap();
assert_eq!(mt2.root(), smt.root().into());
@ -73,7 +73,9 @@ fn build_sparse_tree() {
#[test]
fn test_depth2_tree() {
let tree = SimpleSmt::with_leaves(2, KEYS4.into_iter().zip(VALUES4.into_iter())).unwrap();
let tree =
SimpleSmt::with_leaves(2, KEYS4.into_iter().zip(digests_to_words(&VALUES4).into_iter()))
.unwrap();
// check internal structure
let (root, node2, node3) = compute_internal_nodes();
@ -82,10 +84,10 @@ fn test_depth2_tree() {
assert_eq!(node3, tree.get_node(NodeIndex::make(1, 1)).unwrap());
// check get_node()
assert_eq!(VALUES4[0], *tree.get_node(NodeIndex::make(2, 0)).unwrap());
assert_eq!(VALUES4[1], *tree.get_node(NodeIndex::make(2, 1)).unwrap());
assert_eq!(VALUES4[2], *tree.get_node(NodeIndex::make(2, 2)).unwrap());
assert_eq!(VALUES4[3], *tree.get_node(NodeIndex::make(2, 3)).unwrap());
assert_eq!(VALUES4[0], tree.get_node(NodeIndex::make(2, 0)).unwrap());
assert_eq!(VALUES4[1], tree.get_node(NodeIndex::make(2, 1)).unwrap());
assert_eq!(VALUES4[2], tree.get_node(NodeIndex::make(2, 2)).unwrap());
assert_eq!(VALUES4[3], tree.get_node(NodeIndex::make(2, 3)).unwrap());
// check get_path(): depth 2
assert_eq!(vec![VALUES4[1].into(), node3], *tree.get_path(NodeIndex::make(2, 0)).unwrap());
@ -100,13 +102,15 @@ fn test_depth2_tree() {
#[test]
fn test_inner_node_iterator() -> Result<(), MerkleError> {
let tree = SimpleSmt::with_leaves(2, KEYS4.into_iter().zip(VALUES4.into_iter())).unwrap();
let tree =
SimpleSmt::with_leaves(2, KEYS4.into_iter().zip(digests_to_words(&VALUES4).into_iter()))
.unwrap();
// check depth 2
assert_eq!(VALUES4[0], *tree.get_node(NodeIndex::make(2, 0)).unwrap());
assert_eq!(VALUES4[1], *tree.get_node(NodeIndex::make(2, 1)).unwrap());
assert_eq!(VALUES4[2], *tree.get_node(NodeIndex::make(2, 2)).unwrap());
assert_eq!(VALUES4[3], *tree.get_node(NodeIndex::make(2, 3)).unwrap());
assert_eq!(VALUES4[0], tree.get_node(NodeIndex::make(2, 0)).unwrap());
assert_eq!(VALUES4[1], tree.get_node(NodeIndex::make(2, 1)).unwrap());
assert_eq!(VALUES4[2], tree.get_node(NodeIndex::make(2, 2)).unwrap());
assert_eq!(VALUES4[3], tree.get_node(NodeIndex::make(2, 3)).unwrap());
// get parent nodes
let root = tree.root();
@ -120,19 +124,19 @@ fn test_inner_node_iterator() -> Result<(), MerkleError> {
let nodes: Vec<InnerNodeInfo> = tree.inner_nodes().collect();
let expected = vec![
InnerNodeInfo {
value: root.into(),
left: l1n0.into(),
right: l1n1.into(),
value: root,
left: l1n0,
right: l1n1,
},
InnerNodeInfo {
value: l1n0.into(),
left: l2n0.into(),
right: l2n1.into(),
value: l1n0,
left: l2n0,
right: l2n1,
},
InnerNodeInfo {
value: l1n1.into(),
left: l2n2.into(),
right: l2n3.into(),
value: l1n1,
left: l2n2,
right: l2n3,
},
];
assert_eq!(nodes, expected);
@ -142,18 +146,20 @@ fn test_inner_node_iterator() -> Result<(), MerkleError> {
#[test]
fn update_leaf() {
let mut tree = SimpleSmt::with_leaves(3, KEYS8.into_iter().zip(VALUES8.into_iter())).unwrap();
let mut tree =
SimpleSmt::with_leaves(3, KEYS8.into_iter().zip(digests_to_words(&VALUES8).into_iter()))
.unwrap();
// update one value
let key = 3;
let new_node = int_to_leaf(9);
let mut expected_values = VALUES8.to_vec();
let mut expected_values = digests_to_words(&VALUES8);
expected_values[key] = new_node;
let expected_tree = MerkleTree::new(expected_values.clone()).unwrap();
let old_leaf = tree.update_leaf(key as u64, new_node).unwrap();
assert_eq!(expected_tree.root(), tree.root);
assert_eq!(old_leaf, VALUES8[key]);
assert_eq!(old_leaf, *VALUES8[key]);
// update another value
let key = 6;
@ -163,7 +169,7 @@ fn update_leaf() {
let old_leaf = tree.update_leaf(key as u64, new_node).unwrap();
assert_eq!(expected_tree.root(), tree.root);
assert_eq!(old_leaf, VALUES8[key]);
assert_eq!(old_leaf, *VALUES8[key]);
}
#[test]
@ -252,14 +258,14 @@ fn compute_internal_nodes() -> (RpoDigest, RpoDigest, RpoDigest) {
let node2 = Rpo256::hash_elements(
&[VALUES4[0], VALUES4[1]]
.iter()
.map(|digest| *digest)
.map(|digest| digest.into())
.collect::<Vec<Word>>()
.concat(),
);
let node3 = Rpo256::hash_elements(
&[VALUES4[2], VALUES4[3]]
.iter()
.map(|digest| *digest)
.map(|digest| digest.into())
.collect::<Vec<Word>>()
.concat(),
);

+ 82
- 75
src/merkle/store/tests.rs

@ -4,7 +4,7 @@ use super::{
};
use crate::{
hash::rpo::Rpo256,
merkle::{int_to_leaf, int_to_node, MerklePathSet, MerkleTree, SimpleSmt},
merkle::{digests_to_words, int_to_leaf, int_to_node, MerklePathSet, MerkleTree, SimpleSmt},
Felt, Word, WORD_SIZE,
};
@ -15,17 +15,17 @@ use std::error::Error;
// ================================================================================================
const KEYS4: [u64; 4] = [0, 1, 2, 3];
const VALUES4: [Word; 4] = [int_to_leaf(1), int_to_leaf(2), int_to_leaf(3), int_to_leaf(4)];
const VALUES8: [Word; 8] = [
int_to_leaf(1),
int_to_leaf(2),
int_to_leaf(3),
int_to_leaf(4),
int_to_leaf(5),
int_to_leaf(6),
int_to_leaf(7),
int_to_leaf(8),
const VALUES4: [RpoDigest; 4] = [int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)];
const VALUES8: [RpoDigest; 8] = [
int_to_node(1),
int_to_node(2),
int_to_node(3),
int_to_node(4),
int_to_node(5),
int_to_node(6),
int_to_node(7),
int_to_node(8),
];
// TESTS
@ -33,16 +33,16 @@ const VALUES8: [Word; 8] = [
#[test]
fn test_root_not_in_store() -> Result<(), MerkleError> {
let mtree = MerkleTree::new(VALUES4.to_vec())?;
let mtree = MerkleTree::new(digests_to_words(&VALUES4))?;
let store = MerkleStore::from(&mtree);
assert_eq!(
store.get_node(VALUES4[0].into(), NodeIndex::make(mtree.depth(), 0)),
Err(MerkleError::RootNotInStore(VALUES4[0].into())),
store.get_node(VALUES4[0], NodeIndex::make(mtree.depth(), 0)),
Err(MerkleError::RootNotInStore(VALUES4[0])),
"Leaf 0 is not a root"
);
assert_eq!(
store.get_path(VALUES4[0].into(), NodeIndex::make(mtree.depth(), 0)),
Err(MerkleError::RootNotInStore(VALUES4[0].into())),
store.get_path(VALUES4[0], NodeIndex::make(mtree.depth(), 0)),
Err(MerkleError::RootNotInStore(VALUES4[0])),
"Leaf 0 is not a root"
);
@ -51,29 +51,29 @@ fn test_root_not_in_store() -> Result<(), MerkleError> {
#[test]
fn test_merkle_tree() -> Result<(), MerkleError> {
let mtree = MerkleTree::new(VALUES4.to_vec())?;
let mtree = MerkleTree::new(digests_to_words(&VALUES4))?;
let store = MerkleStore::from(&mtree);
// STORE LEAVES ARE CORRECT -------------------------------------------------------------------
// checks the leaves in the store corresponds to the expected values
assert_eq!(
store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 0)),
Ok(VALUES4[0].into()),
Ok(VALUES4[0]),
"node 0 must be in the tree"
);
assert_eq!(
store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 1)),
Ok(VALUES4[1].into()),
Ok(VALUES4[1]),
"node 1 must be in the tree"
);
assert_eq!(
store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 2)),
Ok(VALUES4[2].into()),
Ok(VALUES4[2]),
"node 2 must be in the tree"
);
assert_eq!(
store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 3)),
Ok(VALUES4[3].into()),
Ok(VALUES4[3]),
"node 3 must be in the tree"
);
@ -104,7 +104,7 @@ fn test_merkle_tree() -> Result<(), MerkleError> {
// assert the merkle path returned by the store is the same as the one in the tree
let result = store.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 0)).unwrap();
assert_eq!(
VALUES4[0], *result.value,
VALUES4[0], result.value,
"Value for merkle path at index 0 must match leaf value"
);
assert_eq!(
@ -115,7 +115,7 @@ fn test_merkle_tree() -> Result<(), MerkleError> {
let result = store.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 1)).unwrap();
assert_eq!(
VALUES4[1], *result.value,
VALUES4[1], result.value,
"Value for merkle path at index 0 must match leaf value"
);
assert_eq!(
@ -126,7 +126,7 @@ fn test_merkle_tree() -> Result<(), MerkleError> {
let result = store.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 2)).unwrap();
assert_eq!(
VALUES4[2], *result.value,
VALUES4[2], result.value,
"Value for merkle path at index 0 must match leaf value"
);
assert_eq!(
@ -137,7 +137,7 @@ fn test_merkle_tree() -> Result<(), MerkleError> {
let result = store.get_path(mtree.root(), NodeIndex::make(mtree.depth(), 3)).unwrap();
assert_eq!(
VALUES4[3], *result.value,
VALUES4[3], result.value,
"Value for merkle path at index 0 must match leaf value"
);
assert_eq!(
@ -157,7 +157,7 @@ fn test_empty_roots() {
for depth in 0..255 {
root = Rpo256::merge(&[root; 2]);
assert!(
store.get_node(root.into(), NodeIndex::make(0, 0)).is_ok(),
store.get_node(root, NodeIndex::make(0, 0)).is_ok(),
"The root of the empty tree of depth {depth} must be registered"
);
}
@ -197,7 +197,8 @@ fn test_leaf_paths_for_empty_trees() -> Result<(), MerkleError> {
#[test]
fn test_get_invalid_node() {
let mtree = MerkleTree::new(VALUES4.to_vec()).expect("creating a merkle tree must work");
let mtree =
MerkleTree::new(digests_to_words(&VALUES4)).expect("creating a merkle tree must work");
let store = MerkleStore::from(&mtree);
let _ = store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 3));
}
@ -211,7 +212,7 @@ fn test_add_sparse_merkle_tree_one_level() -> Result<(), MerkleError> {
let idx = NodeIndex::make(1, 0);
assert_eq!(smt.get_node(idx).unwrap(), leaves2[0].into());
assert_eq!(store.get_node(smt.root().into(), idx).unwrap(), smt.get_node(idx).unwrap());
assert_eq!(store.get_node(smt.root(), idx).unwrap(), smt.get_node(idx).unwrap());
let idx = NodeIndex::make(1, 1);
assert_eq!(smt.get_node(idx).unwrap(), leaves2[1].into());
@ -222,36 +223,38 @@ fn test_add_sparse_merkle_tree_one_level() -> Result<(), MerkleError> {
#[test]
fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
let smt =
SimpleSmt::with_leaves(SimpleSmt::MAX_DEPTH, KEYS4.into_iter().zip(VALUES4.into_iter()))
.unwrap();
let smt = SimpleSmt::with_leaves(
SimpleSmt::MAX_DEPTH,
KEYS4.into_iter().zip(digests_to_words(&VALUES4).into_iter()),
)
.unwrap();
let store = MerkleStore::from(&smt);
// STORE LEAVES ARE CORRECT ==============================================================
// checks the leaves in the store corresponds to the expected values
assert_eq!(
store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 0)),
Ok(VALUES4[0].into()),
store.get_node(smt.root(), NodeIndex::make(smt.depth(), 0)),
Ok(VALUES4[0]),
"node 0 must be in the tree"
);
assert_eq!(
store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 1)),
Ok(VALUES4[1].into()),
store.get_node(smt.root(), NodeIndex::make(smt.depth(), 1)),
Ok(VALUES4[1]),
"node 1 must be in the tree"
);
assert_eq!(
store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 2)),
Ok(VALUES4[2].into()),
store.get_node(smt.root(), NodeIndex::make(smt.depth(), 2)),
Ok(VALUES4[2]),
"node 2 must be in the tree"
);
assert_eq!(
store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 3)),
Ok(VALUES4[3].into()),
store.get_node(smt.root(), NodeIndex::make(smt.depth(), 3)),
Ok(VALUES4[3]),
"node 3 must be in the tree"
);
assert_eq!(
store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 4)),
store.get_node(smt.root(), NodeIndex::make(smt.depth(), 4)),
Ok(RpoDigest::default()),
"unmodified node 4 must be ZERO"
);
@ -288,7 +291,7 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
// assert the merkle path returned by the store is the same as the one in the tree
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 0)).unwrap();
assert_eq!(
VALUES4[0], *result.value,
VALUES4[0], result.value,
"Value for merkle path at index 0 must match leaf value"
);
assert_eq!(
@ -299,7 +302,7 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 1)).unwrap();
assert_eq!(
VALUES4[1], *result.value,
VALUES4[1], result.value,
"Value for merkle path at index 1 must match leaf value"
);
assert_eq!(
@ -310,7 +313,7 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 2)).unwrap();
assert_eq!(
VALUES4[2], *result.value,
VALUES4[2], result.value,
"Value for merkle path at index 2 must match leaf value"
);
assert_eq!(
@ -321,7 +324,7 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 3)).unwrap();
assert_eq!(
VALUES4[3], *result.value,
VALUES4[3], result.value,
"Value for merkle path at index 3 must match leaf value"
);
assert_eq!(
@ -347,7 +350,7 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
#[test]
fn test_add_merkle_paths() -> Result<(), MerkleError> {
let mtree = MerkleTree::new(VALUES4.to_vec())?;
let mtree = MerkleTree::new(digests_to_words(&VALUES4))?;
let i0 = 0;
let p0 = mtree.get_path(NodeIndex::make(2, i0)).unwrap();
@ -362,10 +365,10 @@ fn test_add_merkle_paths() -> Result<(), MerkleError> {
let p3 = mtree.get_path(NodeIndex::make(2, i3)).unwrap();
let paths = [
(i0, VALUES4[i0 as usize].into(), p0),
(i1, VALUES4[i1 as usize].into(), p1),
(i2, VALUES4[i2 as usize].into(), p2),
(i3, VALUES4[i3 as usize].into(), p3),
(i0, VALUES4[i0 as usize], p0),
(i1, VALUES4[i1 as usize], p1),
(i2, VALUES4[i2 as usize], p2),
(i3, VALUES4[i3 as usize], p3),
];
let mut store = MerkleStore::default();
@ -378,22 +381,22 @@ fn test_add_merkle_paths() -> Result<(), MerkleError> {
// checks the leaves in the store corresponds to the expected values
assert_eq!(
store.get_node(set.root(), NodeIndex::make(set.depth(), 0)),
Ok(VALUES4[0].into()),
Ok(VALUES4[0]),
"node 0 must be in the set"
);
assert_eq!(
store.get_node(set.root(), NodeIndex::make(set.depth(), 1)),
Ok(VALUES4[1].into()),
Ok(VALUES4[1]),
"node 1 must be in the set"
);
assert_eq!(
store.get_node(set.root(), NodeIndex::make(set.depth(), 2)),
Ok(VALUES4[2].into()),
Ok(VALUES4[2]),
"node 2 must be in the set"
);
assert_eq!(
store.get_node(set.root(), NodeIndex::make(set.depth(), 3)),
Ok(VALUES4[3].into()),
Ok(VALUES4[3]),
"node 3 must be in the set"
);
@ -424,7 +427,7 @@ fn test_add_merkle_paths() -> Result<(), MerkleError> {
// assert the merkle path returned by the store is the same as the one in the set
let result = store.get_path(set.root(), NodeIndex::make(set.depth(), 0)).unwrap();
assert_eq!(
VALUES4[0], *result.value,
VALUES4[0], result.value,
"Value for merkle path at index 0 must match leaf value"
);
assert_eq!(
@ -435,7 +438,7 @@ fn test_add_merkle_paths() -> Result<(), MerkleError> {
let result = store.get_path(set.root(), NodeIndex::make(set.depth(), 1)).unwrap();
assert_eq!(
VALUES4[1], *result.value,
VALUES4[1], result.value,
"Value for merkle path at index 0 must match leaf value"
);
assert_eq!(
@ -446,7 +449,7 @@ fn test_add_merkle_paths() -> Result<(), MerkleError> {
let result = store.get_path(set.root(), NodeIndex::make(set.depth(), 2)).unwrap();
assert_eq!(
VALUES4[2], *result.value,
VALUES4[2], result.value,
"Value for merkle path at index 0 must match leaf value"
);
assert_eq!(
@ -457,7 +460,7 @@ fn test_add_merkle_paths() -> Result<(), MerkleError> {
let result = store.get_path(set.root(), NodeIndex::make(set.depth(), 3)).unwrap();
assert_eq!(
VALUES4[3], *result.value,
VALUES4[3], result.value,
"Value for merkle path at index 0 must match leaf value"
);
assert_eq!(
@ -517,7 +520,7 @@ fn store_path_opens_from_leaf() {
let mtree = MerkleTree::new(vec![a, b, c, d, e, f, g, h]).unwrap();
let store = MerkleStore::from(&mtree);
let path = store.get_path(root.into(), NodeIndex::make(3, 1)).unwrap().path;
let path = store.get_path(root, NodeIndex::make(3, 1)).unwrap().path;
let expected = MerklePath::new([a.into(), j.into(), n.into()].to_vec());
assert_eq!(path, expected);
@ -525,7 +528,7 @@ fn store_path_opens_from_leaf() {
#[test]
fn test_set_node() -> Result<(), MerkleError> {
let mtree = MerkleTree::new(VALUES4.to_vec())?;
let mtree = MerkleTree::new(digests_to_words(&VALUES4))?;
let mut store = MerkleStore::from(&mtree);
let value = int_to_node(42);
let index = NodeIndex::make(mtree.depth(), 0);
@ -537,7 +540,7 @@ fn test_set_node() -> Result<(), MerkleError> {
#[test]
fn test_constructors() -> Result<(), MerkleError> {
let mtree = MerkleTree::new(VALUES4.to_vec())?;
let mtree = MerkleTree::new(digests_to_words(&VALUES4))?;
let store = MerkleStore::from(&mtree);
let depth = mtree.depth();
@ -549,7 +552,11 @@ fn test_constructors() -> Result<(), MerkleError> {
}
let depth = 32;
let smt = SimpleSmt::with_leaves(depth, KEYS4.into_iter().zip(VALUES4.into_iter())).unwrap();
let smt = SimpleSmt::with_leaves(
depth,
KEYS4.into_iter().zip(digests_to_words(&VALUES4).into_iter()),
)
.unwrap();
let store = MerkleStore::from(&smt);
let depth = smt.depth();
@ -561,20 +568,20 @@ fn test_constructors() -> Result<(), MerkleError> {
let d = 2;
let paths = [
(0, VALUES4[0].into(), mtree.get_path(NodeIndex::make(d, 0)).unwrap()),
(1, VALUES4[1].into(), mtree.get_path(NodeIndex::make(d, 1)).unwrap()),
(2, VALUES4[2].into(), mtree.get_path(NodeIndex::make(d, 2)).unwrap()),
(3, VALUES4[3].into(), mtree.get_path(NodeIndex::make(d, 3)).unwrap()),
(0, VALUES4[0], mtree.get_path(NodeIndex::make(d, 0)).unwrap()),
(1, VALUES4[1], mtree.get_path(NodeIndex::make(d, 1)).unwrap()),
(2, VALUES4[2], mtree.get_path(NodeIndex::make(d, 2)).unwrap()),
(3, VALUES4[3], mtree.get_path(NodeIndex::make(d, 3)).unwrap()),
];
let mut store1 = MerkleStore::default();
store1.add_merkle_paths(paths.clone())?;
let mut store2 = MerkleStore::default();
store2.add_merkle_path(0, VALUES4[0].into(), mtree.get_path(NodeIndex::make(d, 0))?)?;
store2.add_merkle_path(1, VALUES4[1].into(), mtree.get_path(NodeIndex::make(d, 1))?)?;
store2.add_merkle_path(2, VALUES4[2].into(), mtree.get_path(NodeIndex::make(d, 2))?)?;
store2.add_merkle_path(3, VALUES4[3].into(), mtree.get_path(NodeIndex::make(d, 3))?)?;
store2.add_merkle_path(0, VALUES4[0], mtree.get_path(NodeIndex::make(d, 0))?)?;
store2.add_merkle_path(1, VALUES4[1], mtree.get_path(NodeIndex::make(d, 1))?)?;
store2.add_merkle_path(2, VALUES4[2], mtree.get_path(NodeIndex::make(d, 2))?)?;
store2.add_merkle_path(3, VALUES4[3], mtree.get_path(NodeIndex::make(d, 3))?)?;
let set = MerklePathSet::new(d).with_paths(paths).unwrap();
for key in [0, 1, 2, 3] {
@ -744,16 +751,16 @@ fn get_leaf_depth_works_with_depth_8() {
#[test]
fn mstore_subset() {
// add a Merkle tree of depth 3 to the store
let mtree = MerkleTree::new(VALUES8.to_vec()).unwrap();
let mtree = MerkleTree::new(digests_to_words(&VALUES8)).unwrap();
let mut store = MerkleStore::default();
let empty_store_num_nodes = store.nodes.len();
store.extend(mtree.inner_nodes());
// build 3 subtrees contained within the above Merkle tree; note that subtree2 is a subset
// of subtree1
let subtree1 = MerkleTree::new(VALUES8[..4].to_vec()).unwrap();
let subtree2 = MerkleTree::new(VALUES8[2..4].to_vec()).unwrap();
let subtree3 = MerkleTree::new(VALUES8[6..].to_vec()).unwrap();
let subtree1 = MerkleTree::new(digests_to_words(&VALUES8[..4])).unwrap();
let subtree2 = MerkleTree::new(digests_to_words(&VALUES8[2..4])).unwrap();
let subtree3 = MerkleTree::new(digests_to_words(&VALUES8[6..])).unwrap();
// --- extract all 3 subtrees ---------------------------------------------
@ -798,7 +805,7 @@ fn check_mstore_subtree(store: &MerkleStore, subtree: &MerkleTree) {
#[cfg(feature = "std")]
#[test]
fn test_serialization() -> Result<(), Box<dyn Error>> {
let mtree = MerkleTree::new(VALUES4.to_vec())?;
let mtree = MerkleTree::new(digests_to_words(&VALUES4))?;
let store = MerkleStore::from(&mtree);
let decoded = MerkleStore::read_from_bytes(&store.to_bytes()).expect("deserialization failed");
assert_eq!(store, decoded);

+ 14
- 50
src/merkle/tiered_smt/tests.rs

@ -17,7 +17,7 @@ fn tsmt_insert_one() {
// 16 most significant bits of the key
let index = NodeIndex::make(16, raw >> 48);
let leaf_node = build_leaf_node(key, value, 16);
let tree_root = store.set_node(smt.root().into(), index, leaf_node.into()).unwrap().root;
let tree_root = store.set_node(smt.root(), index, leaf_node).unwrap().root;
smt.insert(key, value);
@ -66,19 +66,11 @@ fn tsmt_insert_two_16() {
let mut tree_root = get_init_root();
let index_a = NodeIndex::make(32, raw_a >> 32);
let leaf_node_a = build_leaf_node(key_a, val_a, 32);
tree_root = store
.set_node(tree_root.into(), index_a, leaf_node_a.into())
.unwrap()
.root
.into();
tree_root = store.set_node(tree_root, index_a, leaf_node_a).unwrap().root;
let index_b = NodeIndex::make(32, raw_b >> 32);
let leaf_node_b = build_leaf_node(key_b, val_b, 32);
tree_root = store
.set_node(tree_root.into(), index_b, leaf_node_b.into())
.unwrap()
.root
.into();
tree_root = store.set_node(tree_root, index_b, leaf_node_b).unwrap().root;
// --- verify that data is consistent between store and tree --------------
@ -130,19 +122,11 @@ fn tsmt_insert_two_32() {
let mut tree_root = get_init_root();
let index_a = NodeIndex::make(48, raw_a >> 16);
let leaf_node_a = build_leaf_node(key_a, val_a, 48);
tree_root = store
.set_node(tree_root.into(), index_a, leaf_node_a.into())
.unwrap()
.root
.into();
tree_root = store.set_node(tree_root, index_a, leaf_node_a).unwrap().root;
let index_b = NodeIndex::make(48, raw_b >> 16);
let leaf_node_b = build_leaf_node(key_b, val_b, 48);
tree_root = store
.set_node(tree_root.into(), index_b, leaf_node_b.into())
.unwrap()
.root
.into();
tree_root = store.set_node(tree_root, index_b, leaf_node_b).unwrap().root;
// --- verify that data is consistent between store and tree --------------
@ -197,27 +181,15 @@ fn tsmt_insert_three() {
let mut tree_root = get_init_root();
let index_a = NodeIndex::make(32, raw_a >> 32);
let leaf_node_a = build_leaf_node(key_a, val_a, 32);
tree_root = store
.set_node(tree_root.into(), index_a, leaf_node_a.into())
.unwrap()
.root
.into();
tree_root = store.set_node(tree_root, index_a, leaf_node_a).unwrap().root;
let index_b = NodeIndex::make(32, raw_b >> 32);
let leaf_node_b = build_leaf_node(key_b, val_b, 32);
tree_root = store
.set_node(tree_root.into(), index_b, leaf_node_b.into())
.unwrap()
.root
.into();
tree_root = store.set_node(tree_root, index_b, leaf_node_b).unwrap().root;
let index_c = NodeIndex::make(32, raw_c >> 32);
let leaf_node_c = build_leaf_node(key_c, val_c, 32);
tree_root = store
.set_node(tree_root.into(), index_c, leaf_node_c.into())
.unwrap()
.root
.into();
tree_root = store.set_node(tree_root, index_c, leaf_node_c).unwrap().root;
// --- verify that data is consistent between store and tree --------------
@ -264,7 +236,7 @@ fn tsmt_update() {
let mut tree_root = get_init_root();
let index = NodeIndex::make(16, raw >> 48);
let leaf_node = build_leaf_node(key, value_b, 16);
tree_root = store.set_node(tree_root.into(), index, leaf_node.into()).unwrap().root.into();
tree_root = store.set_node(tree_root, index, leaf_node).unwrap().root;
assert_eq!(smt.root(), tree_root.into());
@ -309,7 +281,7 @@ fn tsmt_bottom_tier() {
// key_b is smaller than key_a.
let leaf_node = build_bottom_leaf_node(&[key_b, key_a], &[val_b, val_a]);
let mut tree_root = get_init_root();
tree_root = store.set_node(tree_root.into(), index, leaf_node.into()).unwrap().root.into();
tree_root = store.set_node(tree_root, index, leaf_node).unwrap().root;
// --- verify that data is consistent between store and tree --------------
@ -357,19 +329,11 @@ fn tsmt_bottom_tier_two() {
let mut tree_root = get_init_root();
let index_a = NodeIndex::make(64, raw_a);
let leaf_node_a = build_bottom_leaf_node(&[key_a], &[val_a]);
tree_root = store
.set_node(tree_root.into(), index_a, leaf_node_a.into())
.unwrap()
.root
.into();
tree_root = store.set_node(tree_root, index_a, leaf_node_a).unwrap().root;
let index_b = NodeIndex::make(64, raw_b);
let leaf_node_b = build_bottom_leaf_node(&[key_b], &[val_b]);
tree_root = store
.set_node(tree_root.into(), index_b, leaf_node_b.into())
.unwrap()
.root
.into();
tree_root = store.set_node(tree_root, index_b, leaf_node_b).unwrap().root;
// --- verify that data is consistent between store and tree --------------
@ -442,8 +406,8 @@ fn tsmt_node_not_available() {
// HELPER FUNCTIONS
// ================================================================================================
fn get_init_root() -> Word {
EmptySubtreeRoots::empty_hashes(64)[0].into()
fn get_init_root() -> RpoDigest {
EmptySubtreeRoots::empty_hashes(64)[0]
}
fn build_leaf_node(key: RpoDigest, value: Word, depth: u8) -> RpoDigest {

Loading…
Cancel
Save