mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
Fix for buffer-pruned positions in MMR store
The MMR storage has a buffer for all changes so they can either be discarded without side effects or committed to disk. Pruning can also happen in the buffer if an input directly spends an output in a block (not likely), or a fork has an input spending a previous output within it. When the buffer gets flushed to storage, the pruned element was just skipped, causing an offset within the underlying storage and a shorter file than expected. This fix writes zeroes instead, so the size is consistent. Note that the zeroes will be removed with all other pruned elements on next compaction. Fixes #444
This commit is contained in:
parent
001fd3789c
commit
6ba22e71c8
1 changed files with 16 additions and 9 deletions
|
@ -394,18 +394,25 @@ where
|
||||||
/// data has been successfully written to disk.
|
/// data has been successfully written to disk.
|
||||||
pub fn sync(&mut self) -> io::Result<()> {
|
pub fn sync(&mut self) -> io::Result<()> {
|
||||||
// truncating the storage file if a rewind occurred
|
// truncating the storage file if a rewind occurred
|
||||||
|
let record_len = 32 + T::sum_len() as u64;
|
||||||
if let Some((pos, _, _)) = self.rewind {
|
if let Some((pos, _, _)) = self.rewind {
|
||||||
let record_len = 32 + T::sum_len() as u64;
|
|
||||||
self.hashsum_file.truncate(pos * record_len)?;
|
self.hashsum_file.truncate(pos * record_len)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for elem in &self.buffer.elems {
|
for elem in &self.buffer.elems {
|
||||||
if let Some(ref hs) = *elem {
|
let res = if let Some(ref hs) = *elem {
|
||||||
if let Err(e) = self.hashsum_file.append(&ser::ser_vec(&hs).unwrap()[..]) {
|
self.hashsum_file.append(&ser::ser_vec(&hs).unwrap()[..])
|
||||||
return Err(io::Error::new(
|
} else {
|
||||||
io::ErrorKind::Interrupted,
|
// the element has alredy been pruned in the buffer, we just insert
|
||||||
format!("Could not write to log storage, disk full? {:?}", e),
|
// zeros until compaction to avoid wrong hashum store offsets
|
||||||
));
|
self.hashsum_file.append(&vec![0; record_len as usize])
|
||||||
}
|
};
|
||||||
|
|
||||||
|
if let Err(e) = res {
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::Interrupted,
|
||||||
|
format!("Could not write to log storage, disk full? {:?}", e),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,7 +429,7 @@ where
|
||||||
if let Some((_, _, bi)) = self.rewind {
|
if let Some((_, _, bi)) = self.rewind {
|
||||||
self.buffer_index = bi;
|
self.buffer_index = bi;
|
||||||
}
|
}
|
||||||
self.buffer = VecBackend::new();
|
self.buffer.clear();
|
||||||
self.remove_log.discard();
|
self.remove_log.discard();
|
||||||
self.rewind = None;
|
self.rewind = None;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue