use env_logger;
use grin_core as core;
use grin_store as store;
use std::fs;
use chrono::prelude::Utc;
use croaring::Bitmap;
use crate::core::core::hash::DefaultHashable;
use crate::core::core::pmmr::{Backend, ReadablePMMR, PMMR};
use crate::core::ser::{
Error, PMMRIndexHashable, PMMRable, ProtocolVersion, Readable, Reader, Writeable, Writer,
};
#[test]
fn pmmr_leaf_idx_iter() {
let (data_dir, elems) = setup("leaf_idx_iter");
{
let mut backend =
store::pmmr::PMMRBackend::new(data_dir.to_string(), true, ProtocolVersion(1), None)
.unwrap();
let mmr_size = load(0, &elems[0..5], &mut backend);
backend.sync().unwrap();
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
let leaf_idx = pmmr.leaf_idx_iter(0).collect::<Vec<_>>();
let leaf_pos = pmmr.leaf_pos_iter().collect::<Vec<_>>();
assert_eq!(leaf_idx, vec![0, 1, 2, 3, 4]);
assert_eq!(leaf_pos, vec![0, 1, 3, 4, 7]);
}
}
teardown(data_dir);
}
#[test]
fn pmmr_append() {
let (data_dir, elems) = setup("append");
{
let mut backend =
store::pmmr::PMMRBackend::new(data_dir.to_string(), false, ProtocolVersion(1), None)
.unwrap();
let mut mmr_size = load(0, &elems[0..4], &mut backend);
backend.sync().unwrap();
let pos_0 = elems[0].hash_with_index(0);
let pos_1 = elems[1].hash_with_index(1);
let pos_2 = (pos_0, pos_1).hash_with_index(2);
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
assert_eq!(pmmr.n_unpruned_leaves(), 4);
assert_eq!(pmmr.get_data(0), Some(elems[0]));
assert_eq!(pmmr.get_data(1), Some(elems[1]));
assert_eq!(pmmr.get_hash(0), Some(pos_0));
assert_eq!(pmmr.get_hash(1), Some(pos_1));
assert_eq!(pmmr.get_hash(2), Some(pos_2));
}
mmr_size = load(mmr_size, &elems[4..9], &mut backend);
backend.sync().unwrap();
let pos_3 = elems[2].hash_with_index(3);
let pos_4 = elems[3].hash_with_index(4);
let pos_5 = (pos_3, pos_4).hash_with_index(5);
let pos_6 = (pos_2, pos_5).hash_with_index(6);
let pos_7 = elems[4].hash_with_index(7);
let pos_8 = elems[5].hash_with_index(8);
let pos_9 = (pos_7, pos_8).hash_with_index(9);
let pos_10 = elems[6].hash_with_index(10);
let pos_11 = elems[7].hash_with_index(11);
let pos_12 = (pos_10, pos_11).hash_with_index(12);
let pos_13 = (pos_9, pos_12).hash_with_index(13);
let pos_14 = (pos_6, pos_13).hash_with_index(14);
let pos_15 = elems[8].hash_with_index(15);
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
assert_eq!(pmmr.n_unpruned_leaves(), 9);
assert_eq!(pmmr.get_data(0), Some(elems[0]));
assert_eq!(pmmr.get_data(1), Some(elems[1]));
assert_eq!(pmmr.get_data(3), Some(elems[2]));
assert_eq!(pmmr.get_data(4), Some(elems[3]));
assert_eq!(pmmr.get_data(7), Some(elems[4]));
assert_eq!(pmmr.get_data(8), Some(elems[5]));
assert_eq!(pmmr.get_hash(9), Some(pos_9));
}
let node_hash = elems[0].hash_with_index(0);
assert_eq!(backend.get_hash(0).unwrap(), node_hash);
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
assert_eq!(pmmr.root().unwrap(), (pos_14, pos_15).hash_with_index(16));
}
}
teardown(data_dir);
}
#[test]
fn pmmr_compact_leaf_sibling() {
let (data_dir, elems) = setup("compact_leaf_sibling");
{
let mut backend =
store::pmmr::PMMRBackend::new(data_dir.to_string(), true, ProtocolVersion(1), None)
.unwrap();
let mmr_size = load(0, &elems[..], &mut backend);
backend.sync().unwrap();
assert_eq!(backend.n_unpruned_leaves(), 19);
let (pos_0_hash, pos_1_hash, pos_2_hash) = {
let pmmr = PMMR::at(&mut backend, mmr_size);
(
pmmr.get_hash(0).unwrap(),
pmmr.get_hash(1).unwrap(),
pmmr.get_hash(2).unwrap(),
)
};
{
let mut pmmr = PMMR::at(&mut backend, mmr_size);
pmmr.prune(0).unwrap();
pmmr.prune(7).unwrap();
}
backend.sync().unwrap();
{
let pmmr = PMMR::at(&mut backend, mmr_size);
assert_eq!(pmmr.n_unpruned_leaves(), 17);
assert_eq!(pmmr.get_hash(0), None);
assert_eq!(pmmr.get_hash(1).unwrap(), pos_1_hash);
assert_eq!(pmmr.get_hash(2).unwrap(), pos_2_hash);
}
assert_eq!(backend.get_from_file(0).unwrap(), pos_0_hash);
backend.check_compact(1, &Bitmap::new()).unwrap();
{
let pmmr = PMMR::at(&mut backend, mmr_size);
assert_eq!(pmmr.get_hash(0), None);
assert_eq!(pmmr.get_hash(1).unwrap(), pos_1_hash);
assert_eq!(pmmr.get_hash(2).unwrap(), pos_2_hash);
}
assert_eq!(backend.get_from_file(0).unwrap(), pos_0_hash);
}
teardown(data_dir);
}
#[test]
fn pmmr_prune_compact() {
let (data_dir, elems) = setup("prune_compact");
{
let mut backend =
store::pmmr::PMMRBackend::new(data_dir.to_string(), true, ProtocolVersion(1), None)
.unwrap();
let mmr_size = load(0, &elems[..], &mut backend);
backend.sync().unwrap();
let root = {
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.root().unwrap()
};
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.prune(0).unwrap();
pmmr.prune(3).unwrap();
pmmr.prune(4).unwrap();
}
backend.sync().unwrap();
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
assert_eq!(root, pmmr.root().unwrap());
assert_eq!(pmmr.get_data(1).unwrap(), TestElem(2));
assert_eq!(pmmr.get_data(10).unwrap(), TestElem(7));
}
backend.check_compact(2, &Bitmap::new()).unwrap();
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
assert_eq!(root, pmmr.root().unwrap());
assert_eq!(pmmr.get_data(1).unwrap(), TestElem(2));
assert_eq!(pmmr.get_data(10).unwrap(), TestElem(7));
}
}
teardown(data_dir);
}
#[test]
fn pmmr_reload() {
let (data_dir, elems) = setup("reload");
{
let mut backend =
store::pmmr::PMMRBackend::new(data_dir.to_string(), true, ProtocolVersion(1), None)
.unwrap();
let mmr_size = load(0, &elems[..], &mut backend);
let pos_2_hash = backend.get_hash(2).unwrap();
let pos_3_hash = backend.get_hash(3).unwrap();
let pos_4_hash = backend.get_hash(4).unwrap();
let root = {
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.root().unwrap()
};
{
backend.sync().unwrap();
assert_eq!(backend.unpruned_size(), mmr_size);
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.prune(0).unwrap();
}
backend.sync().unwrap();
assert_eq!(backend.unpruned_size(), mmr_size);
backend.check_compact(1, &Bitmap::new()).unwrap();
assert_eq!(backend.unpruned_size(), mmr_size);
backend.sync().unwrap();
assert_eq!(backend.unpruned_size(), mmr_size);
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.prune(3).unwrap();
pmmr.prune(1).unwrap();
}
backend.sync().unwrap();
assert_eq!(backend.unpruned_size(), mmr_size);
backend.check_compact(4, &Bitmap::new()).unwrap();
backend.sync().unwrap();
assert_eq!(backend.unpruned_size(), mmr_size);
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.prune(4).unwrap();
}
backend.sync().unwrap();
assert_eq!(backend.unpruned_size(), mmr_size);
}
{
let mut backend =
store::pmmr::PMMRBackend::new(data_dir.to_string(), true, ProtocolVersion(1), None)
.unwrap();
assert_eq!(backend.unpruned_size(), mmr_size);
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
assert_eq!(root, pmmr.root().unwrap());
}
assert_eq!(backend.get_hash(0), None);
assert_eq!(backend.get_hash(1), None);
assert_eq!(backend.get_hash(2), Some(pos_2_hash));
assert_eq!(backend.get_hash(3), None);
assert_eq!(backend.get_hash(4), None);
assert_eq!(backend.get_from_file(0), None);
assert_eq!(backend.get_from_file(1), None);
assert_eq!(backend.get_from_file(2), Some(pos_2_hash));
assert_eq!(backend.get_from_file(3), Some(pos_3_hash));
assert_eq!(backend.get_from_file(4), Some(pos_4_hash));
}
}
teardown(data_dir);
}
#[test]
fn pmmr_rewind() {
let (data_dir, elems) = setup("rewind");
{
let mut backend =
store::pmmr::PMMRBackend::new(data_dir.clone(), true, ProtocolVersion(1), None)
.unwrap();
let mut mmr_size = load(0, &elems[0..4], &mut backend);
backend.sync().unwrap();
let root1 = {
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.root().unwrap()
};
mmr_size = load(mmr_size, &elems[4..6], &mut backend);
backend.sync().unwrap();
let root2 = {
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
assert_eq!(pmmr.unpruned_size(), 10);
pmmr.root().unwrap()
};
mmr_size = load(mmr_size, &elems[6..9], &mut backend);
backend.sync().unwrap();
let root3 = {
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
assert_eq!(pmmr.unpruned_size(), 16);
pmmr.root().unwrap()
};
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.prune(0).unwrap();
pmmr.prune(1).unwrap();
pmmr.prune(3).unwrap();
pmmr.prune(4).unwrap();
}
backend.sync().unwrap();
backend.check_compact(6, &Bitmap::new()).unwrap();
backend.sync().unwrap();
println!("root1 {:?}, root2 {:?}, root3 {:?}", root1, root2, root3);
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.rewind(9, &Bitmap::of(&vec![11, 12, 16])).unwrap();
assert_eq!(pmmr.unpruned_size(), 10);
assert_eq!(pmmr.root().unwrap(), root2);
}
backend.sync().unwrap();
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, 10);
assert_eq!(pmmr.root().unwrap(), root2);
}
for pos in vec![0, 1, 3, 4] {
assert_eq!(backend.get_data(pos), None);
}
for pos in vec![2, 5, 6] {
assert_eq!(backend.get_data(pos), None);
}
assert_eq!(backend.get_data(7), Some(elems[4]));
assert_eq!(backend.get_hash(7), Some(elems[4].hash_with_index(7)));
assert_eq!(backend.get_data(8), Some(elems[5]));
assert_eq!(backend.get_hash(8), Some(elems[5].hash_with_index(8)));
println!("***** backend size here: {}", backend.data_size());
assert_eq!(backend.data_size(), 2);
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, 10);
pmmr.rewind(5, &Bitmap::new()).unwrap();
assert_eq!(pmmr.root().unwrap(), root1);
}
backend.sync().unwrap();
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, 7);
assert_eq!(pmmr.root().unwrap(), root1);
}
for pos in 0..16 {
assert_eq!(backend.get_data(pos), None);
}
println!("***** backend hash size here: {}", backend.hash_size());
println!("***** backend data size here: {}", backend.data_size());
assert_eq!(backend.hash_size(), 1);
assert_eq!(backend.data_size(), 0);
}
teardown(data_dir);
}
#[test]
fn pmmr_compact_single_leaves() {
let (data_dir, elems) = setup("compact_single_leaves");
{
let mut backend =
store::pmmr::PMMRBackend::new(data_dir.clone(), true, ProtocolVersion(1), None)
.unwrap();
let mmr_size = load(0, &elems[0..5], &mut backend);
backend.sync().unwrap();
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.prune(0).unwrap();
pmmr.prune(3).unwrap();
}
backend.sync().unwrap();
backend.check_compact(2, &Bitmap::new()).unwrap();
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.prune(1).unwrap();
pmmr.prune(4).unwrap();
}
backend.sync().unwrap();
backend.check_compact(2, &Bitmap::new()).unwrap();
}
teardown(data_dir);
}
#[test]
fn pmmr_compact_entire_peak() {
let (data_dir, elems) = setup("compact_entire_peak");
{
let mut backend =
store::pmmr::PMMRBackend::new(data_dir.clone(), true, ProtocolVersion(1), None)
.unwrap();
let mmr_size = load(0, &elems[0..5], &mut backend);
backend.sync().unwrap();
let pos_6_hash = backend.get_hash(6).unwrap();
let pos_7 = backend.get_data(7).unwrap();
let pos_7_hash = backend.get_hash(7).unwrap();
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.prune(0).unwrap();
pmmr.prune(1).unwrap();
pmmr.prune(3).unwrap();
pmmr.prune(4).unwrap();
}
backend.sync().unwrap();
backend.check_compact(2, &Bitmap::new()).unwrap();
assert_eq!(backend.get_hash(6), Some(pos_6_hash));
assert_eq!(backend.get_from_file(6), Some(pos_6_hash));
assert_eq!(backend.get_data(7), Some(pos_7));
assert_eq!(backend.get_hash(7), Some(pos_7_hash));
assert_eq!(backend.get_from_file(7), Some(pos_7_hash));
}
teardown(data_dir);
}
#[test]
fn pmmr_compact_horizon() {
let (data_dir, elems) = setup("compact_horizon");
{
let pos_0_hash;
let pos_1_hash;
let pos_2_hash;
let pos_5_hash;
let pos_6_hash;
let pos_7;
let pos_7_hash;
let pos_10;
let pos_10_hash;
let mmr_size;
{
let mut backend =
store::pmmr::PMMRBackend::new(data_dir.clone(), true, ProtocolVersion(1), None)
.unwrap();
mmr_size = load(0, &elems[..], &mut backend);
backend.sync().unwrap();
assert_eq!(backend.data_size(), 19);
assert_eq!(backend.hash_size(), 35);
pos_0_hash = backend.get_hash(0).unwrap();
pos_1_hash = backend.get_hash(1).unwrap();
pos_2_hash = backend.get_hash(2).unwrap();
pos_5_hash = backend.get_hash(5).unwrap();
pos_6_hash = backend.get_hash(6).unwrap();
pos_7 = backend.get_data(7).unwrap();
pos_7_hash = backend.get_hash(7).unwrap();
pos_10 = backend.get_data(10).unwrap();
pos_10_hash = backend.get_hash(10).unwrap();
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.prune(3).unwrap();
pmmr.prune(4).unwrap();
pmmr.prune(0).unwrap();
pmmr.prune(1).unwrap();
}
backend.sync().unwrap();
{
assert_eq!(backend.get_from_file(2), Some(pos_2_hash));
assert_eq!(backend.get_from_file(5), Some(pos_5_hash));
assert_eq!(backend.get_from_file(6), Some(pos_6_hash));
assert_eq!(backend.get_hash(7), Some(pos_7_hash));
assert_eq!(backend.get_data(7), Some(pos_7));
assert_eq!(backend.get_from_file(7), Some(pos_7_hash));
assert_eq!(backend.get_hash(10), Some(pos_10_hash));
assert_eq!(backend.get_data(10), Some(pos_10));
assert_eq!(backend.get_from_file(10), Some(pos_10_hash));
}
backend.check_compact(4, &Bitmap::of(&vec![1, 2])).unwrap();
backend.sync().unwrap();
{
assert_eq!(backend.get_hash(0), None);
assert_eq!(backend.get_from_file(0), Some(pos_0_hash));
assert_eq!(backend.get_hash(1), None);
assert_eq!(backend.get_from_file(1), Some(pos_1_hash));
assert_eq!(backend.get_hash(2), Some(pos_2_hash));
assert_eq!(backend.get_hash(3), None);
assert_eq!(backend.get_hash(4), None);
assert_eq!(backend.get_hash(5), Some(pos_5_hash));
assert_eq!(backend.get_from_file(6), Some(pos_6_hash));
assert_eq!(backend.get_hash(7), Some(pos_7_hash));
assert_eq!(backend.get_from_file(7), Some(pos_7_hash));
}
}
{
let backend = store::pmmr::PMMRBackend::<TestElem>::new(
data_dir.to_string(),
true,
ProtocolVersion(1),
None,
)
.unwrap();
assert_eq!(backend.data_size(), 19);
assert_eq!(backend.hash_size(), 35);
assert_eq!(backend.get_hash(6), Some(pos_6_hash));
assert_eq!(backend.get_from_file(6), Some(pos_6_hash));
assert_eq!(backend.get_hash(7), Some(pos_7_hash));
assert_eq!(backend.get_from_file(7), Some(pos_7_hash));
}
{
let mut backend = store::pmmr::PMMRBackend::<TestElem>::new(
data_dir.to_string(),
true,
ProtocolVersion(1),
None,
)
.unwrap();
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.prune(7).unwrap();
pmmr.prune(8).unwrap();
}
backend.check_compact(9, &Bitmap::new()).unwrap();
}
{
let backend = store::pmmr::PMMRBackend::<TestElem>::new(
data_dir.to_string(),
true,
ProtocolVersion(1),
None,
)
.unwrap();
assert_eq!(backend.data_size(), 13);
assert_eq!(backend.hash_size(), 27);
assert_eq!(backend.get_hash(6), Some(pos_6_hash));
assert_eq!(backend.get_from_file(6), Some(pos_6_hash));
assert_eq!(backend.get_hash(10), Some(pos_10_hash));
assert_eq!(backend.get_data(10), Some(pos_10));
assert_eq!(backend.get_from_file(10), Some(pos_10_hash));
}
}
teardown(data_dir);
}
#[test]
fn compact_twice() {
let (data_dir, elems) = setup("compact_twice");
{
let mut backend =
store::pmmr::PMMRBackend::new(data_dir.to_string(), true, ProtocolVersion(1), None)
.unwrap();
let mmr_size = load(0, &elems[..], &mut backend);
backend.sync().unwrap();
let root = {
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.root().unwrap()
};
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.prune(0).unwrap();
pmmr.prune(1).unwrap();
pmmr.prune(3).unwrap();
}
backend.sync().unwrap();
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
assert_eq!(root, pmmr.root().unwrap());
assert_eq!(pmmr.get_data(4).unwrap(), TestElem(4));
assert_eq!(pmmr.get_data(10).unwrap(), TestElem(7));
}
backend.check_compact(2, &Bitmap::new()).unwrap();
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
assert_eq!(root, pmmr.root().unwrap());
assert_eq!(pmmr.get_data(4).unwrap(), TestElem(4));
assert_eq!(pmmr.get_data(10).unwrap(), TestElem(7));
}
{
let mut pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
pmmr.prune(4).unwrap();
pmmr.prune(7).unwrap();
pmmr.prune(8).unwrap();
}
backend.sync().unwrap();
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
assert_eq!(root, pmmr.root().unwrap());
assert_eq!(pmmr.get_data(10).unwrap(), TestElem(7));
}
backend.check_compact(2, &Bitmap::new()).unwrap();
{
let pmmr: PMMR<'_, TestElem, _> = PMMR::at(&mut backend, mmr_size);
assert_eq!(root, pmmr.root().unwrap());
assert_eq!(pmmr.get_data(10).unwrap(), TestElem(7));
}
}
teardown(data_dir);
}
#[test]
fn cleanup_rewind_files_test() {
let expected = 10;
let prefix_to_delete = "foo";
let prefix_to_save = "bar";
let seconds_to_delete_after = 100;
let (data_dir, _) = setup("cleanup_rewind_files_test");
create_numbered_files(&data_dir, expected, prefix_to_delete, 0, 0);
create_numbered_files(
&data_dir,
expected,
prefix_to_delete,
seconds_to_delete_after + 1,
expected,
);
create_numbered_files(
&data_dir,
expected,
prefix_to_save,
seconds_to_delete_after,
0,
);
let actual =
store::pmmr::clean_files_by_prefix(&data_dir, prefix_to_delete, seconds_to_delete_after)
.unwrap();
assert_eq!(
actual, expected,
"the clean files by prefix function did not report the correct number of files deleted"
);
{
let count_fn = |prefix| {
let mut remaining_count = 0;
for entry in fs::read_dir(&data_dir).unwrap() {
if entry
.unwrap()
.file_name()
.into_string()
.unwrap()
.starts_with(prefix)
{
remaining_count += 1;
}
}
remaining_count
};
assert_eq!(
count_fn(prefix_to_delete),
expected, "it should delete all of the files it is supposed to delete"
);
assert_eq!(
count_fn(prefix_to_save),
expected,
"it should delete none of the files it is not supposed to"
);
}
teardown(data_dir);
}
fn create_numbered_files(
data_dir: &str,
num_files: u32,
prefix: &str,
last_accessed_delay_seconds: u64,
start_index: u32,
) {
let now = std::time::SystemTime::now();
let time_to_set = now - std::time::Duration::from_secs(last_accessed_delay_seconds);
let time_to_set_ft = filetime::FileTime::from_system_time(time_to_set);
for rewind_file_num in 0..num_files {
let path = std::path::Path::new(&data_dir).join(format!(
"{}.{}",
prefix,
start_index + rewind_file_num
));
let file = fs::File::create(path.clone()).unwrap();
let _metadata = file.metadata().unwrap();
filetime::set_file_times(path, time_to_set_ft, time_to_set_ft).unwrap();
}
}
fn setup(tag: &str) -> (String, Vec<TestElem>) {
match env_logger::try_init() {
Ok(_) => println!("Initializing env logger"),
Err(e) => println!("env logger already initialized: {:?}", e),
};
let t = Utc::now();
let data_dir = format!(
"./target/tmp/{}.{}-{}",
t.timestamp(),
t.timestamp_subsec_nanos(),
tag
);
fs::create_dir_all(data_dir.clone()).unwrap();
let mut elems = vec![];
for x in 1..20 {
elems.push(TestElem(x));
}
(data_dir, elems)
}
fn teardown(data_dir: String) {
fs::remove_dir_all(data_dir).unwrap();
}
fn load(pos: u64, elems: &[TestElem], backend: &mut store::pmmr::PMMRBackend<TestElem>) -> u64 {
let mut pmmr = PMMR::at(backend, pos);
for elem in elems {
pmmr.push(elem).unwrap();
}
pmmr.unpruned_size()
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
struct TestElem(u32);
impl DefaultHashable for TestElem {}
impl PMMRable for TestElem {
type E = Self;
fn as_elmt(&self) -> Self::E {
self.clone()
}
fn elmt_size() -> Option<u16> {
Some(4)
}
}
impl Writeable for TestElem {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), Error> {
writer.write_u32(self.0)
}
}
impl Readable for TestElem {
fn read<R: Reader>(reader: &mut R) -> Result<TestElem, Error> {
Ok(TestElem(reader.read_u32()?))
}
}