#[allow(dead_code)]
mod support;
use croaring::Bitmap;
use digest::Digest;
use support::{create_mmr, int_to_hash, Hasher};
use tari_crypto::tari_utilities::hex::Hex;
use tari_mmr::{Hash, HashSlice, MutableMmr};
fn hash_with_bitmap(hash: &HashSlice, bitmap: &mut Bitmap) -> Hash {
bitmap.run_optimize();
let hasher = Hasher::new();
hasher.chain(hash).chain(&bitmap.serialize()).finalize().to_vec()
}
#[test]
fn zero_length_mmr() {
let mmr = MutableMmr::<Hasher, _>::new(Vec::default(), Bitmap::create()).unwrap();
assert_eq!(mmr.len(), 0);
assert_eq!(mmr.is_empty(), Ok(true));
let empty_hash = Hasher::digest(b"").to_vec();
assert_eq!(
mmr.get_merkle_root(),
Ok(hash_with_bitmap(&empty_hash, &mut Bitmap::create()))
);
}
#[test]
fn delete() {
let mut mmr = MutableMmr::<Hasher, _>::new(Vec::default(), Bitmap::create()).unwrap();
assert_eq!(mmr.is_empty(), Ok(true));
for i in 0..5 {
assert!(mmr.push(int_to_hash(i)).is_ok());
}
assert_eq!(mmr.len(), 5);
let root = mmr.get_merkle_root().unwrap();
assert_eq!(
&root.to_hex(),
"7b7ddec2af4f3d0b9b165750cf2ff15813e965d29ecd5318e0c8fea901ceaef4"
);
assert!(!mmr.delete(5));
assert_eq!(mmr.len(), 5);
assert_eq!(mmr.is_empty(), Ok(false));
assert_eq!(mmr.get_merkle_root(), Ok(root));
assert!(mmr.push(int_to_hash(5)).is_ok());
assert!(mmr.delete(0));
assert!(mmr.delete(2));
assert!(mmr.delete(4));
let root = mmr.get_merkle_root().unwrap();
assert_eq!(
&root.to_hex(),
"69e69ba0c6222f2d9caa68282de0ba7f1259a0fa2b8d84af68f907ef4ec05054"
);
assert_eq!(mmr.len(), 3);
assert_eq!(mmr.is_empty(), Ok(false));
assert!(!mmr.delete(0,));
assert!(!mmr.delete(2,));
assert!(!mmr.delete(0,));
assert!(!mmr.delete(9));
assert_eq!(mmr.len(), 3);
assert_eq!(mmr.is_empty(), Ok(false));
assert_eq!(mmr.get_merkle_root(), Ok(root));
assert!(mmr.delete(1));
assert!(mmr.delete(5));
assert!(mmr.delete(3));
assert_eq!(mmr.len(), 0);
assert_eq!(mmr.is_empty(), Ok(true));
mmr.compress();
let root = mmr.get_merkle_root().unwrap();
assert_eq!(
&root.to_hex(),
"2a540797d919e63cff8051e54ae13197315000bcfde53efd3f711bb3d24995bc"
);
}
#[test]
fn build_mmr() {
let mmr_check = create_mmr(5);
assert_eq!(mmr_check.len(), Ok(8));
let mut bitmap = Bitmap::create();
let mut mmr = MutableMmr::<Hasher, _>::new(Vec::default(), Bitmap::create()).unwrap();
for i in 0..5 {
assert!(mmr.push(int_to_hash(i)).is_ok());
}
assert_eq!(mmr.len(), 5);
let mmr_root = mmr_check.get_merkle_root().unwrap();
let root_check = hash_with_bitmap(&mmr_root, &mut bitmap);
assert_eq!(mmr.get_merkle_root(), Ok(root_check));
assert!(mmr.delete(3));
bitmap.add(3);
let root_check = hash_with_bitmap(&mmr_root, &mut bitmap);
assert_eq!(mmr.get_merkle_root(), Ok(root_check));
}
#[test]
fn equality_check() {
let mut ma = MutableMmr::<Hasher, _>::new(Vec::default(), Bitmap::create()).unwrap();
let mut mb = MutableMmr::<Hasher, _>::new(Vec::default(), Bitmap::create()).unwrap();
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!(ma != mb);
assert!(ma.delete(1));
assert!(ma != mb);
assert!(mb.push(int_to_hash(2)).is_ok());
assert!(mb.delete(1));
assert!(ma == mb);
}
#[test]
fn restore_from_leaf_nodes() {
let mut mmr = MutableMmr::<Hasher, _>::new(Vec::default(), Bitmap::create()).unwrap();
for i in 0..12 {
assert!(mmr.push(int_to_hash(i)).is_ok());
}
assert!(mmr.delete(2));
assert!(mmr.delete(4));
assert!(mmr.delete(5));
let leaf_count = mmr.get_leaf_count();
let mmr_state1 = mmr.to_leaf_nodes(0, leaf_count).unwrap();
let mut mmr_state2 = mmr.to_leaf_nodes(0, 3).unwrap();
mmr_state2.combine(mmr.to_leaf_nodes(3, 3).unwrap());
mmr_state2.combine(mmr.to_leaf_nodes(6, leaf_count - 6).unwrap());
assert_eq!(mmr_state1, mmr_state2);
let mmr_root = mmr.get_merkle_root();
assert!(mmr.push(int_to_hash(7)).is_ok());
assert!(mmr.push(int_to_hash(8)).is_ok());
assert!(mmr.delete(3));
assert!(mmr.assign(mmr_state1).is_ok());
assert_eq!(mmr.get_merkle_root(), mmr_root);
let restored_mmr_state = mmr.to_leaf_nodes(0, mmr.get_leaf_count()).unwrap();
assert_eq!(restored_mmr_state, mmr_state2);
}