Rm log rewind on startup (#760)

* add rewind to block height to rm_log on startup

* add rewind to block height to rm_log on startup

* flush remove log
This commit is contained in:
Yeastplume 2018-03-09 17:17:48 +00:00 committed by GitHub
parent 23ac36a834
commit 5cf780ab98
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 8 deletions

View file

@ -157,7 +157,15 @@ impl Chain {
// check if we have a head in store, otherwise the genesis block is it
let head = store.head();
let txhashset_md = match head {
Ok(h) => Some(store.get_block_pmmr_file_metadata(&h.last_block_h)?),
Ok(h) => {
// Add the height to the metadata for the use of the rewind log, as this isn't
// stored
let mut ts = store.get_block_pmmr_file_metadata(&h.last_block_h)?;
ts.output_file_md.block_height = h.height;
ts.rproof_file_md.block_height = h.height;
ts.kernel_file_md.block_height = h.height;
Some(ts)
}
Err(NotFoundErr) => None,
Err(e) => return Err(Error::StoreErr(e, "chain init load head".to_owned())),
};

View file

@ -35,6 +35,8 @@ pub const RM_LOG_MAX_NODES: usize = 10000;
/// stored
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct PMMRFileMetadata {
/// The block height represented by these indices in the file
pub block_height: u64,
/// last written index of the hash file
pub last_hash_file_pos: u64,
/// last written index of the data file
@ -43,6 +45,7 @@ pub struct PMMRFileMetadata {
impl Writeable for PMMRFileMetadata {
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
writer.write_u64(self.block_height)?;
writer.write_u64(self.last_hash_file_pos)?;
writer.write_u64(self.last_data_file_pos)?;
Ok(())
@ -52,6 +55,7 @@ impl Writeable for PMMRFileMetadata {
impl Readable for PMMRFileMetadata {
fn read(reader: &mut Reader) -> Result<PMMRFileMetadata, ser::Error> {
Ok(PMMRFileMetadata {
block_height: reader.read_u64()?,
last_hash_file_pos: reader.read_u64()?,
last_data_file_pos: reader.read_u64()?,
})
@ -62,6 +66,7 @@ impl PMMRFileMetadata {
/// Return fields with all positions = 0
pub fn empty() -> PMMRFileMetadata {
PMMRFileMetadata {
block_height: 0,
last_hash_file_pos: 0,
last_data_file_pos: 0,
}
@ -211,13 +216,17 @@ where
/// Instantiates a new PMMR backend that will use the provided directly to
/// store its files.
pub fn new(data_dir: String, file_md: Option<PMMRFileMetadata>) -> io::Result<PMMRBackend<T>> {
let (hash_to_pos, data_to_pos) = match file_md {
Some(m) => (m.last_hash_file_pos, m.last_data_file_pos),
None => (0, 0),
let (height, hash_to_pos, data_to_pos) = match file_md {
Some(m) => (
m.block_height as u32,
m.last_hash_file_pos,
m.last_data_file_pos,
),
None => (0, 0, 0),
};
let hash_file =
AppendOnlyFile::open(format!("{}/{}", data_dir, PMMR_HASH_FILE), hash_to_pos)?;
let rm_log = RemoveLog::open(format!("{}/{}", data_dir, PMMR_RM_LOG_FILE))?;
let rm_log = RemoveLog::open(format!("{}/{}", data_dir, PMMR_RM_LOG_FILE), height)?;
let prune_list = read_ordered_vec(format!("{}/{}", data_dir, PMMR_PRUNED_FILE), 8)?;
let data_file =
AppendOnlyFile::open(format!("{}/{}", data_dir, PMMR_DATA_FILE), data_to_pos)?;
@ -290,6 +299,7 @@ where
/// Return last written buffer positions for the hash file and the data file
pub fn last_file_positions(&self) -> PMMRFileMetadata {
PMMRFileMetadata {
block_height: 0,
last_hash_file_pos: self.hash_file.last_buffer_pos() as u64,
last_data_file_pos: self.data_file.last_buffer_pos() as u64,
}

View file

@ -28,6 +28,7 @@ use libc::{ftruncate as ftruncate64, off_t as off64_t};
use core::ser;
/// Noop
pub fn prune_noop(_pruned_data: &[u8]) {}
/// Wrapper for a file that can be read at any position (random read) but for
@ -229,14 +230,19 @@ pub struct RemoveLog {
impl RemoveLog {
/// Open the remove log file. The content of the file will be read in memory
/// for fast checking.
pub fn open(path: String) -> io::Result<RemoveLog> {
pub fn open(path: String, rewind_to_index: u32) -> io::Result<RemoveLog> {
let removed = read_ordered_vec(path.clone(), 12)?;
Ok(RemoveLog {
let mut rl = RemoveLog {
path: path,
removed: removed,
removed_tmp: vec![],
removed_bak: vec![],
})
};
if rewind_to_index > 0 {
rl.rewind(rewind_to_index)?;
rl.flush()?;
}
Ok(rl)
}
/// Truncate and empties the remove log.