use services::ledger::merkletree::tree::{ Tree, LeavesIterator, LeavesIntoIterator, TreeLeafData };
use services::ledger::merkletree::proof::{ Proof, Lemma };
use utils::crypto::hash::{Hash, HASH_OUTPUT_LEN};
use errors::common::CommonError;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct MerkleTree {
pub root: Tree,
pub height: usize,
pub count: usize,
pub nodes_count: usize
}
impl MerkleTree {
pub fn from_vec(values: Vec<TreeLeafData>) -> Result<Self, CommonError> {
if values.is_empty() {
return Ok(MerkleTree {
root: Tree::empty(Hash::hash_empty()?),
height: 0,
count: 0,
nodes_count: 0
});
}
let count = values.len();
let mut nodes_count = 0;
let mut height = 0;
let mut cur = Vec::with_capacity(count);
for v in values {
let leaf = Tree::new_leaf(v)?;
cur.push(leaf);
}
while cur.len() > 1 {
let mut next = Vec::new();
while !cur.is_empty() {
if cur.len() == 1 {
next.push(cur.remove(0));
}
else {
let left = cur.remove(0);
let right = cur.remove(0);
let combined_hash = Hash::hash_nodes(
left.hash(),
right.hash()
)?;
let node = Tree::Node {
hash: combined_hash.to_vec(),
left: Box::new(left),
right: Box::new(right)
};
next.push(node);
nodes_count+=1;
}
}
height += 1;
cur = next;
}
debug_assert!(cur.len() == 1);
let root = cur.remove(0);
Ok(MerkleTree {
root: root,
height: height,
count: count,
nodes_count: nodes_count
})
}
pub fn root_hash(&self) -> &Vec<u8> {
self.root.hash()
}
pub fn root_hash_hex(&self) -> String {
let rh = self.root.hash();
let mut ret:String = String::with_capacity(HASH_OUTPUT_LEN*2);
for i in rh {
ret.push_str(&format!("{:02x}", i));
}
return ret;
}
pub fn height(&self) -> usize {
self.height
}
pub fn count(&self) -> usize {
self.count
}
pub fn is_empty(&self) -> bool {
self.count() == 0
}
pub fn gen_proof(&self, value: TreeLeafData) -> Result<Option<Proof>, CommonError> {
let root_hash = self.root_hash().clone();
let leaf_hash = Hash::hash_leaf(&value)?;
Ok(Lemma::new(&self.root, leaf_hash.to_vec().as_slice()).map(|lemma|
Proof::new(root_hash, lemma, value)
))
}
pub fn iter(&self) -> LeavesIterator {
self.root.iter()
}
}
impl IntoIterator for MerkleTree {
type Item = TreeLeafData;
type IntoIter = LeavesIntoIterator;
fn into_iter(self) -> Self::IntoIter {
self.root.into_iter()
}
}
impl <'a> IntoIterator for &'a MerkleTree {
type Item = &'a TreeLeafData;
type IntoIter = LeavesIterator<'a>;
fn into_iter(self) -> Self::IntoIter {
self.root.iter()
}
}