Back up the removed log before truncating in memory

Without a backup, the in-memory data structure stays truncated
even if the rewind is abandoned. Also add some logging on our
most problematic block in case it still is problematic.
This commit is contained in:
Ignotus Peverell 2017-11-28 18:43:02 -05:00 committed by Simon B
parent 6b48e7840d
commit b893a6c8ee
2 changed files with 26 additions and 1 deletions

View file

@ -239,9 +239,13 @@ impl<'a> Extension<'a> {
pub fn apply_block(&mut self, b: &Block) -> Result<(), Error> {
// doing inputs first guarantees an input can't spend an output in the
// same block, enforcing block cut-through
// same block, enforcing block cut-through
for input in &b.inputs {
let pos_res = self.commit_index.get_output_pos(&input.commitment());
if b.hash().to_string() == "f697a877" {
debug!(LOGGER, "input pos: {:?}, commit: {} {:?}",
pos_res, input.commitment().hash(), input.commitment());
}
if let Ok(pos) = pos_res {
match self.output_pmmr.prune(pos, b.header.height as u32) {
Ok(true) => {

View file

@ -163,6 +163,8 @@ struct RemoveLog {
removed: Vec<(u64, u32)>,
// Holds positions temporarily until flush is called.
removed_tmp: Vec<(u64, u32)>,
// Holds truncated removed temporarily until discarded or committed
removed_bak: Vec<(u64, u32)>,
}
impl RemoveLog {
@ -174,6 +176,7 @@ impl RemoveLog {
path: path,
removed: removed,
removed_tmp: vec![],
removed_bak: vec![],
})
}
@ -181,10 +184,14 @@ impl RemoveLog {
fn truncate(&mut self, last_offs: u32) -> io::Result<()> {
// simplifying assumption: we always remove older than what's in tmp
self.removed_tmp = vec![];
// DEBUG
let _ = self.flush_truncate(last_offs);
if last_offs == 0 {
self.removed = vec![];
} else {
// backing it up before truncating
self.removed_bak = self.removed.clone();
self.removed = self.removed
.iter()
.filter(|&&(_, idx)| idx < last_offs)
@ -194,6 +201,15 @@ impl RemoveLog {
Ok(())
}
// DEBUG: saves the remove log to the side before each truncate
fn flush_truncate(&mut self, last_offs: u32) -> io::Result<()> {
let mut file = File::create(format!("{}.{}", self.path.clone(), last_offs))?;
for elmt in &self.removed {
file.write_all(&ser::ser_vec(&elmt).unwrap()[..])?;
}
file.sync_data()
}
/// Append a set of new positions to the remove log. Both adds those
/// positions the ordered in-memory set and to the file.
fn append(&mut self, elmts: Vec<u64>, index: u32) -> io::Result<()> {
@ -223,11 +239,16 @@ impl RemoveLog {
file.write_all(&ser::ser_vec(&elmt).unwrap()[..])?;
}
self.removed_tmp = vec![];
self.removed_bak = vec![];
file.sync_data()
}
/// Discard pending changes
fn discard(&mut self) {
if self.removed_bak.len() > 0 {
self.removed = self.removed_bak.clone();
self.removed_bak = vec![];
}
self.removed_tmp = vec![];
}