diff --git a/src/database.rs b/src/database.rs index cb61a89..ba0faaa 100644 --- a/src/database.rs +++ b/src/database.rs @@ -4,6 +4,6 @@ use crate::*; pub trait Database { fn new(dbpath: &str) -> Self; fn get(&self, key: &[u8]) -> Result>>; - fn put(&mut self, key: &[u8]) -> Result<()>; + fn put(&mut self, key: &[u8], value: &[u8]) -> Result<()>; fn delete(&mut self, key: &[u8]) -> Result<()>; } diff --git a/src/hasher.rs b/src/hasher.rs index f2cb554..2bae535 100644 --- a/src/hasher.rs +++ b/src/hasher.rs @@ -1,7 +1,12 @@ +pub trait ToBytes { + fn to_bytes(&self) -> Vec; +} + /// Trait that must be implemented for Hash Function pub trait Hasher { - type Fr: Copy + Eq + Default; + type Fr: Copy + Eq + Default + From> + Into>; fn new() -> Self; + fn default_leaf() -> Self::Fr; fn hash(input: &[Self::Fr]) -> Self::Fr; } diff --git a/src/tree.rs b/src/tree.rs index a503a4b..5980396 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -11,19 +11,39 @@ where next_index: usize, } +pub(crate) struct Key(usize, usize); + +impl From for Vec { + fn from(key: Key) -> Vec { + todo!() + } +} + impl MerkleTree where D: Database, H: Hasher, { /// Creates new `MerkleTree` - pub fn new(depth: usize, dbpath: &str) -> Self { - Self { - db: Database::new(dbpath), + pub fn new(depth: usize, dbpath: &str) -> Result { + // TODO: Use open instead of new, and check if the database is exists + let mut db: D = Database::new(dbpath); + + db.put(&Vec::::from(Key(depth, 0)), &H::default_leaf().into())?; + for i in (0..depth).rev() { + let prev = db.get(&Vec::::from(Key(i + 1, 0)))?.unwrap(); + db.put( + &Vec::::from(Key(i, 0)), + &H::hash(&[prev.clone().into(), prev.into()]).into(), + )?; + } + + Ok(Self { + db, h: Hasher::new(), depth, next_index: 0, - } + }) } /// Inserts a leaf to the next available index @@ -31,6 +51,11 @@ where todo!() } + /// Recalculates `Merkle Tree` from the specified key + fn recalculate_from(&mut self, key: usize) { + todo!() + } + /// Deletes a leaf at the `key` by setting it to its default value pub fn delete(&mut self, key: usize) { todo!()