#[allow(dead_code)]
mod support;
use digest::Digest;
use support::{combine_hashes, create_mmr, int_to_hash, Hasher};
use tari_mmr::MerkleMountainRange;
#[test]
fn zero_length_mmr() {
let mmr = MerkleMountainRange::<Hasher, _>::new(Vec::default());
assert_eq!(mmr.len(), Ok(0));
assert_eq!(mmr.is_empty(), Ok(true));
let empty_hash = Hasher::digest(b"").to_vec();
assert_eq!(mmr.get_merkle_root(), Ok(empty_hash));
}
#[test]
fn build_mmr() {
let mut mmr = MerkleMountainRange::<Hasher, _>::new(Vec::default());
let h0 = int_to_hash(0);
assert!(mmr.push(h0.clone()).is_ok());
assert_eq!(mmr.len(), Ok(1));
assert_eq!(mmr.get_merkle_root(), Ok(combine_hashes(&[&h0])));
let h1 = int_to_hash(1);
assert!(mmr.push(h1.clone()).is_ok());
let h_2 = combine_hashes(&[&h0, &h1]);
assert_eq!(mmr.get_merkle_root(), Ok(combine_hashes(&[&h_2])));
assert_eq!(mmr.len(), Ok(3));
let h3 = int_to_hash(3);
assert!(mmr.push(h3.clone()).is_ok());
let root = combine_hashes(&[&h_2, &h3]);
assert_eq!(mmr.get_merkle_root(), Ok(root));
assert_eq!(mmr.len(), Ok(4));
let h4 = int_to_hash(4);
assert!(mmr.push(h4.clone()).is_ok());
let h_5 = combine_hashes(&[&h3, &h4]);
let h_6 = combine_hashes(&[&h_2, &h_5]);
assert_eq!(mmr.get_merkle_root(), Ok(combine_hashes(&[&h_6])));
assert_eq!(mmr.len(), Ok(7));
let h7 = int_to_hash(7);
assert!(mmr.push(h7.clone()).is_ok());
let root = combine_hashes(&[&h_6, &h7]);
assert_eq!(mmr.get_merkle_root(), Ok(root));
assert_eq!(mmr.len(), Ok(8));
let h8 = int_to_hash(8);
let h_9 = combine_hashes(&[&h7, &h8]);
assert!(mmr.push(h8).is_ok());
let root = combine_hashes(&[&h_6, &h_9]);
assert_eq!(mmr.get_merkle_root(), Ok(root));
assert_eq!(mmr.len(), Ok(10));
}
#[test]
fn equality_check() {
let mut ma = MerkleMountainRange::<Hasher, _>::new(Vec::default());
let mut mb = MerkleMountainRange::<Hasher, _>::new(Vec::default());
assert!(ma == mb);
assert!(ma.push(int_to_hash(1)).is_ok());
assert!(ma != mb);
assert!(mb.push(int_to_hash(1)).is_ok());
assert!(ma == mb);
assert!(ma.push(int_to_hash(2)).is_ok());
assert!(mb.push(int_to_hash(3)).is_ok());
assert!(ma != mb);
}
#[test]
fn validate() {
let mmr = create_mmr(65);
assert!(mmr.validate().is_ok());
}
#[test]
fn restore_from_leaf_hashes() {
let mut mmr = MerkleMountainRange::<Hasher, _>::new(Vec::default());
let leaf_hashes = mmr.get_leaf_hashes(0, 1).unwrap();
assert_eq!(leaf_hashes.len(), 0);
let h0 = int_to_hash(0);
let h1 = int_to_hash(1);
let h2 = int_to_hash(2);
let h3 = int_to_hash(3);
assert!(mmr.push(h0.clone()).is_ok());
assert!(mmr.push(h1.clone()).is_ok());
assert!(mmr.push(h2.clone()).is_ok());
assert!(mmr.push(h3.clone()).is_ok());
assert_eq!(mmr.len(), Ok(7));
let leaf_count = mmr.get_leaf_count().unwrap();
let mut leaf_hashes = mmr.get_leaf_hashes(0, 2).unwrap();
leaf_hashes.append(&mut mmr.get_leaf_hashes(2, leaf_count - 2).unwrap());
assert_eq!(leaf_hashes.len(), 4);
assert_eq!(leaf_hashes[0], h0);
assert_eq!(leaf_hashes[1], h1);
assert_eq!(leaf_hashes[2], h2);
assert_eq!(leaf_hashes[3], h3);
assert!(mmr.push(int_to_hash(4)).is_ok());
assert!(mmr.push(int_to_hash(5)).is_ok());
assert_eq!(mmr.len(), Ok(10));
assert!(mmr.assign(leaf_hashes).is_ok());
assert_eq!(mmr.len(), Ok(7));
assert_eq!(mmr.get_leaf_hash(0), Ok(Some(h0)));
assert_eq!(mmr.get_leaf_hash(1), Ok(Some(h1)));
assert_eq!(mmr.get_leaf_hash(2), Ok(Some(h2)));
assert_eq!(mmr.get_leaf_hash(3), Ok(Some(h3)));
assert_eq!(mmr.get_leaf_hash(4), Ok(None));
}
#[test]
fn find_leaf_index() {
let mut mmr = MerkleMountainRange::<Hasher, _>::new(Vec::default());
let h0 = int_to_hash(0);
let h1 = int_to_hash(1);
let h2 = int_to_hash(2);
let h3 = int_to_hash(3);
let h4 = int_to_hash(4);
let h5 = int_to_hash(5);
assert!(mmr.push(h0.clone()).is_ok());
assert!(mmr.push(h1.clone()).is_ok());
assert!(mmr.push(h2.clone()).is_ok());
assert!(mmr.push(h3.clone()).is_ok());
assert!(mmr.push(h4.clone()).is_ok());
assert_eq!(mmr.len(), Ok(8));
assert_eq!(mmr.find_leaf_index(&h0), Ok(Some(0)));
assert_eq!(mmr.find_leaf_index(&h1), Ok(Some(1)));
assert_eq!(mmr.find_leaf_index(&h2), Ok(Some(2)));
assert_eq!(mmr.find_leaf_index(&h3), Ok(Some(3)));
assert_eq!(mmr.find_leaf_index(&h4), Ok(Some(4)));
assert_eq!(mmr.find_leaf_index(&h5), Ok(None));
}