run chain compaction on startup (#2127)

* run chain compaction on startup
* make sure we can compact an empty chain
This commit is contained in:
Antioch Peverell 2018-12-11 16:52:55 +00:00 committed by Ignotus Peverell
parent 16641fe149
commit c5e771cbf0

View file

@ -167,6 +167,7 @@ impl Chain {
archive_mode: bool, archive_mode: bool,
stop_state: Arc<Mutex<StopState>>, stop_state: Arc<Mutex<StopState>>,
) -> Result<Chain, Error> { ) -> Result<Chain, Error> {
let chain = {
// Note: We take a lock on the stop_state here and do not release it until // Note: We take a lock on the stop_state here and do not release it until
// we have finished chain initialization. // we have finished chain initialization.
let stop_state_local = stop_state.clone(); let stop_state_local = stop_state.clone();
@ -183,7 +184,7 @@ impl Chain {
setup_head(&genesis, &store, &mut txhashset)?; setup_head(&genesis, &store, &mut txhashset)?;
Chain::log_heads(&store)?; Chain::log_heads(&store)?;
Ok(Chain { Chain {
db_root, db_root,
store, store,
adapter, adapter,
@ -194,7 +195,16 @@ impl Chain {
archive_mode, archive_mode,
stop_state, stop_state,
genesis: genesis.header.clone(), genesis: genesis.header.clone(),
}) }
};
// Run chain compaction. Laptops and other intermittent nodes
// may not run long enough to trigger daily compaction.
// So run it explicitly here on startup (its fast enough to do so).
// Note: we release the stop_lock from above as compact also requires a lock.
chain.compact()?;
Ok(chain)
} }
fn log_heads(store: &store::ChainStore) -> Result<(), Error> { fn log_heads(store: &store::ChainStore) -> Result<(), Error> {
@ -895,10 +905,10 @@ impl Chain {
} }
fn compact_txhashset(&self) -> Result<(), Error> { fn compact_txhashset(&self) -> Result<(), Error> {
debug!("Starting blockchain compaction."); debug!("Starting txhashset compaction...");
{ {
// Note: We take a lock on the stop_state here and do not release it until // Note: We take a lock on the stop_state here and do not release it until
// we have finished processing this compaction operation. // we have finished processing this chain compaction operation.
let stop_lock = self.stop_state.lock(); let stop_lock = self.stop_state.lock();
if stop_lock.is_stopped() { if stop_lock.is_stopped() {
return Err(ErrorKind::Stopped.into()); return Err(ErrorKind::Stopped.into());
@ -906,16 +916,8 @@ impl Chain {
let mut txhashset = self.txhashset.write(); let mut txhashset = self.txhashset.write();
txhashset.compact()?; txhashset.compact()?;
txhashset::extending_readonly(&mut txhashset, |extension| {
extension.dump_output_pmmr();
Ok(())
})?;
} }
debug!("... finished txhashset compaction.");
// Now check we can still successfully validate the chain state after
// compacting, shouldn't be necessary once all of this is well-oiled
debug!("Validating state after compaction.");
self.validate(true)?;
Ok(()) Ok(())
} }
@ -929,7 +931,11 @@ impl Chain {
let horizon = global::cut_through_horizon() as u64; let horizon = global::cut_through_horizon() as u64;
let head = self.head()?; let head = self.head()?;
let tail = self.tail()?;
let tail = match self.tail() {
Ok(tail) => tail,
Err(_) => Tip::from_header(&self.genesis),
};
let cutoff = head.height.saturating_sub(horizon); let cutoff = head.height.saturating_sub(horizon);