From 9be4253f195a2e2249a1b451dd3984a316616e13 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Fri, 21 Apr 2023 11:22:36 -0700 Subject: [PATCH] feat: remove clone requirement for MerkleStore From constructors --- benches/store.rs | 24 ++++++++++++------------ src/merkle/merkle_tree.rs | 3 +++ src/merkle/store/mod.rs | 22 +++++++++++++++------- src/merkle/store/tests.rs | 20 ++++++++++---------- 4 files changed, 40 insertions(+), 29 deletions(-) diff --git a/benches/store.rs b/benches/store.rs index 2319128..3ad79c4 100644 --- a/benches/store.rs +++ b/benches/store.rs @@ -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 // being benchmarked here, so no values are inserted into the backends let smt = SimpleSmt::new(depth).unwrap(); - let store: MerkleStore = smt.clone().into(); + let store = MerkleStore::from(&smt); let root = smt.root(); group.bench_function(BenchmarkId::new("SimpleSmt", depth), |b| { @@ -66,7 +66,7 @@ fn get_leaf_merkletree(c: &mut Criterion) { let mtree_leaves: Vec = leaves.iter().map(|v| v.into()).collect(); let mtree = MerkleTree::new(mtree_leaves.clone()).unwrap(); - let store: MerkleStore = mtree.clone().into(); + let store = MerkleStore::from(&mtree); let depth = mtree.depth(); let root = mtree.root(); let size_u64 = size as u64; @@ -108,7 +108,7 @@ fn get_leaf_simplesmt(c: &mut Criterion) { .unwrap() .with_leaves(smt_leaves.clone()) .unwrap(); - let store: MerkleStore = smt.clone().into(); + let store = MerkleStore::from(&smt); let depth = smt.depth(); let root = smt.root(); let size_u64 = size as u64; @@ -141,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 // backends. let smt = SimpleSmt::new(depth).unwrap(); - let store: MerkleStore = smt.clone().into(); + let store = MerkleStore::from(&smt); let root = smt.root(); let half_depth = depth / 2; let half_size = 2_u64.pow(half_depth as u32); @@ -176,7 +176,7 @@ fn get_node_merkletree(c: &mut Criterion) { let mtree_leaves: Vec = leaves.iter().map(|v| v.into()).collect(); let mtree = MerkleTree::new(mtree_leaves.clone()).unwrap(); - let store: MerkleStore = mtree.clone().into(); + let store = MerkleStore::from(&mtree); let root = mtree.root(); let half_depth = mtree.depth() / 2; let half_size = 2_u64.pow(half_depth as u32); @@ -219,7 +219,7 @@ fn get_node_simplesmt(c: &mut Criterion) { .unwrap() .with_leaves(smt_leaves.clone()) .unwrap(); - let store: MerkleStore = smt.clone().into(); + let store = MerkleStore::from(&smt); let root = smt.root(); let half_depth = smt.depth() / 2; let half_size = 2_u64.pow(half_depth as u32); @@ -254,7 +254,7 @@ fn get_leaf_path_merkletree(c: &mut Criterion) { let mtree_leaves: Vec = leaves.iter().map(|v| v.into()).collect(); let mtree = MerkleTree::new(mtree_leaves.clone()).unwrap(); - let store: MerkleStore = mtree.clone().into(); + let store = MerkleStore::from(&mtree); let depth = mtree.depth(); let root = mtree.root(); let size_u64 = size as u64; @@ -296,7 +296,7 @@ fn get_leaf_path_simplesmt(c: &mut Criterion) { .unwrap() .with_leaves(smt_leaves.clone()) .unwrap(); - let store: MerkleStore = smt.clone().into(); + let store = MerkleStore::from(&smt); let depth = smt.depth(); let root = smt.root(); let size_u64 = size as u64; @@ -346,7 +346,7 @@ fn new(c: &mut Criterion) { || leaves.iter().map(|v| v.into()).collect::>(), |l| { let mtree = MerkleTree::new(l).unwrap(); - black_box(MerkleStore::from(mtree)); + black_box(MerkleStore::from(&mtree)); }, BatchSize::SmallInput, ) @@ -377,7 +377,7 @@ fn new(c: &mut Criterion) { }, |l| { let smt = SimpleSmt::new(SimpleSmt::MAX_DEPTH).unwrap().with_leaves(l).unwrap(); - black_box(MerkleStore::from(smt)); + black_box(MerkleStore::from(&smt)); }, BatchSize::SmallInput, ) @@ -397,7 +397,7 @@ fn update_leaf_merkletree(c: &mut Criterion) { let mtree_leaves: Vec = leaves.iter().map(|v| v.into()).collect(); let mut mtree = MerkleTree::new(mtree_leaves.clone()).unwrap(); - let mut store: MerkleStore = mtree.clone().into(); + let mut store = MerkleStore::from(&mtree); let depth = mtree.depth(); let root = mtree.root(); let size_u64 = size as u64; @@ -446,7 +446,7 @@ fn update_leaf_simplesmt(c: &mut Criterion) { .unwrap() .with_leaves(smt_leaves.clone()) .unwrap(); - let mut store: MerkleStore = smt.clone().into(); + let mut store = MerkleStore::from(&smt); let depth = smt.depth(); let root = smt.root(); let size_u64 = size as u64; diff --git a/src/merkle/merkle_tree.rs b/src/merkle/merkle_tree.rs index 4e39a09..106ec27 100644 --- a/src/merkle/merkle_tree.rs +++ b/src/merkle/merkle_tree.rs @@ -192,6 +192,9 @@ impl<'a> Iterator for MerkleTreeNodes<'a> { } } +// UTILITY FUNCTIONS +// ================================================================================================ + /// Utility to visualize a [MerkleTree] in text. pub fn tree_to_text(tree: &MerkleTree) -> Result { let indent = " "; diff --git a/src/merkle/store/mod.rs b/src/merkle/store/mod.rs index 8ed03e7..442ff00 100644 --- a/src/merkle/store/mod.rs +++ b/src/merkle/store/mod.rs @@ -393,33 +393,41 @@ impl MerkleStore { } } -// CONVERTIONS +// CONVERSIONS // ================================================================================================ -impl From for MerkleStore { - fn from(value: MerkleTree) -> Self { +impl From<&MerkleTree> for MerkleStore { + fn from(value: &MerkleTree) -> Self { let mut store = MerkleStore::new(); store.extend(value.inner_nodes()); store } } -impl From for MerkleStore { - fn from(value: SimpleSmt) -> Self { +impl From<&SimpleSmt> for MerkleStore { + fn from(value: &SimpleSmt) -> Self { let mut store = MerkleStore::new(); store.extend(value.inner_nodes()); store } } -impl From for MerkleStore { - fn from(value: Mmr) -> Self { +impl From<&Mmr> for MerkleStore { + fn from(value: &Mmr) -> Self { let mut store = MerkleStore::new(); store.extend(value.inner_nodes()); store } } +impl FromIterator for MerkleStore { + fn from_iter>(iter: T) -> Self { + let mut store = MerkleStore::new(); + store.extend(iter.into_iter()); + store + } +} + // ITERATORS // ================================================================================================ diff --git a/src/merkle/store/tests.rs b/src/merkle/store/tests.rs index 4c5eeb4..ca5be9e 100644 --- a/src/merkle/store/tests.rs +++ b/src/merkle/store/tests.rs @@ -15,7 +15,7 @@ const EMPTY: Word = [ZERO; WORD_SIZE]; #[test] fn test_root_not_in_store() -> Result<(), MerkleError> { let mtree = MerkleTree::new(LEAVES4.to_vec())?; - let store: MerkleStore = mtree.clone().into(); + let store = MerkleStore::from(&mtree); assert_eq!( store.get_node(LEAVES4[0], NodeIndex::make(mtree.depth(), 0)), Err(MerkleError::RootNotInStore(LEAVES4[0])), @@ -33,7 +33,7 @@ fn test_root_not_in_store() -> Result<(), MerkleError> { #[test] fn test_merkle_tree() -> Result<(), MerkleError> { let mtree = MerkleTree::new(LEAVES4.to_vec())?; - let store: MerkleStore = mtree.clone().into(); + let store = MerkleStore::from(&mtree); // STORE LEAVES ARE CORRECT ============================================================== // checks the leaves in the store corresponds to the expected values @@ -175,7 +175,7 @@ fn test_leaf_paths_for_empty_trees() -> Result<(), MerkleError> { #[test] fn test_get_invalid_node() { let mtree = MerkleTree::new(LEAVES4.to_vec()).expect("creating a merkle tree must work"); - let store: MerkleStore = mtree.clone().into(); + let store = MerkleStore::from(&mtree); let _ = store.get_node(mtree.root(), NodeIndex::make(mtree.depth(), 3)); } @@ -187,7 +187,7 @@ fn test_add_sparse_merkle_tree_one_level() -> Result<(), MerkleError> { .unwrap() .with_leaves(keys2.into_iter().zip(leaves2.into_iter())) .unwrap(); - let store: MerkleStore = smt.clone().into(); + let store = MerkleStore::from(&smt); let idx = NodeIndex::make(1, 0); assert_eq!(smt.get_node(idx).unwrap(), leaves2[0]); @@ -207,7 +207,7 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> { .with_leaves(KEYS4.into_iter().zip(LEAVES4.into_iter())) .unwrap(); - let store: MerkleStore = smt.clone().into(); + let store = MerkleStore::from(&smt); // STORE LEAVES ARE CORRECT ============================================================== // checks the leaves in the store corresponds to the expected values @@ -465,7 +465,7 @@ fn wont_open_to_different_depth_root() { // attempt to fetch a node on the maximum depth, and it should fail because the root shouldn't // exist for the set. let mtree = MerkleTree::new(vec![a, b]).unwrap(); - let store: MerkleStore = mtree.clone().into(); + let store = MerkleStore::from(&mtree); let index = NodeIndex::root(); let err = store.get_node(root, index).err().unwrap(); assert_eq!(err, MerkleError::RootNotInStore(root)); @@ -493,7 +493,7 @@ fn store_path_opens_from_leaf() { let root = Rpo256::merge(&[m.into(), n.into()]); let mtree = MerkleTree::new(vec![a, b, c, d, e, f, g, h]).unwrap(); - let store: MerkleStore = mtree.clone().into(); + let store = MerkleStore::from(&mtree); 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()); @@ -503,7 +503,7 @@ fn store_path_opens_from_leaf() { #[test] fn test_set_node() -> Result<(), MerkleError> { let mtree = MerkleTree::new(LEAVES4.to_vec())?; - let mut store: MerkleStore = mtree.clone().into(); + let mut store = MerkleStore::from(&mtree); let value = int_to_node(42); let index = NodeIndex::make(mtree.depth(), 0); let new_root = store.set_node(mtree.root(), index, value)?.root; @@ -515,7 +515,7 @@ fn test_set_node() -> Result<(), MerkleError> { #[test] fn test_constructors() -> Result<(), MerkleError> { let mtree = MerkleTree::new(LEAVES4.to_vec())?; - let store: MerkleStore = mtree.clone().into(); + let store = MerkleStore::from(&mtree); let depth = mtree.depth(); let leaves = 2u64.pow(depth.into()); @@ -530,7 +530,7 @@ fn test_constructors() -> Result<(), MerkleError> { .unwrap() .with_leaves(KEYS4.into_iter().zip(LEAVES4.into_iter())) .unwrap(); - let store: MerkleStore = smt.clone().into(); + let store = MerkleStore::from(&smt); let depth = smt.depth(); for key in KEYS4 {