#[cfg(not(any(feature = "hashbrown")))]
use std::collections::HashMap;
use std::marker::PhantomData;
use std::path::Path;
use crate::Array;
#[cfg(feature = "hashbrown")]
use hashbrown::HashMap;
use crate::merkle_bit::{BinaryMerkleTreeResult, MerkleBIT, MerkleTree};
use crate::traits::{Decode, Encode};
use crate::tree::tree_branch::TreeBranch;
use crate::tree::tree_data::TreeData;
use crate::tree::tree_leaf::TreeLeaf;
use crate::tree::tree_node::TreeNode;
use crate::tree_db::HashTreeDB;
use crate::tree_hasher::TreeHasher;
type Tree<const N: usize, Value = Vec<u8>> = MerkleBIT<HashTree<N, Value>, N>;
pub struct HashTree<const N: usize = 32, Value: Encode + Decode = Vec<u8>> {
tree: Tree<N>,
_value: PhantomData<Value>,
}
impl<const N: usize, Value: Encode + Decode> MerkleTree<N> for HashTree<N, Value> {
type Database = HashTreeDB<N>;
type Branch = TreeBranch<N>;
type Leaf = TreeLeaf<N>;
type Data = TreeData;
type Node = TreeNode<N>;
type Hasher = TreeHasher;
type Value = Value;
}
impl<const N: usize> HashTree<N> {
#[inline]
pub fn new(depth: usize) -> BinaryMerkleTreeResult<Self> {
let path = Path::new("");
let tree = MerkleBIT::new(path, depth)?;
Ok(Self {
tree,
_value: PhantomData::default(),
})
}
#[inline]
pub fn open(path: &Path, depth: usize) -> BinaryMerkleTreeResult<Self> {
let tree = MerkleBIT::new(path, depth)?;
Ok(Self {
tree,
_value: PhantomData::default(),
})
}
#[inline]
pub fn get(
&self,
root_hash: &Array<N>,
keys: &mut [Array<N>],
) -> BinaryMerkleTreeResult<HashMap<Array<N>, Option<<Self as MerkleTree<N>>::Value>>> {
self.tree.get(root_hash, keys)
}
#[inline]
pub fn insert(
&mut self,
previous_root: Option<&Array<N>>,
keys: &mut [Array<N>],
values: &[<Self as MerkleTree<N>>::Value],
) -> BinaryMerkleTreeResult<Array<N>> {
self.tree.insert(previous_root, keys, values)
}
#[inline]
pub fn remove(&mut self, root_hash: &Array<N>) -> BinaryMerkleTreeResult<()> {
self.tree.remove(root_hash)
}
#[inline]
pub fn generate_inclusion_proof(
&self,
root: &Array<N>,
key: Array<N>,
) -> BinaryMerkleTreeResult<Vec<(Array<N>, bool)>> {
self.tree.generate_inclusion_proof(root, key)
}
#[inline]
pub fn verify_inclusion_proof(
root: &Array<N>,
key: Array<N>,
value: &<Self as MerkleTree<N>>::Value,
proof: &[(Array<N>, bool)],
) -> BinaryMerkleTreeResult<()> {
Tree::verify_inclusion_proof(root, key, value, proof)
}
#[inline]
pub fn get_one(
&self,
root: &Array<N>,
key: &Array<N>,
) -> BinaryMerkleTreeResult<Option<<Self as MerkleTree<N>>::Value>> {
self.tree.get_one(root, key)
}
#[inline]
pub fn insert_one(
&mut self,
previous_root: Option<&Array<N>>,
key: &Array<N>,
value: &<Self as MerkleTree<N>>::Value,
) -> BinaryMerkleTreeResult<Array<N>> {
self.tree.insert_one(previous_root, key, value)
}
#[inline]
#[must_use]
pub fn decompose(self) -> (HashTreeDB<N>, usize) {
self.tree.decompose()
}
}