mirror of
https://github.com/vacp2p/pmtree.git
synced 2025-02-20 02:58:20 +00:00
chore: implement recalculate tree function
This commit is contained in:
parent
b08d1710a0
commit
b032d03f53
@ -4,7 +4,7 @@
|
|||||||
//! ## How it stored
|
//! ## How it stored
|
||||||
//! { (usize::MAX - 1) : depth }
|
//! { (usize::MAX - 1) : depth }
|
||||||
//! { (usize::MAX) : next_index}
|
//! { (usize::MAX) : next_index}
|
||||||
//! { Position (tuple, converted to DBKey) : Value}
|
//! { Position (tuple - (depth, index), converted to DBKey) : Value}
|
||||||
|
|
||||||
pub mod database;
|
pub mod database;
|
||||||
pub mod hasher;
|
pub mod hasher;
|
||||||
|
53
src/tree.rs
53
src/tree.rs
@ -8,6 +8,7 @@ const DEPTH_KEY: DBKey = (usize::MAX - 1).to_be_bytes();
|
|||||||
const NEXT_INDEX_KEY: DBKey = usize::MAX.to_be_bytes();
|
const NEXT_INDEX_KEY: DBKey = usize::MAX.to_be_bytes();
|
||||||
|
|
||||||
// Denotes keys (depth, index) in Merkle Tree. Can be converted to DBKey
|
// Denotes keys (depth, index) in Merkle Tree. Can be converted to DBKey
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
struct Key(usize, usize);
|
struct Key(usize, usize);
|
||||||
impl From<Key> for DBKey {
|
impl From<Key> for DBKey {
|
||||||
fn from(key: Key) -> DBKey {
|
fn from(key: Key) -> DBKey {
|
||||||
@ -26,6 +27,7 @@ where
|
|||||||
h: PhantomData<H>,
|
h: PhantomData<H>,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
next_index: usize,
|
next_index: usize,
|
||||||
|
cache: Vec<H::Fr>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D, H> MerkleTree<D, H>
|
impl<D, H> MerkleTree<D, H>
|
||||||
@ -47,12 +49,15 @@ where
|
|||||||
let next_index_val = next_index.to_be_bytes().to_vec();
|
let next_index_val = next_index.to_be_bytes().to_vec();
|
||||||
db.put(NEXT_INDEX_KEY, next_index_val);
|
db.put(NEXT_INDEX_KEY, next_index_val);
|
||||||
|
|
||||||
|
// Cache nodes
|
||||||
|
let mut cache = Vec::with_capacity(depth + 1);
|
||||||
|
|
||||||
// Initialize one branch of the `Merkle Tree` from bottom to top
|
// Initialize one branch of the `Merkle Tree` from bottom to top
|
||||||
let mut prev = H::default_leaf();
|
cache[depth] = H::default_leaf();
|
||||||
db.put(Key(depth, 0).into(), prev.into());
|
db.put(Key(depth, 0).into(), cache[depth].into());
|
||||||
for i in (0..depth).rev() {
|
for i in (0..depth).rev() {
|
||||||
prev = H::hash(&[prev, prev]);
|
cache[i] = H::hash(&[cache[i + 1], cache[i + 1]]);
|
||||||
db.put(Key(i, 0).into(), prev.into());
|
db.put(Key(i, 0).into(), cache[i].into());
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -60,6 +65,7 @@ where
|
|||||||
h: PhantomData,
|
h: PhantomData,
|
||||||
depth,
|
depth,
|
||||||
next_index,
|
next_index,
|
||||||
|
cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,18 +75,25 @@ where
|
|||||||
let db = D::load(dbpath);
|
let db = D::load(dbpath);
|
||||||
|
|
||||||
// Load depth & next_index values from db
|
// Load depth & next_index values from db
|
||||||
// TODO: proper handling instead of unwrap
|
|
||||||
let depth = db.get(DEPTH_KEY).unwrap().try_into().unwrap();
|
let depth = db.get(DEPTH_KEY).unwrap().try_into().unwrap();
|
||||||
let depth = usize::from_be_bytes(depth);
|
let depth = usize::from_be_bytes(depth);
|
||||||
|
|
||||||
let next_index = db.get(NEXT_INDEX_KEY).unwrap().try_into().unwrap();
|
let next_index = db.get(NEXT_INDEX_KEY).unwrap().try_into().unwrap();
|
||||||
let next_index = usize::from_be_bytes(next_index);
|
let next_index = usize::from_be_bytes(next_index);
|
||||||
|
|
||||||
|
// Load cache vec
|
||||||
|
let mut cache = Vec::with_capacity(depth + 1);
|
||||||
|
cache[depth] = H::default_leaf();
|
||||||
|
for i in (0..depth).rev() {
|
||||||
|
cache[i] = H::hash(&[cache[i + 1], cache[i + 1]]);
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
db,
|
db,
|
||||||
h: PhantomData,
|
h: PhantomData,
|
||||||
depth,
|
depth,
|
||||||
next_index,
|
next_index,
|
||||||
|
cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,12 +124,38 @@ where
|
|||||||
|
|
||||||
/// Sets a leaf at the specified tree index
|
/// Sets a leaf at the specified tree index
|
||||||
fn set(&mut self, key: usize, leaf: H::Fr) {
|
fn set(&mut self, key: usize, leaf: H::Fr) {
|
||||||
todo!()
|
self.db.put(Key(self.depth, key).into(), leaf.into());
|
||||||
|
self.recalculate_from(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recalculates `Merkle Tree` from the specified key
|
// Recalculates `Merkle Tree` from the specified key
|
||||||
fn recalculate_from(&mut self, key: usize) {
|
fn recalculate_from(&mut self, key: usize) {
|
||||||
todo!()
|
let mut depth = self.depth;
|
||||||
|
let mut i = key;
|
||||||
|
|
||||||
|
while depth != 0 {
|
||||||
|
let value = self.hash_couple(depth, key);
|
||||||
|
i >>= 1;
|
||||||
|
depth -= 1;
|
||||||
|
self.db.put(Key(depth, i).into(), value.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hashes the right couple for the key
|
||||||
|
fn hash_couple(&mut self, depth: usize, key: usize) -> H::Fr {
|
||||||
|
let b = key & !1;
|
||||||
|
H::hash(&[
|
||||||
|
self.get_elem(Key(depth, b)),
|
||||||
|
self.get_elem(Key(depth, b + 1)),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns elem by the key
|
||||||
|
fn get_elem(&self, key: Key) -> H::Fr {
|
||||||
|
self.db
|
||||||
|
.get(key.into())
|
||||||
|
.unwrap_or_else(|| self.cache[key.0].into())
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the root of the tree
|
/// Returns the root of the tree
|
||||||
|
Loading…
x
Reference in New Issue
Block a user