From 9ac4143bc9ac313161d706db2530a072c90eb5f0 Mon Sep 17 00:00:00 2001 From: Daogang Tang Date: Mon, 13 May 2019 23:10:31 +0800 Subject: [PATCH] fix: try to fix issue #2585 by adding block cleanup from db directly. (#2815) * fix: try to fix issue #2585 by adding block cleanup from db directly. Signed-off-by: Mike Tang * use another effective algorithm to do old block and short-lived block cleaup. Signed-off-by: Mike Tang * 1. rename iter_lived_blocks to blocks_iter; 2. comments and iterator calling optimiztions. Signed-off-by: Mike Tang * Fix locking bug when calling is_on_current_chain() in batch.blocks_iter just by removing it. Because "we want to delete block older (i.e. lower height) than tail.height". Signed-off-by: Mike Tang --- chain/src/chain.rs | 34 +++++++--------------------------- chain/src/store.rs | 9 ++++++++- 2 files changed, 15 insertions(+), 28 deletions(-) diff --git a/chain/src/chain.rs b/chain/src/chain.rs index c0ec8e4331..56b6a52bd2 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -1026,38 +1026,18 @@ impl Chain { } let mut count = 0; - let tail_hash = txhashset.get_header_hash_by_height(head.height - horizon)?; let tail = batch.get_block_header(&tail_hash)?; - let current_hash = txhashset.get_header_hash_by_height(head.height - horizon - 1)?; - let mut current = batch.get_block_header(¤t_hash)?; - - loop { - // Go to the store directly so we can handle NotFoundErr robustly. - match self.store.get_block(¤t.hash()) { - Ok(b) => { - batch.delete_block(&b.hash())?; - count += 1; - } - Err(NotFoundErr(_)) => { - break; - } - Err(e) => { - return Err( - ErrorKind::StoreErr(e, "retrieving block to compact".to_owned()).into(), - ); - } - } - if current.height <= 1 { - break; - } - match batch.get_previous_header(¤t) { - Ok(h) => current = h, - Err(NotFoundErr(_)) => break, - Err(e) => return Err(From::from(e)), + // Remove old blocks (including short lived fork blocks) which height < tail.height + // here b is a block + for (_, b) in batch.blocks_iter()? { + if b.header.height < tail.height { + let _ = batch.delete_block(&b.hash()); + count += 1; } } + batch.save_body_tail(&Tip::from_header(&tail))?; debug!( diff --git a/chain/src/store.rs b/chain/src/store.rs index fe75bbfd5f..58c5b72162 100644 --- a/chain/src/store.rs +++ b/chain/src/store.rs @@ -22,7 +22,7 @@ use crate::types::Tip; use crate::util::secp::pedersen::Commitment; use croaring::Bitmap; use grin_store as store; -use grin_store::{option_to_not_found, to_key, Error}; +use grin_store::{option_to_not_found, to_key, Error, SerIterator}; use std::sync::Arc; const STORE_SUBPATH: &'static str = "chain"; @@ -378,6 +378,13 @@ impl<'a> Batch<'a> { db: self.db.child()?, }) } + + /// An iterator to all block in db + pub fn blocks_iter(&self) -> Result, Error> { + let key = to_key(BLOCK_PREFIX, &mut "".to_string().into_bytes()); + self.db.iter(&key) + } + } /// An iterator on blocks, from latest to earliest, specialized to return