Merge pull request #139 from 0xPolygonMiden/hacka-support-adding-existing-structures-to-store
store: support adding existing structures
This commit is contained in:
commit
ae4e27b6c7
5 changed files with 216 additions and 233 deletions
|
@ -34,7 +34,7 @@ fn get_empty_leaf_simplesmt(c: &mut Criterion) {
|
||||||
// both SMT and the store are pre-populated with empty hashes, accessing these values is what is
|
// both SMT and the store are pre-populated with empty hashes, accessing these values is what is
|
||||||
// being benchmarked here, so no values are inserted into the backends
|
// being benchmarked here, so no values are inserted into the backends
|
||||||
let smt = SimpleSmt::new(depth).unwrap();
|
let smt = SimpleSmt::new(depth).unwrap();
|
||||||
let store = MerkleStore::new();
|
let store = MerkleStore::from(&smt);
|
||||||
let root = smt.root();
|
let root = smt.root();
|
||||||
|
|
||||||
group.bench_function(BenchmarkId::new("SimpleSmt", depth), |b| {
|
group.bench_function(BenchmarkId::new("SimpleSmt", depth), |b| {
|
||||||
|
@ -66,7 +66,7 @@ fn get_leaf_merkletree(c: &mut Criterion) {
|
||||||
|
|
||||||
let mtree_leaves: Vec<Word> = leaves.iter().map(|v| v.into()).collect();
|
let mtree_leaves: Vec<Word> = leaves.iter().map(|v| v.into()).collect();
|
||||||
let mtree = MerkleTree::new(mtree_leaves.clone()).unwrap();
|
let mtree = MerkleTree::new(mtree_leaves.clone()).unwrap();
|
||||||
let store = MerkleStore::new().with_merkle_tree(mtree_leaves).unwrap();
|
let store = MerkleStore::from(&mtree);
|
||||||
let depth = mtree.depth();
|
let depth = mtree.depth();
|
||||||
let root = mtree.root();
|
let root = mtree.root();
|
||||||
let size_u64 = size as u64;
|
let size_u64 = size as u64;
|
||||||
|
@ -108,9 +108,7 @@ fn get_leaf_simplesmt(c: &mut Criterion) {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.with_leaves(smt_leaves.clone())
|
.with_leaves(smt_leaves.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let store = MerkleStore::new()
|
let store = MerkleStore::from(&smt);
|
||||||
.with_sparse_merkle_tree(SimpleSmt::MAX_DEPTH, smt_leaves)
|
|
||||||
.unwrap();
|
|
||||||
let depth = smt.depth();
|
let depth = smt.depth();
|
||||||
let root = smt.root();
|
let root = smt.root();
|
||||||
let size_u64 = size as u64;
|
let size_u64 = size as u64;
|
||||||
|
@ -143,7 +141,7 @@ fn get_node_of_empty_simplesmt(c: &mut Criterion) {
|
||||||
// of these values is what is being benchmarked here, so no values are inserted into the
|
// of these values is what is being benchmarked here, so no values are inserted into the
|
||||||
// backends.
|
// backends.
|
||||||
let smt = SimpleSmt::new(depth).unwrap();
|
let smt = SimpleSmt::new(depth).unwrap();
|
||||||
let store = MerkleStore::new();
|
let store = MerkleStore::from(&smt);
|
||||||
let root = smt.root();
|
let root = smt.root();
|
||||||
let half_depth = depth / 2;
|
let half_depth = depth / 2;
|
||||||
let half_size = 2_u64.pow(half_depth as u32);
|
let half_size = 2_u64.pow(half_depth as u32);
|
||||||
|
@ -178,7 +176,7 @@ fn get_node_merkletree(c: &mut Criterion) {
|
||||||
|
|
||||||
let mtree_leaves: Vec<Word> = leaves.iter().map(|v| v.into()).collect();
|
let mtree_leaves: Vec<Word> = leaves.iter().map(|v| v.into()).collect();
|
||||||
let mtree = MerkleTree::new(mtree_leaves.clone()).unwrap();
|
let mtree = MerkleTree::new(mtree_leaves.clone()).unwrap();
|
||||||
let store = MerkleStore::new().with_merkle_tree(mtree_leaves).unwrap();
|
let store = MerkleStore::from(&mtree);
|
||||||
let root = mtree.root();
|
let root = mtree.root();
|
||||||
let half_depth = mtree.depth() / 2;
|
let half_depth = mtree.depth() / 2;
|
||||||
let half_size = 2_u64.pow(half_depth as u32);
|
let half_size = 2_u64.pow(half_depth as u32);
|
||||||
|
@ -221,9 +219,7 @@ fn get_node_simplesmt(c: &mut Criterion) {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.with_leaves(smt_leaves.clone())
|
.with_leaves(smt_leaves.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let store = MerkleStore::new()
|
let store = MerkleStore::from(&smt);
|
||||||
.with_sparse_merkle_tree(SimpleSmt::MAX_DEPTH, smt_leaves)
|
|
||||||
.unwrap();
|
|
||||||
let root = smt.root();
|
let root = smt.root();
|
||||||
let half_depth = smt.depth() / 2;
|
let half_depth = smt.depth() / 2;
|
||||||
let half_size = 2_u64.pow(half_depth as u32);
|
let half_size = 2_u64.pow(half_depth as u32);
|
||||||
|
@ -258,7 +254,7 @@ fn get_leaf_path_merkletree(c: &mut Criterion) {
|
||||||
|
|
||||||
let mtree_leaves: Vec<Word> = leaves.iter().map(|v| v.into()).collect();
|
let mtree_leaves: Vec<Word> = leaves.iter().map(|v| v.into()).collect();
|
||||||
let mtree = MerkleTree::new(mtree_leaves.clone()).unwrap();
|
let mtree = MerkleTree::new(mtree_leaves.clone()).unwrap();
|
||||||
let store = MerkleStore::new().with_merkle_tree(mtree_leaves).unwrap();
|
let store = MerkleStore::from(&mtree);
|
||||||
let depth = mtree.depth();
|
let depth = mtree.depth();
|
||||||
let root = mtree.root();
|
let root = mtree.root();
|
||||||
let size_u64 = size as u64;
|
let size_u64 = size as u64;
|
||||||
|
@ -300,9 +296,7 @@ fn get_leaf_path_simplesmt(c: &mut Criterion) {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.with_leaves(smt_leaves.clone())
|
.with_leaves(smt_leaves.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let store = MerkleStore::new()
|
let store = MerkleStore::from(&smt);
|
||||||
.with_sparse_merkle_tree(SimpleSmt::MAX_DEPTH, smt_leaves)
|
|
||||||
.unwrap();
|
|
||||||
let depth = smt.depth();
|
let depth = smt.depth();
|
||||||
let root = smt.root();
|
let root = smt.root();
|
||||||
let size_u64 = size as u64;
|
let size_u64 = size as u64;
|
||||||
|
@ -347,10 +341,13 @@ fn new(c: &mut Criterion) {
|
||||||
|
|
||||||
// This could be done with `bench_with_input`, however to remove variables while comparing
|
// This could be done with `bench_with_input`, however to remove variables while comparing
|
||||||
// with MerkleTree it is using `iter_batched`
|
// with MerkleTree it is using `iter_batched`
|
||||||
group.bench_function(BenchmarkId::new("MerkleStore::with_merkle_tree", size), |b| {
|
group.bench_function(BenchmarkId::new("MerkleStore::extend::MerkleTree", size), |b| {
|
||||||
b.iter_batched(
|
b.iter_batched(
|
||||||
|| leaves.iter().map(|v| v.into()).collect::<Vec<Word>>(),
|
|| leaves.iter().map(|v| v.into()).collect::<Vec<Word>>(),
|
||||||
|l| black_box(MerkleStore::new().with_merkle_tree(l)),
|
|l| {
|
||||||
|
let mtree = MerkleTree::new(l).unwrap();
|
||||||
|
black_box(MerkleStore::from(&mtree));
|
||||||
|
},
|
||||||
BatchSize::SmallInput,
|
BatchSize::SmallInput,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -369,7 +366,7 @@ fn new(c: &mut Criterion) {
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
group.bench_function(BenchmarkId::new("MerkleStore::with_sparse_merkle_tree", size), |b| {
|
group.bench_function(BenchmarkId::new("MerkleStore::extend::SimpleSmt", size), |b| {
|
||||||
b.iter_batched(
|
b.iter_batched(
|
||||||
|| {
|
|| {
|
||||||
leaves
|
leaves
|
||||||
|
@ -378,7 +375,10 @@ fn new(c: &mut Criterion) {
|
||||||
.map(|(c, v)| (c.try_into().unwrap(), v.into()))
|
.map(|(c, v)| (c.try_into().unwrap(), v.into()))
|
||||||
.collect::<Vec<(u64, Word)>>()
|
.collect::<Vec<(u64, Word)>>()
|
||||||
},
|
},
|
||||||
|l| black_box(MerkleStore::new().with_sparse_merkle_tree(SimpleSmt::MAX_DEPTH, l)),
|
|l| {
|
||||||
|
let smt = SimpleSmt::new(SimpleSmt::MAX_DEPTH).unwrap().with_leaves(l).unwrap();
|
||||||
|
black_box(MerkleStore::from(&smt));
|
||||||
|
},
|
||||||
BatchSize::SmallInput,
|
BatchSize::SmallInput,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -397,7 +397,7 @@ fn update_leaf_merkletree(c: &mut Criterion) {
|
||||||
|
|
||||||
let mtree_leaves: Vec<Word> = leaves.iter().map(|v| v.into()).collect();
|
let mtree_leaves: Vec<Word> = leaves.iter().map(|v| v.into()).collect();
|
||||||
let mut mtree = MerkleTree::new(mtree_leaves.clone()).unwrap();
|
let mut mtree = MerkleTree::new(mtree_leaves.clone()).unwrap();
|
||||||
let mut store = MerkleStore::new().with_merkle_tree(mtree_leaves).unwrap();
|
let mut store = MerkleStore::from(&mtree);
|
||||||
let depth = mtree.depth();
|
let depth = mtree.depth();
|
||||||
let root = mtree.root();
|
let root = mtree.root();
|
||||||
let size_u64 = size as u64;
|
let size_u64 = size as u64;
|
||||||
|
@ -446,9 +446,7 @@ fn update_leaf_simplesmt(c: &mut Criterion) {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.with_leaves(smt_leaves.clone())
|
.with_leaves(smt_leaves.clone())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut store = MerkleStore::new()
|
let mut store = MerkleStore::from(&smt);
|
||||||
.with_sparse_merkle_tree(SimpleSmt::MAX_DEPTH, smt_leaves)
|
|
||||||
.unwrap();
|
|
||||||
let depth = smt.depth();
|
let depth = smt.depth();
|
||||||
let root = smt.root();
|
let root = smt.root();
|
||||||
let size_u64 = size as u64;
|
let size_u64 = size as u64;
|
||||||
|
|
|
@ -150,9 +150,11 @@ impl MerkleTree {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator over every inner node in the tree. The iterator order is unspecified.
|
/// Returns n iterator over every inner node of this [MerkleTree].
|
||||||
pub fn inner_nodes(&self) -> MerkleTreeNodes<'_> {
|
///
|
||||||
MerkleTreeNodes {
|
/// The iterator order is unspecified.
|
||||||
|
pub fn inner_nodes(&self) -> InnerNodeIterator<'_> {
|
||||||
|
InnerNodeIterator {
|
||||||
nodes: &self.nodes,
|
nodes: &self.nodes,
|
||||||
index: 1, // index 0 is just padding, start at 1
|
index: 1, // index 0 is just padding, start at 1
|
||||||
}
|
}
|
||||||
|
@ -165,12 +167,12 @@ impl MerkleTree {
|
||||||
/// An iterator over every inner node of the [MerkleTree].
|
/// An iterator over every inner node of the [MerkleTree].
|
||||||
///
|
///
|
||||||
/// Use this to extract the data of the tree, there is no guarantee on the order of the elements.
|
/// Use this to extract the data of the tree, there is no guarantee on the order of the elements.
|
||||||
pub struct MerkleTreeNodes<'a> {
|
pub struct InnerNodeIterator<'a> {
|
||||||
nodes: &'a Vec<Word>,
|
nodes: &'a Vec<Word>,
|
||||||
index: usize,
|
index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for MerkleTreeNodes<'a> {
|
impl<'a> Iterator for InnerNodeIterator<'a> {
|
||||||
type Item = InnerNodeInfo;
|
type Item = InnerNodeInfo;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
@ -192,6 +194,9 @@ impl<'a> Iterator for MerkleTreeNodes<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UTILITY FUNCTIONS
|
||||||
|
// ================================================================================================
|
||||||
|
|
||||||
/// Utility to visualize a [MerkleTree] in text.
|
/// Utility to visualize a [MerkleTree] in text.
|
||||||
pub fn tree_to_text(tree: &MerkleTree) -> Result<String, fmt::Error> {
|
pub fn tree_to_text(tree: &MerkleTree) -> Result<String, fmt::Error> {
|
||||||
let indent = " ";
|
let indent = " ";
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{vec, MerkleError, NodeIndex, Rpo256, Vec, Word};
|
use super::{vec, InnerNodeInfo, MerkleError, NodeIndex, Rpo256, Vec, Word};
|
||||||
use core::ops::{Deref, DerefMut};
|
use core::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
// MERKLE PATH
|
// MERKLE PATH
|
||||||
|
@ -22,6 +22,11 @@ impl MerklePath {
|
||||||
// PROVIDERS
|
// PROVIDERS
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// Returns the depth in which this Merkle path proof is valid.
|
||||||
|
pub fn depth(&self) -> u8 {
|
||||||
|
self.nodes.len() as u8
|
||||||
|
}
|
||||||
|
|
||||||
/// Computes the merkle root for this opening.
|
/// Computes the merkle root for this opening.
|
||||||
pub fn compute_root(&self, index: u64, node: Word) -> Result<Word, MerkleError> {
|
pub fn compute_root(&self, index: u64, node: Word) -> Result<Word, MerkleError> {
|
||||||
let mut index = NodeIndex::new(self.depth(), index)?;
|
let mut index = NodeIndex::new(self.depth(), index)?;
|
||||||
|
@ -34,11 +39,6 @@ impl MerklePath {
|
||||||
Ok(root)
|
Ok(root)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the depth in which this Merkle path proof is valid.
|
|
||||||
pub fn depth(&self) -> u8 {
|
|
||||||
self.nodes.len() as u8
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Verifies the Merkle opening proof towards the provided root.
|
/// Verifies the Merkle opening proof towards the provided root.
|
||||||
///
|
///
|
||||||
/// Returns `true` if `node` exists at `index` in a Merkle tree with `root`.
|
/// Returns `true` if `node` exists at `index` in a Merkle tree with `root`.
|
||||||
|
@ -48,6 +48,20 @@ impl MerklePath {
|
||||||
Err(_) => false,
|
Err(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over every inner node of this [MerklePath].
|
||||||
|
///
|
||||||
|
/// The iteration order is unspecified.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// Returns an error if the specified index is not valid for this path.
|
||||||
|
pub fn inner_nodes(&self, index: u64, node: Word) -> Result<InnerNodeIterator, MerkleError> {
|
||||||
|
Ok(InnerNodeIterator {
|
||||||
|
nodes: &self.nodes,
|
||||||
|
index: NodeIndex::new(self.depth(), index)?,
|
||||||
|
value: node,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Vec<Word>> for MerklePath {
|
impl From<Vec<Word>> for MerklePath {
|
||||||
|
@ -72,6 +86,9 @@ impl DerefMut for MerklePath {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ITERATORS
|
||||||
|
// ================================================================================================
|
||||||
|
|
||||||
impl FromIterator<Word> for MerklePath {
|
impl FromIterator<Word> for MerklePath {
|
||||||
fn from_iter<T: IntoIterator<Item = Word>>(iter: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = Word>>(iter: T) -> Self {
|
||||||
Self::new(iter.into_iter().collect())
|
Self::new(iter.into_iter().collect())
|
||||||
|
@ -87,6 +104,39 @@ impl IntoIterator for MerklePath {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An iterator over internal nodes of a [MerklePath].
|
||||||
|
pub struct InnerNodeIterator<'a> {
|
||||||
|
nodes: &'a Vec<Word>,
|
||||||
|
index: NodeIndex,
|
||||||
|
value: Word,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for InnerNodeIterator<'a> {
|
||||||
|
type Item = InnerNodeInfo;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if !self.index.is_root() {
|
||||||
|
let sibling_pos = self.nodes.len() - self.index.depth() as usize;
|
||||||
|
let (left, right) = if self.index.is_value_odd() {
|
||||||
|
(self.nodes[sibling_pos], self.value)
|
||||||
|
} else {
|
||||||
|
(self.value, self.nodes[sibling_pos])
|
||||||
|
};
|
||||||
|
|
||||||
|
self.value = Rpo256::merge(&[left.into(), right.into()]).into();
|
||||||
|
self.index.move_up();
|
||||||
|
|
||||||
|
Some(InnerNodeInfo {
|
||||||
|
value: self.value,
|
||||||
|
left,
|
||||||
|
right,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MERKLE PATH CONTAINERS
|
// MERKLE PATH CONTAINERS
|
||||||
// ================================================================================================
|
// ================================================================================================
|
||||||
|
|
||||||
|
@ -110,3 +160,25 @@ pub struct RootPath {
|
||||||
/// The path from `value` to `root` (exclusive).
|
/// The path from `value` to `root` (exclusive).
|
||||||
pub path: MerklePath,
|
pub path: MerklePath,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TESTS
|
||||||
|
// ================================================================================================
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::merkle::{int_to_node, MerklePath};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_inner_nodes() {
|
||||||
|
let nodes = vec![int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)];
|
||||||
|
let merkle_path = MerklePath::new(nodes);
|
||||||
|
|
||||||
|
let index = 6;
|
||||||
|
let node = int_to_node(5);
|
||||||
|
let root = merkle_path.compute_root(index, node).unwrap();
|
||||||
|
|
||||||
|
let inner_root = merkle_path.inner_nodes(index, node).unwrap().last().unwrap().value;
|
||||||
|
|
||||||
|
assert_eq!(root, inner_root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use super::mmr::{Mmr, MmrPeaks};
|
use super::mmr::Mmr;
|
||||||
use super::{
|
use super::{
|
||||||
BTreeMap, EmptySubtreeRoots, MerkleError, MerklePath, MerklePathSet, MerkleTree, NodeIndex,
|
BTreeMap, EmptySubtreeRoots, InnerNodeInfo, MerkleError, MerklePath, MerklePathSet, MerkleTree,
|
||||||
RootPath, Rpo256, RpoDigest, SimpleSmt, ValuePath, Vec, Word,
|
NodeIndex, RootPath, Rpo256, RpoDigest, SimpleSmt, ValuePath, Vec, Word,
|
||||||
};
|
};
|
||||||
use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
|
use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
|
||||||
|
|
||||||
|
@ -47,9 +47,13 @@ pub struct Node {
|
||||||
/// // the store is initialized with the SMT empty nodes
|
/// // the store is initialized with the SMT empty nodes
|
||||||
/// assert_eq!(store.num_internal_nodes(), 255);
|
/// assert_eq!(store.num_internal_nodes(), 255);
|
||||||
///
|
///
|
||||||
|
/// let tree1 = MerkleTree::new(vec![A, B, C, D, E, F, G, H0]).unwrap();
|
||||||
|
/// let tree2 = MerkleTree::new(vec![A, B, C, D, E, F, G, H1]).unwrap();
|
||||||
|
///
|
||||||
/// // populates the store with two merkle trees, common nodes are shared
|
/// // populates the store with two merkle trees, common nodes are shared
|
||||||
/// store.add_merkle_tree([A, B, C, D, E, F, G, H0]);
|
/// store
|
||||||
/// store.add_merkle_tree([A, B, C, D, E, F, G, H1]);
|
/// .extend(tree1.inner_nodes())
|
||||||
|
/// .extend(tree2.inner_nodes());
|
||||||
///
|
///
|
||||||
/// // every leaf except the last are the same
|
/// // every leaf except the last are the same
|
||||||
/// for i in 0..7 {
|
/// for i in 0..7 {
|
||||||
|
@ -111,60 +115,6 @@ impl MerkleStore {
|
||||||
MerkleStore { nodes }
|
MerkleStore { nodes }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends the provided merkle tree represented by its `leaves` to the set.
|
|
||||||
pub fn with_merkle_tree<I>(mut self, leaves: I) -> Result<Self, MerkleError>
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = Word>,
|
|
||||||
{
|
|
||||||
self.add_merkle_tree(leaves)?;
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Appends the provided Sparse Merkle tree represented by its `entries` to the set.
|
|
||||||
///
|
|
||||||
/// For more information, check [MerkleStore::add_sparse_merkle_tree].
|
|
||||||
pub fn with_sparse_merkle_tree<R, I>(
|
|
||||||
mut self,
|
|
||||||
depth: u8,
|
|
||||||
entries: R,
|
|
||||||
) -> Result<Self, MerkleError>
|
|
||||||
where
|
|
||||||
R: IntoIterator<IntoIter = I>,
|
|
||||||
I: Iterator<Item = (u64, Word)> + ExactSizeIterator,
|
|
||||||
{
|
|
||||||
self.add_sparse_merkle_tree(depth, entries)?;
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Appends the provided merkle path set.
|
|
||||||
pub fn with_merkle_path(
|
|
||||||
mut self,
|
|
||||||
index_value: u64,
|
|
||||||
node: Word,
|
|
||||||
path: MerklePath,
|
|
||||||
) -> Result<Self, MerkleError> {
|
|
||||||
self.add_merkle_path(index_value, node, path)?;
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Appends the provided merkle path set.
|
|
||||||
pub fn with_merkle_paths<I>(mut self, paths: I) -> Result<Self, MerkleError>
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = (u64, Word, MerklePath)>,
|
|
||||||
{
|
|
||||||
self.add_merkle_paths(paths)?;
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Appends the provided [Mmr] represented by its `leaves` to the set.
|
|
||||||
pub fn with_mmr<I>(mut self, leaves: I) -> Result<Self, MerkleError>
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = Word>,
|
|
||||||
{
|
|
||||||
self.add_mmr(leaves)?;
|
|
||||||
Ok(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PUBLIC ACCESSORS
|
// PUBLIC ACCESSORS
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -310,68 +260,21 @@ impl MerkleStore {
|
||||||
// STATE MUTATORS
|
// STATE MUTATORS
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Adds all the nodes of a Merkle tree represented by `leaves`.
|
/// Adds a sequence of nodes yielded by the provided iterator into the store.
|
||||||
///
|
pub fn extend<I>(&mut self, iter: I) -> &mut MerkleStore
|
||||||
/// This will instantiate a Merkle tree using `leaves` and include all the nodes into the
|
|
||||||
/// store.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// This method may return the following errors:
|
|
||||||
/// - `DepthTooSmall` if leaves is empty or contains only 1 element
|
|
||||||
/// - `NumLeavesNotPowerOfTwo` if the number of leaves is not a power-of-two
|
|
||||||
pub fn add_merkle_tree<I>(&mut self, leaves: I) -> Result<Word, MerkleError>
|
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = Word>,
|
I: Iterator<Item = InnerNodeInfo>,
|
||||||
{
|
{
|
||||||
let leaves: Vec<_> = leaves.into_iter().collect();
|
for node in iter {
|
||||||
if leaves.len() < 2 {
|
let value: RpoDigest = node.value.into();
|
||||||
return Err(MerkleError::DepthTooSmall(leaves.len() as u8));
|
let left: RpoDigest = node.left.into();
|
||||||
|
let right: RpoDigest = node.right.into();
|
||||||
|
|
||||||
|
debug_assert_eq!(Rpo256::merge(&[left, right]), value);
|
||||||
|
self.nodes.insert(value, Node { left, right });
|
||||||
}
|
}
|
||||||
|
|
||||||
let tree = MerkleTree::new(leaves)?;
|
self
|
||||||
for node in tree.inner_nodes() {
|
|
||||||
self.nodes.insert(
|
|
||||||
node.value.into(),
|
|
||||||
Node {
|
|
||||||
left: node.left.into(),
|
|
||||||
right: node.right.into(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(tree.root())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds a Sparse Merkle tree defined by the specified `entries` to the store, and returns the
|
|
||||||
/// root of the added tree.
|
|
||||||
///
|
|
||||||
/// The entries are expected to contain tuples of `(index, node)` describing nodes in the tree
|
|
||||||
/// at `depth`.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
/// Returns an error if the provided `depth` is greater than [SimpleSmt::MAX_DEPTH].
|
|
||||||
pub fn add_sparse_merkle_tree<R, I>(
|
|
||||||
&mut self,
|
|
||||||
depth: u8,
|
|
||||||
entries: R,
|
|
||||||
) -> Result<Word, MerkleError>
|
|
||||||
where
|
|
||||||
R: IntoIterator<IntoIter = I>,
|
|
||||||
I: Iterator<Item = (u64, Word)> + ExactSizeIterator,
|
|
||||||
{
|
|
||||||
let smt = SimpleSmt::new(depth)?.with_leaves(entries)?;
|
|
||||||
for node in smt.inner_nodes() {
|
|
||||||
self.nodes.insert(
|
|
||||||
node.value.into(),
|
|
||||||
Node {
|
|
||||||
left: node.left.into(),
|
|
||||||
right: node.right.into(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(smt.root())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds all the nodes of a Merkle path represented by `path`, opening to `node`. Returns the
|
/// Adds all the nodes of a Merkle path represented by `path`, opening to `node`. Returns the
|
||||||
|
@ -381,31 +284,21 @@ impl MerkleStore {
|
||||||
/// include all the nodes into the store.
|
/// include all the nodes into the store.
|
||||||
pub fn add_merkle_path(
|
pub fn add_merkle_path(
|
||||||
&mut self,
|
&mut self,
|
||||||
index_value: u64,
|
index: u64,
|
||||||
mut node: Word,
|
node: Word,
|
||||||
path: MerklePath,
|
path: MerklePath,
|
||||||
) -> Result<Word, MerkleError> {
|
) -> Result<Word, MerkleError> {
|
||||||
let mut index = NodeIndex::new(path.len() as u8, index_value)?;
|
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();
|
||||||
|
|
||||||
for sibling in path {
|
debug_assert_eq!(Rpo256::merge(&[left, right]), value);
|
||||||
let (left, right) = match index.is_value_odd() {
|
self.nodes.insert(value, Node { left, right });
|
||||||
true => (sibling, node),
|
|
||||||
false => (node, sibling),
|
|
||||||
};
|
|
||||||
let parent = Rpo256::merge(&[left.into(), right.into()]);
|
|
||||||
self.nodes.insert(
|
|
||||||
parent,
|
|
||||||
Node {
|
|
||||||
left: left.into(),
|
|
||||||
right: right.into(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
index.move_up();
|
node.value
|
||||||
node = parent.into();
|
});
|
||||||
}
|
Ok(root)
|
||||||
|
|
||||||
Ok(node)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds all the nodes of multiple Merkle paths into the store.
|
/// Adds all the nodes of multiple Merkle paths into the store.
|
||||||
|
@ -435,25 +328,6 @@ impl MerkleStore {
|
||||||
Ok(root)
|
Ok(root)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Appends the provided [Mmr] into the store.
|
|
||||||
pub fn add_mmr<I>(&mut self, leaves: I) -> Result<MmrPeaks, MerkleError>
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = Word>,
|
|
||||||
{
|
|
||||||
let mmr = Mmr::from(leaves);
|
|
||||||
for node in mmr.inner_nodes() {
|
|
||||||
self.nodes.insert(
|
|
||||||
node.value.into(),
|
|
||||||
Node {
|
|
||||||
left: node.left.into(),
|
|
||||||
right: node.right.into(),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(mmr.accumulator())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets a node to `value`.
|
/// Sets a node to `value`.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
@ -482,19 +356,57 @@ impl MerkleStore {
|
||||||
///
|
///
|
||||||
/// Merges arbitrary values. They may be leafs, nodes, or a mixture of both.
|
/// 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> {
|
pub fn merge_roots(&mut self, root1: Word, root2: Word) -> Result<Word, MerkleError> {
|
||||||
let root1: RpoDigest = root1.into();
|
let left: RpoDigest = root1.into();
|
||||||
let root2: RpoDigest = root2.into();
|
let right: RpoDigest = root2.into();
|
||||||
|
|
||||||
let parent: Word = Rpo256::merge(&[root1, root2]).into();
|
let parent = Rpo256::merge(&[left, right]);
|
||||||
self.nodes.insert(
|
self.nodes.insert(parent, Node { left, right });
|
||||||
parent.into(),
|
|
||||||
Node {
|
|
||||||
left: root1,
|
|
||||||
right: root2,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(parent)
|
Ok(parent.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CONVERSIONS
|
||||||
|
// ================================================================================================
|
||||||
|
|
||||||
|
impl From<&MerkleTree> for MerkleStore {
|
||||||
|
fn from(value: &MerkleTree) -> Self {
|
||||||
|
let mut store = MerkleStore::new();
|
||||||
|
store.extend(value.inner_nodes());
|
||||||
|
store
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&SimpleSmt> for MerkleStore {
|
||||||
|
fn from(value: &SimpleSmt) -> Self {
|
||||||
|
let mut store = MerkleStore::new();
|
||||||
|
store.extend(value.inner_nodes());
|
||||||
|
store
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Mmr> for MerkleStore {
|
||||||
|
fn from(value: &Mmr) -> Self {
|
||||||
|
let mut store = MerkleStore::new();
|
||||||
|
store.extend(value.inner_nodes());
|
||||||
|
store
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromIterator<InnerNodeInfo> for MerkleStore {
|
||||||
|
fn from_iter<T: IntoIterator<Item = InnerNodeInfo>>(iter: T) -> Self {
|
||||||
|
let mut store = MerkleStore::new();
|
||||||
|
store.extend(iter.into_iter());
|
||||||
|
store
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ITERATORS
|
||||||
|
// ================================================================================================
|
||||||
|
|
||||||
|
impl Extend<InnerNodeInfo> for MerkleStore {
|
||||||
|
fn extend<T: IntoIterator<Item = InnerNodeInfo>>(&mut self, iter: T) {
|
||||||
|
self.extend(iter.into_iter());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
hash::rpo::Rpo256,
|
hash::rpo::Rpo256,
|
||||||
merkle::{int_to_node, MerklePathSet},
|
merkle::{int_to_node, MerklePathSet, MerkleTree, SimpleSmt},
|
||||||
Felt, Word, WORD_SIZE, ZERO,
|
Felt, Word, WORD_SIZE, ZERO,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(std)]
|
#[cfg(feature = "std")]
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
const KEYS4: [u64; 4] = [0, 1, 2, 3];
|
const KEYS4: [u64; 4] = [0, 1, 2, 3];
|
||||||
|
@ -15,7 +15,7 @@ const EMPTY: Word = [ZERO; WORD_SIZE];
|
||||||
#[test]
|
#[test]
|
||||||
fn test_root_not_in_store() -> Result<(), MerkleError> {
|
fn test_root_not_in_store() -> Result<(), MerkleError> {
|
||||||
let mtree = MerkleTree::new(LEAVES4.to_vec())?;
|
let mtree = MerkleTree::new(LEAVES4.to_vec())?;
|
||||||
let store = MerkleStore::default().with_merkle_tree(LEAVES4)?;
|
let store = MerkleStore::from(&mtree);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
store.get_node(LEAVES4[0], NodeIndex::make(mtree.depth(), 0)),
|
store.get_node(LEAVES4[0], NodeIndex::make(mtree.depth(), 0)),
|
||||||
Err(MerkleError::RootNotInStore(LEAVES4[0])),
|
Err(MerkleError::RootNotInStore(LEAVES4[0])),
|
||||||
|
@ -32,10 +32,8 @@ fn test_root_not_in_store() -> Result<(), MerkleError> {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_merkle_tree() -> Result<(), MerkleError> {
|
fn test_merkle_tree() -> Result<(), MerkleError> {
|
||||||
let mut store = MerkleStore::default();
|
|
||||||
|
|
||||||
let mtree = MerkleTree::new(LEAVES4.to_vec())?;
|
let mtree = MerkleTree::new(LEAVES4.to_vec())?;
|
||||||
store.add_merkle_tree(LEAVES4.to_vec())?;
|
let store = MerkleStore::from(&mtree);
|
||||||
|
|
||||||
// STORE LEAVES ARE CORRECT ==============================================================
|
// STORE LEAVES ARE CORRECT ==============================================================
|
||||||
// checks the leaves in the store corresponds to the expected values
|
// checks the leaves in the store corresponds to the expected values
|
||||||
|
@ -176,24 +174,20 @@ fn test_leaf_paths_for_empty_trees() -> Result<(), MerkleError> {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_invalid_node() {
|
fn test_get_invalid_node() {
|
||||||
let mut store = MerkleStore::default();
|
|
||||||
let mtree = MerkleTree::new(LEAVES4.to_vec()).expect("creating a merkle tree must work");
|
let mtree = MerkleTree::new(LEAVES4.to_vec()).expect("creating a merkle tree must work");
|
||||||
store
|
let store = MerkleStore::from(&mtree);
|
||||||
.add_merkle_tree(LEAVES4.to_vec())
|
|
||||||
.expect("adding a merkle tree to the store must work");
|
|
||||||
let _ = store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 3));
|
let _ = store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_add_sparse_merkle_tree_one_level() -> Result<(), MerkleError> {
|
fn test_add_sparse_merkle_tree_one_level() -> Result<(), MerkleError> {
|
||||||
let mut store = MerkleStore::default();
|
|
||||||
let keys2: [u64; 2] = [0, 1];
|
let keys2: [u64; 2] = [0, 1];
|
||||||
let leaves2: [Word; 2] = [int_to_node(1), int_to_node(2)];
|
let leaves2: [Word; 2] = [int_to_node(1), int_to_node(2)];
|
||||||
store.add_sparse_merkle_tree(48, keys2.into_iter().zip(leaves2.into_iter()))?;
|
|
||||||
let smt = SimpleSmt::new(1)
|
let smt = SimpleSmt::new(1)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.with_leaves(keys2.into_iter().zip(leaves2.into_iter()))
|
.with_leaves(keys2.into_iter().zip(leaves2.into_iter()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let store = MerkleStore::from(&smt);
|
||||||
|
|
||||||
let idx = NodeIndex::make(1, 0);
|
let idx = NodeIndex::make(1, 0);
|
||||||
assert_eq!(smt.get_node(idx).unwrap(), leaves2[0]);
|
assert_eq!(smt.get_node(idx).unwrap(), leaves2[0]);
|
||||||
|
@ -208,15 +202,13 @@ fn test_add_sparse_merkle_tree_one_level() -> Result<(), MerkleError> {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
|
fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
|
||||||
let mut store = MerkleStore::default();
|
|
||||||
store
|
|
||||||
.add_sparse_merkle_tree(SimpleSmt::MAX_DEPTH, KEYS4.into_iter().zip(LEAVES4.into_iter()))?;
|
|
||||||
|
|
||||||
let smt = SimpleSmt::new(SimpleSmt::MAX_DEPTH)
|
let smt = SimpleSmt::new(SimpleSmt::MAX_DEPTH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.with_leaves(KEYS4.into_iter().zip(LEAVES4.into_iter()))
|
.with_leaves(KEYS4.into_iter().zip(LEAVES4.into_iter()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let store = MerkleStore::from(&smt);
|
||||||
|
|
||||||
// STORE LEAVES ARE CORRECT ==============================================================
|
// STORE LEAVES ARE CORRECT ==============================================================
|
||||||
// checks the leaves in the store corresponds to the expected values
|
// checks the leaves in the store corresponds to the expected values
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -472,7 +464,8 @@ fn wont_open_to_different_depth_root() {
|
||||||
// For this example, the depth of the Merkle tree is 1, as we have only two leaves. Here we
|
// 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
|
// attempt to fetch a node on the maximum depth, and it should fail because the root shouldn't
|
||||||
// exist for the set.
|
// exist for the set.
|
||||||
let store = MerkleStore::default().with_merkle_tree([a, b]).unwrap();
|
let mtree = MerkleTree::new(vec![a, b]).unwrap();
|
||||||
|
let store = MerkleStore::from(&mtree);
|
||||||
let index = NodeIndex::root();
|
let index = NodeIndex::root();
|
||||||
let err = store.get_node(root, index).err().unwrap();
|
let err = store.get_node(root, index).err().unwrap();
|
||||||
assert_eq!(err, MerkleError::RootNotInStore(root));
|
assert_eq!(err, MerkleError::RootNotInStore(root));
|
||||||
|
@ -499,7 +492,8 @@ fn store_path_opens_from_leaf() {
|
||||||
|
|
||||||
let root = Rpo256::merge(&[m.into(), n.into()]);
|
let root = Rpo256::merge(&[m.into(), n.into()]);
|
||||||
|
|
||||||
let store = MerkleStore::default().with_merkle_tree([a, b, c, d, e, f, g, h]).unwrap();
|
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.into(), NodeIndex::make(3, 1)).unwrap().path;
|
||||||
|
|
||||||
let expected = MerklePath::new([a.into(), j.into(), n.into()].to_vec());
|
let expected = MerklePath::new([a.into(), j.into(), n.into()].to_vec());
|
||||||
|
@ -509,7 +503,7 @@ fn store_path_opens_from_leaf() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_set_node() -> Result<(), MerkleError> {
|
fn test_set_node() -> Result<(), MerkleError> {
|
||||||
let mtree = MerkleTree::new(LEAVES4.to_vec())?;
|
let mtree = MerkleTree::new(LEAVES4.to_vec())?;
|
||||||
let mut store = MerkleStore::default().with_merkle_tree(LEAVES4)?;
|
let mut store = MerkleStore::from(&mtree);
|
||||||
let value = int_to_node(42);
|
let value = int_to_node(42);
|
||||||
let index = NodeIndex::make(mtree.depth(), 0);
|
let index = NodeIndex::make(mtree.depth(), 0);
|
||||||
let new_root = store.set_node(mtree.root(), index, value)?.root;
|
let new_root = store.set_node(mtree.root(), index, value)?.root;
|
||||||
|
@ -520,8 +514,8 @@ fn test_set_node() -> Result<(), MerkleError> {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_constructors() -> Result<(), MerkleError> {
|
fn test_constructors() -> Result<(), MerkleError> {
|
||||||
let store = MerkleStore::new().with_merkle_tree(LEAVES4)?;
|
|
||||||
let mtree = MerkleTree::new(LEAVES4.to_vec())?;
|
let mtree = MerkleTree::new(LEAVES4.to_vec())?;
|
||||||
|
let store = MerkleStore::from(&mtree);
|
||||||
|
|
||||||
let depth = mtree.depth();
|
let depth = mtree.depth();
|
||||||
let leaves = 2u64.pow(depth.into());
|
let leaves = 2u64.pow(depth.into());
|
||||||
|
@ -532,12 +526,11 @@ fn test_constructors() -> Result<(), MerkleError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let depth = 32;
|
let depth = 32;
|
||||||
let store = MerkleStore::default()
|
|
||||||
.with_sparse_merkle_tree(depth, KEYS4.into_iter().zip(LEAVES4.into_iter()))?;
|
|
||||||
let smt = SimpleSmt::new(depth)
|
let smt = SimpleSmt::new(depth)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.with_leaves(KEYS4.into_iter().zip(LEAVES4.into_iter()))
|
.with_leaves(KEYS4.into_iter().zip(LEAVES4.into_iter()))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
let store = MerkleStore::from(&smt);
|
||||||
let depth = smt.depth();
|
let depth = smt.depth();
|
||||||
|
|
||||||
for key in KEYS4 {
|
for key in KEYS4 {
|
||||||
|
@ -554,12 +547,14 @@ fn test_constructors() -> Result<(), MerkleError> {
|
||||||
(3, LEAVES4[3], mtree.get_path(NodeIndex::make(d, 3)).unwrap()),
|
(3, LEAVES4[3], mtree.get_path(NodeIndex::make(d, 3)).unwrap()),
|
||||||
];
|
];
|
||||||
|
|
||||||
let store1 = MerkleStore::default().with_merkle_paths(paths.clone())?;
|
let mut store1 = MerkleStore::default();
|
||||||
let store2 = MerkleStore::default()
|
store1.add_merkle_paths(paths.clone())?;
|
||||||
.with_merkle_path(0, LEAVES4[0], mtree.get_path(NodeIndex::make(d, 0))?)?
|
|
||||||
.with_merkle_path(1, LEAVES4[1], mtree.get_path(NodeIndex::make(d, 1))?)?
|
let mut store2 = MerkleStore::default();
|
||||||
.with_merkle_path(2, LEAVES4[2], mtree.get_path(NodeIndex::make(d, 2))?)?
|
store2.add_merkle_path(0, LEAVES4[0], mtree.get_path(NodeIndex::make(d, 0))?)?;
|
||||||
.with_merkle_path(3, LEAVES4[3], mtree.get_path(NodeIndex::make(d, 3))?)?;
|
store2.add_merkle_path(1, LEAVES4[1], mtree.get_path(NodeIndex::make(d, 1))?)?;
|
||||||
|
store2.add_merkle_path(2, LEAVES4[2], mtree.get_path(NodeIndex::make(d, 2))?)?;
|
||||||
|
store2.add_merkle_path(3, LEAVES4[3], mtree.get_path(NodeIndex::make(d, 3))?)?;
|
||||||
let set = MerklePathSet::new(d).with_paths(paths).unwrap();
|
let set = MerklePathSet::new(d).with_paths(paths).unwrap();
|
||||||
|
|
||||||
for key in [0, 1, 2, 3] {
|
for key in [0, 1, 2, 3] {
|
||||||
|
@ -723,11 +718,12 @@ fn get_leaf_depth_works_with_depth_8() {
|
||||||
assert_eq!(Err(MerkleError::DepthTooBig(9)), store.get_leaf_depth(root, 8, a));
|
assert_eq!(Err(MerkleError::DepthTooBig(9)), store.get_leaf_depth(root, 8, a));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(std)]
|
#[cfg(feature = "std")]
|
||||||
#[test]
|
#[test]
|
||||||
fn test_serialization() -> Result<(), Box<dyn Error>> {
|
fn test_serialization() -> Result<(), Box<dyn Error>> {
|
||||||
let original = MerkleStore::new().with_merkle_tree(LEAVES4)?;
|
let mtree = MerkleTree::new(LEAVES4.to_vec())?;
|
||||||
let decoded = MerkleStore::read_from_bytes(&original.to_bytes())?;
|
let store = MerkleStore::from(&mtree);
|
||||||
assert_eq!(original, decoded);
|
let decoded = MerkleStore::read_from_bytes(&store.to_bytes()).expect("deserialization failed");
|
||||||
|
assert_eq!(store, decoded);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue