diff --git a/chain/src/chain.rs b/chain/src/chain.rs index 55e2da9af..93e71929d 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -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())), }; diff --git a/store/src/pmmr.rs b/store/src/pmmr.rs index 373750395..4aa672ffd 100644 --- a/store/src/pmmr.rs +++ b/store/src/pmmr.rs @@ -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(&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 { 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) -> io::Result> { - 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, } diff --git a/store/src/types.rs b/store/src/types.rs index 74b2a2c32..8419353d7 100644 --- a/store/src/types.rs +++ b/store/src/types.rs @@ -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 { + pub fn open(path: String, rewind_to_index: u32) -> io::Result { 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.