From 689a3e2ed4982bc281c39c525fc70b23a25368ac Mon Sep 17 00:00:00 2001 From: Magamedrasul Ibragimov Date: Sun, 29 Jan 2023 15:07:42 +0400 Subject: [PATCH] chore: add frame for batch_insertions --- src/hasher.rs | 2 +- src/tree.rs | 63 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/hasher.rs b/src/hasher.rs index 25184ca..329b9c0 100644 --- a/src/hasher.rs +++ b/src/hasher.rs @@ -3,7 +3,7 @@ use crate::*; /// Trait that must be implemented for Hash Function pub trait Hasher { /// Native type for the hash-function - type Fr: Copy + Eq + Default; + type Fr: Copy + Eq + Default + Sync; /// Serializes Self::Fr fn serialize(value: Self::Fr) -> Value; diff --git a/src/tree.rs b/src/tree.rs index cce95db..b6ebe54 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -1,5 +1,7 @@ use crate::*; + use std::cmp::max; +use std::collections::HashMap; use std::marker::PhantomData; // db[DEPTH_KEY] = depth @@ -10,7 +12,7 @@ const NEXT_INDEX_KEY: DBKey = u64::MAX.to_be_bytes(); // Denotes keys (depth, index) in Merkle Tree. Can be converted to DBKey // TODO! Think about using hashing for that -#[derive(Clone, Copy)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] struct Key(usize, usize); impl From for DBKey { fn from(key: Key) -> Self { @@ -195,10 +197,67 @@ where /// Batch insertion, updates the tree in parallel. pub fn batch_insert(&mut self, leaves: &[H::Fr]) -> Result<()> { - // if leaves.len() + let end = self.next_index + leaves.len(); + + if end > self.capacity() { + return Err(Error("Not enough space to insert the leaves!".to_string())); + } + + let mut subtree = HashMap::::new(); + + let root_key = Key(0, 0); + + subtree.insert(root_key, self.root); + self.fill_nodes(root_key, self.next_index, end, &mut subtree)?; + + rayon::ThreadPoolBuilder::new() + .num_threads(8) + .build() + .unwrap() + .install(|| Self::batch_recalculate(root_key, &subtree)); + Ok(()) } + // Fills hashmap subtree + fn fill_nodes( + &self, + key: Key, + start: usize, + end: usize, + subtree: &mut HashMap, + ) -> Result<()> { + if key.0 == self.depth { + return Ok(()); + } + + let left = Key(key.0 + 1, key.1 * 2); + let right = Key(key.0 + 1, key.1 * 2 + 1); + + let left_val = self.get_elem(left)?; + let right_val = self.get_elem(right)?; + + subtree.insert(left, left_val); + subtree.insert(right, right_val); + + let half = 1 << (self.depth - key.0 - 1); + + if start < half { + self.fill_nodes(left, start, end, subtree)?; + } + + if end > half { + self.fill_nodes(right, start, end, subtree)?; + } + + Ok(()) + } + + // Recalculates tree in parallel (in-memory) + fn batch_recalculate(key: Key, subtree: &HashMap) { + todo!() + } + /// Computes a Merkle proof for the leaf at the specified index pub fn proof(&self, index: usize) -> Result> { if index >= self.capacity() {