refactor: refactor crypto APIs to use RpoDigest instead of Word

This commit is contained in:
tohrnii
2023-06-09 21:18:13 +01:00
parent 59f7723221
commit fe9aa8c28c
16 changed files with 590 additions and 376 deletions

View File

@@ -1,6 +1,6 @@
use super::{
mmr::Mmr, BTreeMap, EmptySubtreeRoots, InnerNodeInfo, MerkleError, MerklePath, MerklePathSet,
MerkleTree, NodeIndex, RootPath, Rpo256, RpoDigest, SimpleSmt, TieredSmt, ValuePath, Vec, Word,
MerkleTree, NodeIndex, RootPath, Rpo256, RpoDigest, SimpleSmt, TieredSmt, ValuePath, Vec,
};
use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
use core::borrow::Borrow;
@@ -130,21 +130,20 @@ impl MerkleStore {
/// This method can return the following errors:
/// - `RootNotInStore` if the `root` is not present in the store.
/// - `NodeNotInStore` if a node needed to traverse from `root` to `index` is not present in the store.
pub fn get_node(&self, root: Word, index: NodeIndex) -> Result<Word, MerkleError> {
let mut hash: RpoDigest = root.into();
pub fn get_node(&self, root: RpoDigest, index: NodeIndex) -> Result<RpoDigest, MerkleError> {
let mut hash = root;
// corner case: check the root is in the store when called with index `NodeIndex::root()`
self.nodes.get(&hash).ok_or(MerkleError::RootNotInStore(hash.into()))?;
self.nodes.get(&hash).ok_or(MerkleError::RootNotInStore(hash))?;
for i in (0..index.depth()).rev() {
let node =
self.nodes.get(&hash).ok_or(MerkleError::NodeNotInStore(hash.into(), index))?;
let node = self.nodes.get(&hash).ok_or(MerkleError::NodeNotInStore(hash, index))?;
let bit = (index.value() >> i) & 1;
hash = if bit == 0 { node.left } else { node.right }
}
Ok(hash.into())
Ok(hash)
}
/// Returns the node at the specified `index` and its opening to the `root`.
@@ -155,23 +154,22 @@ impl MerkleStore {
/// This method can return the following errors:
/// - `RootNotInStore` if the `root` is not present in the store.
/// - `NodeNotInStore` if a node needed to traverse from `root` to `index` is not present in the store.
pub fn get_path(&self, root: Word, index: NodeIndex) -> Result<ValuePath, MerkleError> {
let mut hash: RpoDigest = root.into();
pub fn get_path(&self, root: RpoDigest, index: NodeIndex) -> Result<ValuePath, MerkleError> {
let mut hash = root;
let mut path = Vec::with_capacity(index.depth().into());
// corner case: check the root is in the store when called with index `NodeIndex::root()`
self.nodes.get(&hash).ok_or(MerkleError::RootNotInStore(hash.into()))?;
self.nodes.get(&hash).ok_or(MerkleError::RootNotInStore(hash))?;
for i in (0..index.depth()).rev() {
let node =
self.nodes.get(&hash).ok_or(MerkleError::NodeNotInStore(hash.into(), index))?;
let node = self.nodes.get(&hash).ok_or(MerkleError::NodeNotInStore(hash, index))?;
let bit = (index.value() >> i) & 1;
hash = if bit == 0 {
path.push(node.right.into());
path.push(node.right);
node.left
} else {
path.push(node.left.into());
path.push(node.left);
node.right
}
}
@@ -180,7 +178,7 @@ impl MerkleStore {
path.reverse();
Ok(ValuePath {
value: hash.into(),
value: hash,
path: MerklePath::new(path),
})
}
@@ -202,7 +200,7 @@ impl MerkleStore {
/// information, check [NodeIndex::new].
pub fn get_leaf_depth(
&self,
root: Word,
root: RpoDigest,
tree_depth: u8,
index: u64,
) -> Result<u8, MerkleError> {
@@ -221,9 +219,9 @@ impl MerkleStore {
// check if the root exists, providing the proper error report if it doesn't
let empty = EmptySubtreeRoots::empty_hashes(tree_depth);
let mut hash: RpoDigest = root.into();
let mut hash = root;
if !self.nodes.contains_key(&hash) {
return Err(MerkleError::RootNotInStore(hash.into()));
return Err(MerkleError::RootNotInStore(hash));
}
// we traverse from root to leaf, so the path is reversed
@@ -266,11 +264,11 @@ impl MerkleStore {
pub fn subset<I, R>(&self, roots: I) -> MerkleStore
where
I: Iterator<Item = R>,
R: Borrow<Word>,
R: Borrow<RpoDigest>,
{
let mut store = MerkleStore::new();
for root in roots {
let root = RpoDigest::from(*root.borrow());
let root = *root.borrow();
store.clone_tree_from(root, self);
}
store
@@ -279,9 +277,9 @@ impl MerkleStore {
/// Iterator over the inner nodes of the [MerkleStore].
pub fn inner_nodes(&self) -> impl Iterator<Item = InnerNodeInfo> + '_ {
self.nodes.iter().map(|(r, n)| InnerNodeInfo {
value: r.into(),
left: n.left.into(),
right: n.right.into(),
value: *r,
left: n.left,
right: n.right,
})
}
@@ -294,9 +292,9 @@ impl MerkleStore {
I: Iterator<Item = InnerNodeInfo>,
{
for node in iter {
let value: RpoDigest = node.value.into();
let left: RpoDigest = node.left.into();
let right: RpoDigest = node.right.into();
let value: RpoDigest = node.value;
let left: RpoDigest = node.left;
let right: RpoDigest = node.right;
debug_assert_eq!(Rpo256::merge(&[left, right]), value);
self.nodes.insert(value, Node { left, right });
@@ -313,13 +311,13 @@ impl MerkleStore {
pub fn add_merkle_path(
&mut self,
index: u64,
node: Word,
node: RpoDigest,
path: MerklePath,
) -> Result<Word, MerkleError> {
let root = path.inner_nodes(index, node)?.fold(Word::default(), |_, node| {
let value: RpoDigest = node.value.into();
let left: RpoDigest = node.left.into();
let right: RpoDigest = node.right.into();
) -> Result<RpoDigest, MerkleError> {
let root = path.inner_nodes(index, node)?.fold(RpoDigest::default(), |_, node| {
let value: RpoDigest = node.value;
let left: RpoDigest = node.left;
let right: RpoDigest = node.right;
debug_assert_eq!(Rpo256::merge(&[left, right]), value);
self.nodes.insert(value, Node { left, right });
@@ -337,7 +335,7 @@ impl MerkleStore {
/// For further reference, check [MerkleStore::add_merkle_path].
pub fn add_merkle_paths<I>(&mut self, paths: I) -> Result<(), MerkleError>
where
I: IntoIterator<Item = (u64, Word, MerklePath)>,
I: IntoIterator<Item = (u64, RpoDigest, MerklePath)>,
{
for (index_value, node, path) in paths.into_iter() {
self.add_merkle_path(index_value, node, path)?;
@@ -348,7 +346,10 @@ impl MerkleStore {
/// Appends the provided [MerklePathSet] into the store.
///
/// For further reference, check [MerkleStore::add_merkle_path].
pub fn add_merkle_path_set(&mut self, path_set: &MerklePathSet) -> Result<Word, MerkleError> {
pub fn add_merkle_path_set(
&mut self,
path_set: &MerklePathSet,
) -> Result<RpoDigest, MerkleError> {
let root = path_set.root();
for (index, path) in path_set.to_paths() {
self.add_merkle_path(index, path.value, path.path)?;
@@ -365,9 +366,9 @@ impl MerkleStore {
/// - `NodeNotInStore` if a node needed to traverse from `root` to `index` is not present in the store.
pub fn set_node(
&mut self,
mut root: Word,
mut root: RpoDigest,
index: NodeIndex,
value: Word,
value: RpoDigest,
) -> Result<RootPath, MerkleError> {
let node = value;
let ValuePath { value, path } = self.get_path(root, index)?;
@@ -383,14 +384,21 @@ impl MerkleStore {
/// Merges two elements and adds the resulting node into the store.
///
/// Merges arbitrary values. They may be leafs, nodes, or a mixture of both.
pub fn merge_roots(&mut self, root1: Word, root2: Word) -> Result<Word, MerkleError> {
let left: RpoDigest = root1.into();
let right: RpoDigest = root2.into();
pub fn merge_roots(
&mut self,
left_root: RpoDigest,
right_root: RpoDigest,
) -> Result<RpoDigest, MerkleError> {
let parent = Rpo256::merge(&[left_root, right_root]);
self.nodes.insert(
parent,
Node {
left: left_root,
right: right_root,
},
);
let parent = Rpo256::merge(&[left, right]);
self.nodes.insert(parent, Node { left, right });
Ok(parent.into())
Ok(parent)
}
// HELPER METHODS
@@ -404,7 +412,7 @@ impl MerkleStore {
if let Some(node) = source.nodes.get(&root) {
// if the node has already been inserted, no need to process it further as all of its
// descendants should be already cloned from the source store
if matches!(self.nodes.insert(root, *node), None) {
if self.nodes.insert(root, *node).is_none() {
self.clone_tree_from(node.left, source);
self.clone_tree_from(node.right, source);
}

View File

@@ -1,10 +1,10 @@
use super::{
super::EMPTY_WORD, Deserializable, EmptySubtreeRoots, MerkleError, MerklePath, MerkleStore,
NodeIndex, RpoDigest, Serializable,
Deserializable, EmptySubtreeRoots, MerkleError, MerklePath, MerkleStore, NodeIndex, RpoDigest,
Serializable,
};
use crate::{
hash::rpo::Rpo256,
merkle::{int_to_node, MerklePathSet, MerkleTree, SimpleSmt},
merkle::{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_node(1), int_to_node(2), int_to_node(3), int_to_node(4)];
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_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),
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),
];
// TESTS
@@ -36,13 +36,13 @@ fn test_root_not_in_store() -> Result<(), MerkleError> {
let mtree = MerkleTree::new(VALUES4.to_vec())?;
let store = MerkleStore::from(&mtree);
assert_eq!(
store.get_node(VALUES4[0], NodeIndex::make(mtree.depth(), 0)),
Err(MerkleError::RootNotInStore(VALUES4[0])),
store.get_node(VALUES4[0].into(), NodeIndex::make(mtree.depth(), 0)),
Err(MerkleError::RootNotInStore(VALUES4[0].into())),
"Leaf 0 is not a root"
);
assert_eq!(
store.get_path(VALUES4[0], NodeIndex::make(mtree.depth(), 0)),
Err(MerkleError::RootNotInStore(VALUES4[0])),
store.get_path(VALUES4[0].into(), NodeIndex::make(mtree.depth(), 0)),
Err(MerkleError::RootNotInStore(VALUES4[0].into())),
"Leaf 0 is not a root"
);
@@ -58,22 +58,22 @@ fn test_merkle_tree() -> Result<(), MerkleError> {
// 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]),
Ok(VALUES4[0].into()),
"node 0 must be in the tree"
);
assert_eq!(
store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 1)),
Ok(VALUES4[1]),
Ok(VALUES4[1].into()),
"node 1 must be in the tree"
);
assert_eq!(
store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 2)),
Ok(VALUES4[2]),
Ok(VALUES4[2].into()),
"node 2 must be in the tree"
);
assert_eq!(
store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 3)),
Ok(VALUES4[3]),
Ok(VALUES4[3].into()),
"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!(
@@ -152,7 +152,7 @@ fn test_merkle_tree() -> Result<(), MerkleError> {
#[test]
fn test_empty_roots() {
let store = MerkleStore::default();
let mut root = RpoDigest::new(EMPTY_WORD);
let mut root = RpoDigest::default();
for depth in 0..255 {
root = Rpo256::merge(&[root; 2]);
@@ -176,13 +176,17 @@ fn test_leaf_paths_for_empty_trees() -> Result<(), MerkleError> {
let index = NodeIndex::make(depth, 0);
let store_path = store.get_path(smt.root(), index)?;
let smt_path = smt.get_path(index)?;
assert_eq!(store_path.value, EMPTY_WORD, "the leaf of an empty tree is always ZERO");
assert_eq!(
store_path.value,
RpoDigest::default(),
"the leaf of an empty tree is always ZERO"
);
assert_eq!(
store_path.path, smt_path,
"the returned merkle path does not match the computed values"
);
assert_eq!(
store_path.path.compute_root(depth.into(), EMPTY_WORD).unwrap(),
store_path.path.compute_root(depth.into(), RpoDigest::default()).unwrap(),
smt.root(),
"computed root from the path must match the empty tree root"
);
@@ -201,16 +205,16 @@ fn test_get_invalid_node() {
#[test]
fn test_add_sparse_merkle_tree_one_level() -> Result<(), MerkleError> {
let keys2: [u64; 2] = [0, 1];
let leaves2: [Word; 2] = [int_to_node(1), int_to_node(2)];
let leaves2: [Word; 2] = [int_to_leaf(1), int_to_leaf(2)];
let smt = SimpleSmt::with_leaves(1, keys2.into_iter().zip(leaves2.into_iter())).unwrap();
let store = MerkleStore::from(&smt);
let idx = NodeIndex::make(1, 0);
assert_eq!(smt.get_node(idx).unwrap(), leaves2[0]);
assert_eq!(store.get_node(smt.root(), idx).unwrap(), smt.get_node(idx).unwrap());
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());
let idx = NodeIndex::make(1, 1);
assert_eq!(smt.get_node(idx).unwrap(), leaves2[1]);
assert_eq!(smt.get_node(idx).unwrap(), leaves2[1].into());
assert_eq!(store.get_node(smt.root(), idx).unwrap(), smt.get_node(idx).unwrap());
Ok(())
@@ -227,28 +231,28 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
// STORE LEAVES ARE CORRECT ==============================================================
// checks the leaves in the store corresponds to the expected values
assert_eq!(
store.get_node(smt.root(), NodeIndex::make(smt.depth(), 0)),
Ok(VALUES4[0]),
store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 0)),
Ok(VALUES4[0].into()),
"node 0 must be in the tree"
);
assert_eq!(
store.get_node(smt.root(), NodeIndex::make(smt.depth(), 1)),
Ok(VALUES4[1]),
store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 1)),
Ok(VALUES4[1].into()),
"node 1 must be in the tree"
);
assert_eq!(
store.get_node(smt.root(), NodeIndex::make(smt.depth(), 2)),
Ok(VALUES4[2]),
store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 2)),
Ok(VALUES4[2].into()),
"node 2 must be in the tree"
);
assert_eq!(
store.get_node(smt.root(), NodeIndex::make(smt.depth(), 3)),
Ok(VALUES4[3]),
store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 3)),
Ok(VALUES4[3].into()),
"node 3 must be in the tree"
);
assert_eq!(
store.get_node(smt.root(), NodeIndex::make(smt.depth(), 4)),
Ok(EMPTY_WORD),
store.get_node(smt.root().into(), NodeIndex::make(smt.depth(), 4)),
Ok(RpoDigest::default()),
"unmodified node 4 must be ZERO"
);
@@ -284,7 +288,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!(
@@ -295,7 +299,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!(
@@ -306,7 +310,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!(
@@ -317,7 +321,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!(
@@ -328,7 +332,8 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
let result = store.get_path(smt.root(), NodeIndex::make(smt.depth(), 4)).unwrap();
assert_eq!(
EMPTY_WORD, result.value,
RpoDigest::default(),
result.value,
"Value for merkle path at index 4 must match leaf value"
);
assert_eq!(
@@ -357,10 +362,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], p0),
(i1, VALUES4[i1 as usize], p1),
(i2, VALUES4[i2 as usize], p2),
(i3, VALUES4[i3 as usize], p3),
(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),
];
let mut store = MerkleStore::default();
@@ -373,22 +378,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]),
Ok(VALUES4[0].into()),
"node 0 must be in the set"
);
assert_eq!(
store.get_node(set.root(), NodeIndex::make(set.depth(), 1)),
Ok(VALUES4[1]),
Ok(VALUES4[1].into()),
"node 1 must be in the set"
);
assert_eq!(
store.get_node(set.root(), NodeIndex::make(set.depth(), 2)),
Ok(VALUES4[2]),
Ok(VALUES4[2].into()),
"node 2 must be in the set"
);
assert_eq!(
store.get_node(set.root(), NodeIndex::make(set.depth(), 3)),
Ok(VALUES4[3]),
Ok(VALUES4[3].into()),
"node 3 must be in the set"
);
@@ -419,7 +424,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!(
@@ -430,7 +435,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!(
@@ -441,7 +446,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!(
@@ -452,7 +457,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!(
@@ -477,7 +482,7 @@ fn wont_open_to_different_depth_root() {
for depth in (1..=63).rev() {
root = Rpo256::merge(&[root, empty[depth]]);
}
let root = Word::from(root);
let root = RpoDigest::from(root);
// For this example, the depth of the Merkle tree is 1, as we have only two leaves. Here we
// attempt to fetch a node on the maximum depth, and it should fail because the root shouldn't
@@ -556,20 +561,20 @@ fn test_constructors() -> Result<(), MerkleError> {
let d = 2;
let paths = [
(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()),
(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()),
];
let mut store1 = MerkleStore::default();
store1.add_merkle_paths(paths.clone())?;
let mut store2 = MerkleStore::default();
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))?)?;
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))?)?;
let set = MerklePathSet::new(d).with_paths(paths).unwrap();
for key in [0, 1, 2, 3] {
@@ -590,11 +595,11 @@ fn node_path_should_be_truncated_by_midtier_insert() {
let key = 0b11010010_11001100_11001100_11001100_11001100_11001100_11001100_11001100_u64;
let mut store = MerkleStore::new();
let root: Word = EmptySubtreeRoots::empty_hashes(64)[0].into();
let root: RpoDigest = EmptySubtreeRoots::empty_hashes(64)[0];
// insert first node - works as expected
let depth = 64;
let node = [Felt::new(key); WORD_SIZE];
let node = RpoDigest::from([Felt::new(key); WORD_SIZE]);
let index = NodeIndex::new(depth, key).unwrap();
let root = store.set_node(root, index, node).unwrap().root;
let result = store.get_node(root, index).unwrap();
@@ -607,7 +612,7 @@ fn node_path_should_be_truncated_by_midtier_insert() {
let key = key ^ (1 << 63);
let key = key >> 8;
let depth = 56;
let node = [Felt::new(key); WORD_SIZE];
let node = RpoDigest::from([Felt::new(key); WORD_SIZE]);
let index = NodeIndex::new(depth, key).unwrap();
let root = store.set_node(root, index, node).unwrap().root;
let result = store.get_node(root, index).unwrap();
@@ -626,13 +631,13 @@ fn node_path_should_be_truncated_by_midtier_insert() {
#[test]
fn get_leaf_depth_works_depth_64() {
let mut store = MerkleStore::new();
let mut root: Word = EmptySubtreeRoots::empty_hashes(64)[0].into();
let mut root: RpoDigest = EmptySubtreeRoots::empty_hashes(64)[0];
let key = u64::MAX;
// this will create a rainbow tree and test all opening to depth 64
for d in 0..64 {
let k = key & (u64::MAX >> d);
let node = [Felt::new(k); WORD_SIZE];
let node = RpoDigest::from([Felt::new(k); WORD_SIZE]);
let index = NodeIndex::new(64, k).unwrap();
// assert the leaf doesn't exist before the insert. the returned depth should always
@@ -649,14 +654,14 @@ fn get_leaf_depth_works_depth_64() {
#[test]
fn get_leaf_depth_works_with_incremental_depth() {
let mut store = MerkleStore::new();
let mut root: Word = EmptySubtreeRoots::empty_hashes(64)[0].into();
let mut root: RpoDigest = EmptySubtreeRoots::empty_hashes(64)[0];
// insert some path to the left of the root and assert it
let key = 0b01001011_10110110_00001101_01110100_00111011_10101101_00000100_01000001_u64;
assert_eq!(0, store.get_leaf_depth(root, 64, key).unwrap());
let depth = 64;
let index = NodeIndex::new(depth, key).unwrap();
let node = [Felt::new(key); WORD_SIZE];
let node = RpoDigest::from([Felt::new(key); WORD_SIZE]);
root = store.set_node(root, index, node).unwrap().root;
assert_eq!(depth, store.get_leaf_depth(root, 64, key).unwrap());
@@ -665,7 +670,7 @@ fn get_leaf_depth_works_with_incremental_depth() {
assert_eq!(1, store.get_leaf_depth(root, 64, key).unwrap());
let depth = 16;
let index = NodeIndex::new(depth, key >> (64 - depth)).unwrap();
let node = [Felt::new(key); WORD_SIZE];
let node = RpoDigest::from([Felt::new(key); WORD_SIZE]);
root = store.set_node(root, index, node).unwrap().root;
assert_eq!(depth, store.get_leaf_depth(root, 64, key).unwrap());
@@ -673,7 +678,7 @@ fn get_leaf_depth_works_with_incremental_depth() {
let key = 0b11001011_10110111_00000000_00000000_00000000_00000000_00000000_00000000_u64;
assert_eq!(16, store.get_leaf_depth(root, 64, key).unwrap());
let index = NodeIndex::new(depth, key >> (64 - depth)).unwrap();
let node = [Felt::new(key); WORD_SIZE];
let node = RpoDigest::from([Felt::new(key); WORD_SIZE]);
root = store.set_node(root, index, node).unwrap().root;
assert_eq!(depth, store.get_leaf_depth(root, 64, key).unwrap());
@@ -682,7 +687,7 @@ fn get_leaf_depth_works_with_incremental_depth() {
assert_eq!(15, store.get_leaf_depth(root, 64, key).unwrap());
let depth = 17;
let index = NodeIndex::new(depth, key >> (64 - depth)).unwrap();
let node = [Felt::new(key); WORD_SIZE];
let node = RpoDigest::from([Felt::new(key); WORD_SIZE]);
root = store.set_node(root, index, node).unwrap().root;
assert_eq!(depth, store.get_leaf_depth(root, 64, key).unwrap());
}
@@ -690,7 +695,7 @@ fn get_leaf_depth_works_with_incremental_depth() {
#[test]
fn get_leaf_depth_works_with_depth_8() {
let mut store = MerkleStore::new();
let mut root: Word = EmptySubtreeRoots::empty_hashes(8)[0].into();
let mut root: RpoDigest = EmptySubtreeRoots::empty_hashes(8)[0];
// insert some random, 8 depth keys. `a` diverges from the first bit
let a = 0b01101001_u64;
@@ -700,7 +705,7 @@ fn get_leaf_depth_works_with_depth_8() {
for k in [a, b, c, d] {
let index = NodeIndex::new(8, k).unwrap();
let node = [Felt::new(k); WORD_SIZE];
let node = RpoDigest::from([Felt::new(k); WORD_SIZE]);
root = store.set_node(root, index, node).unwrap().root;
}
@@ -780,7 +785,7 @@ fn check_mstore_subtree(store: &MerkleStore, subtree: &MerkleTree) {
for (i, value) in subtree.leaves() {
let index = NodeIndex::new(subtree.depth(), i).unwrap();
let path1 = store.get_path(subtree.root(), index).unwrap();
assert_eq!(&path1.value, value);
assert_eq!(*path1.value, *value);
let path2 = subtree.get_path(index).unwrap();
assert_eq!(path1.path, path2);