use super::hashing::keccak_concat;
use jam_types::{Hash, MmrPeakHash};
use scale::{Decode, Encode};
#[derive(Debug, Encode, Decode, Eq, PartialEq, Clone, Default)]
pub struct Mmr {
pub peaks: Vec<Option<Hash>>,
}
impl Mmr {
pub fn new() -> Self {
Default::default()
}
pub fn append(&mut self, mut peak: Hash) {
for height in 0..usize::MAX {
match self.peaks.get_mut(height) {
None => {
self.peaks.push(Some(peak));
break
},
Some(p) => match p.take() {
None => {
*p = Some(peak);
break
},
Some(left) => peak = keccak_concat([&left[..], &peak[..]]),
},
}
}
}
pub fn root(&self) -> MmrPeakHash {
let mut iter = self.peaks.iter().filter_map(Option::as_ref);
let mut root = iter.next().cloned().unwrap_or_default();
for node in iter {
root = keccak_concat([b"peak", &root[..], &node[..]]);
}
root.into()
}
}