jam_std_common/crypto/
mmr.rs1use super::hashing::keccak_concat;
2use jam_types::{Hash, MmrPeakHash};
3use scale::{Decode, Encode};
4
5#[derive(Debug, Encode, Decode, Eq, PartialEq, Clone, Default)]
6pub struct Mmr {
7 pub peaks: Vec<Option<Hash>>,
8}
9
10impl Mmr {
11 pub fn new() -> Self {
13 Default::default()
14 }
15
16 pub fn append(&mut self, mut peak: Hash) {
18 for height in 0..usize::MAX {
19 match self.peaks.get_mut(height) {
20 None => {
21 self.peaks.push(Some(peak));
22 break
23 },
24 Some(p) => match p.take() {
25 None => {
26 *p = Some(peak);
27 break
28 },
29 Some(left) => peak = keccak_concat([&left[..], &peak[..]]),
30 },
31 }
32 }
33 }
34
35 pub fn root(&self) -> MmrPeakHash {
37 let mut iter = self.peaks.iter().filter_map(Option::as_ref);
38 let mut root = iter.next().cloned().unwrap_or_default();
39 for node in iter {
40 root = keccak_concat([b"peak", &root[..], &node[..]]);
41 }
42 root.into()
43 }
44}