mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 08:51:08 +03:00
Fix 2nd compact (#1143)
* add failing test to cover case where we compact an already compacted data file * fix the logic for pruning the data file
This commit is contained in:
parent
8f66016557
commit
fffee377dd
2 changed files with 78 additions and 3 deletions
|
@ -335,8 +335,9 @@ where
|
|||
let record_len = T::len() as u64;
|
||||
|
||||
let off_to_rm = map_vec!(leaf_pos_to_rm, |pos| {
|
||||
let shift = self.pruned_nodes.get_leaf_shift(*pos);
|
||||
(pmmr::n_leaves(pos - shift.unwrap()) - 1) * record_len
|
||||
let flat_pos = pmmr::n_leaves(*pos);
|
||||
let shift = self.pruned_nodes.get_leaf_shift(*pos).unwrap();
|
||||
(flat_pos - 1 - shift) * record_len
|
||||
});
|
||||
|
||||
self.data_file.save_prune(
|
||||
|
@ -352,6 +353,8 @@ where
|
|||
for &pos in &rm_pre_cutoff {
|
||||
self.pruned_nodes.add(pos);
|
||||
}
|
||||
// TODO - we can get rid of leaves in the prunelist here (and things still work)
|
||||
// self.pruned_nodes.pruned_nodes.retain(|&x| !pmmr::is_leaf(x));
|
||||
|
||||
write_vec(
|
||||
format!("{}/{}", self.data_dir, PMMR_PRUNED_FILE),
|
||||
|
|
|
@ -19,8 +19,8 @@ extern crate time;
|
|||
|
||||
use std::fs;
|
||||
|
||||
use core::ser::*;
|
||||
use core::core::pmmr::{Backend, PMMR};
|
||||
use core::ser::*;
|
||||
use store::types::prune_noop;
|
||||
|
||||
#[test]
|
||||
|
@ -566,6 +566,78 @@ fn pmmr_compact_horizon() {
|
|||
teardown(data_dir);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compact_twice() {
|
||||
let (data_dir, elems) = setup("compact_twice");
|
||||
|
||||
// setup the mmr store with all elements
|
||||
let mut backend = store::pmmr::PMMRBackend::new(data_dir.to_string()).unwrap();
|
||||
let mmr_size = load(0, &elems[..], &mut backend);
|
||||
backend.sync().unwrap();
|
||||
|
||||
// save the root
|
||||
let root = {
|
||||
let pmmr: PMMR<TestElem, _> = PMMR::at(&mut backend, mmr_size);
|
||||
pmmr.root()
|
||||
};
|
||||
|
||||
// pruning some choice nodes
|
||||
{
|
||||
let mut pmmr: PMMR<TestElem, _> = PMMR::at(&mut backend, mmr_size);
|
||||
pmmr.prune(1, 1).unwrap();
|
||||
pmmr.prune(2, 1).unwrap();
|
||||
pmmr.prune(4, 1).unwrap();
|
||||
}
|
||||
backend.sync().unwrap();
|
||||
|
||||
// check the root and stored data
|
||||
{
|
||||
let pmmr: PMMR<TestElem, _> = PMMR::at(&mut backend, mmr_size);
|
||||
assert_eq!(root, pmmr.root());
|
||||
assert_eq!(pmmr.get_data(5).unwrap(), TestElem(4));
|
||||
assert_eq!(pmmr.get_data(11).unwrap(), TestElem(7));
|
||||
}
|
||||
|
||||
// compact
|
||||
backend.check_compact(2, 2, &prune_noop).unwrap();
|
||||
|
||||
// recheck the root and stored data
|
||||
{
|
||||
let pmmr: PMMR<TestElem, _> = PMMR::at(&mut backend, mmr_size);
|
||||
assert_eq!(root, pmmr.root());
|
||||
assert_eq!(pmmr.get_data(5).unwrap(), TestElem(4));
|
||||
assert_eq!(pmmr.get_data(11).unwrap(), TestElem(7));
|
||||
}
|
||||
|
||||
// now prune some more nodes
|
||||
{
|
||||
let mut pmmr: PMMR<TestElem, _> = PMMR::at(&mut backend, mmr_size);
|
||||
pmmr.prune(5, 2).unwrap();
|
||||
pmmr.prune(8, 2).unwrap();
|
||||
pmmr.prune(9, 2).unwrap();
|
||||
}
|
||||
backend.sync().unwrap();
|
||||
|
||||
// recheck the root and stored data
|
||||
{
|
||||
let pmmr: PMMR<TestElem, _> = PMMR::at(&mut backend, mmr_size);
|
||||
assert_eq!(root, pmmr.root());
|
||||
assert_eq!(pmmr.get_data(11).unwrap(), TestElem(7));
|
||||
}
|
||||
|
||||
// compact
|
||||
backend.check_compact(2, 3, &prune_noop).unwrap();
|
||||
|
||||
// recheck the root and stored data
|
||||
{
|
||||
let pmmr: PMMR<TestElem, _> = PMMR::at(&mut backend, mmr_size);
|
||||
assert_eq!(root, pmmr.root());
|
||||
assert_eq!(pmmr.get_data(11).unwrap(), TestElem(7));
|
||||
}
|
||||
|
||||
teardown(data_dir);
|
||||
}
|
||||
|
||||
fn setup(tag: &str) -> (String, Vec<TestElem>) {
|
||||
let _ = env_logger::init();
|
||||
let t = time::get_time();
|
||||
|
|
Loading…
Reference in a new issue