mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-01 17:01:09 +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 record_len = T::len() as u64;
|
||||||
|
|
||||||
let off_to_rm = map_vec!(leaf_pos_to_rm, |pos| {
|
let off_to_rm = map_vec!(leaf_pos_to_rm, |pos| {
|
||||||
let shift = self.pruned_nodes.get_leaf_shift(*pos);
|
let flat_pos = pmmr::n_leaves(*pos);
|
||||||
(pmmr::n_leaves(pos - shift.unwrap()) - 1) * record_len
|
let shift = self.pruned_nodes.get_leaf_shift(*pos).unwrap();
|
||||||
|
(flat_pos - 1 - shift) * record_len
|
||||||
});
|
});
|
||||||
|
|
||||||
self.data_file.save_prune(
|
self.data_file.save_prune(
|
||||||
|
@ -352,6 +353,8 @@ where
|
||||||
for &pos in &rm_pre_cutoff {
|
for &pos in &rm_pre_cutoff {
|
||||||
self.pruned_nodes.add(pos);
|
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(
|
write_vec(
|
||||||
format!("{}/{}", self.data_dir, PMMR_PRUNED_FILE),
|
format!("{}/{}", self.data_dir, PMMR_PRUNED_FILE),
|
||||||
|
|
|
@ -19,8 +19,8 @@ extern crate time;
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
use core::ser::*;
|
|
||||||
use core::core::pmmr::{Backend, PMMR};
|
use core::core::pmmr::{Backend, PMMR};
|
||||||
|
use core::ser::*;
|
||||||
use store::types::prune_noop;
|
use store::types::prune_noop;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -566,6 +566,78 @@ fn pmmr_compact_horizon() {
|
||||||
teardown(data_dir);
|
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>) {
|
fn setup(tag: &str) -> (String, Vec<TestElem>) {
|
||||||
let _ = env_logger::init();
|
let _ = env_logger::init();
|
||||||
let t = time::get_time();
|
let t = time::get_time();
|
||||||
|
|
Loading…
Reference in a new issue