From 91667fd7dec45c070cfc44eebcc10bf76928a7d8 Mon Sep 17 00:00:00 2001 From: Victor Lopez Date: Thu, 16 Mar 2023 10:08:26 +0100 Subject: [PATCH] refactor: add derive proc macros to merkle store This commit introduce common derive proc macros to MerkleStore. These are required downstream as the in-memory storage can be cloned. It also introduces constructors common to the other types of the crate that will help to build a merkle store, using a build pattern. --- src/merkle/store.rs | 68 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/src/merkle/store.rs b/src/merkle/store.rs index 82001dc..ae2dec9 100644 --- a/src/merkle/store.rs +++ b/src/merkle/store.rs @@ -8,12 +8,13 @@ use super::{ RpoDigest, SimpleSmt, Vec, Word, }; -#[derive(Debug)] +#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)] pub struct Node { left: RpoDigest, right: RpoDigest, } +#[derive(Debug, Clone, Eq, PartialEq)] pub struct MerkleStore { nodes: BTreeMap, } @@ -30,22 +31,59 @@ impl MerkleStore { /// Creates an empty `MerkleStore` instance. pub fn new() -> MerkleStore { - let mut nodes = BTreeMap::new(); - // pre-populate the store with the empty hashes let subtrees = EmptySubtreeRoots::empty_hashes(64); - for (child, parent) in subtrees.iter().zip(subtrees.iter().skip(1)) { - nodes.insert( - *parent, - Node { - left: *child, - right: *child, - }, - ); - } + let nodes = subtrees + .iter() + .copied() + .zip(subtrees.iter().skip(1).copied()) + .map(|(child, parent)| { + ( + parent, + Node { + left: child, + right: child, + }, + ) + }) + .collect(); + MerkleStore { nodes } } + /// Appends the provided merkle tree represented by its `leaves` to the set. + pub fn with_merkle_tree(mut self, leaves: I) -> Result + where + I: IntoIterator, + { + self.add_merkle_tree(leaves)?; + Ok(self) + } + + /// Appends the provided sparse merkle tree represented by its `entries` to the set. + pub fn with_sparse_merkle_tree(mut self, entries: R) -> Result + where + R: IntoIterator, + I: Iterator + ExactSizeIterator, + { + self.add_sparse_merkle_tree(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.add_merkle_path(index_value, node, path)?; + Ok(self) + } + + // STATE MUTATORS + // -------------------------------------------------------------------------------------------- + /// Adds all the nodes of a Merkle tree represented by `leaves`. /// /// This will instantiate a Merkle tree using `leaves` and include all the nodes into the @@ -56,7 +94,11 @@ impl MerkleStore { /// 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(&mut self, leaves: Vec) -> Result { + pub fn add_merkle_tree(&mut self, leaves: I) -> Result + where + I: IntoIterator, + { + let leaves: Vec<_> = leaves.into_iter().collect(); let layers = leaves.len().ilog2(); let tree = MerkleTree::new(leaves)?;