From e1c8dc5a3a8b556fabaea8e4db77656763d72ceb Mon Sep 17 00:00:00 2001 From: Gary Yu Date: Thu, 20 Sep 2018 07:29:24 +0800 Subject: [PATCH] fix: reset sync_head to header_head on initial transition to HeaderSync (#1531) * fix for bug #1524, reset sync_head to header_head on initial transition to HeaderSync. * using @antiochp fix solution in #1539 --- chain/src/chain.rs | 8 ++++++++ chain/src/pipe.rs | 10 ++++++++-- servers/src/grin/sync.rs | 34 +++++++++++++++++++++++++--------- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/chain/src/chain.rs b/chain/src/chain.rs index d64e66984..835938a7a 100644 --- a/chain/src/chain.rs +++ b/chain/src/chain.rs @@ -931,6 +931,14 @@ impl Chain { .block_exists(&h) .map_err(|e| ErrorKind::StoreErr(e, "chain block exists".to_owned()).into()) } + + /// reset sync_head to header_head + pub fn init_sync_head(&self, header_head: &Tip) -> Result<(), Error> { + let batch = self.store.batch()?; + batch.init_sync_head(header_head)?; + batch.commit()?; + Ok(()) + } } fn setup_head( diff --git a/chain/src/pipe.rs b/chain/src/pipe.rs index 7f2e1b9c5..bd144bf3d 100644 --- a/chain/src/pipe.rs +++ b/chain/src/pipe.rs @@ -215,9 +215,15 @@ pub fn sync_block_header( validate_header(&bh, sync_ctx)?; add_block_header(bh, batch)?; - // now update the header_head (if new header with most work) and the sync_head - // (always) + // Update header_head (but only if this header increases our total known work). + // i.e. Only if this header is now the head of the current "most work" chain. update_header_head(bh, header_ctx, batch)?; + + // Update sync_head regardless of total work. + // We may be syncing a long fork that will *eventually* increase the work + // and become the "most work" chain. + // header_head and sync_head will diverge in this situation until we switch to + // a single "most work" chain. update_sync_head(bh, sync_ctx, batch) } diff --git a/servers/src/grin/sync.rs b/servers/src/grin/sync.rs index 8d63feb10..9dedd1269 100644 --- a/servers/src/grin/sync.rs +++ b/servers/src/grin/sync.rs @@ -141,18 +141,34 @@ pub fn run_sync( // run the header sync every 10s if si.header_sync_due(&header_head) { - header_sync(peers.clone(), chain.clone(), &mut history_locators); - let status = sync_state.status(); - match status { - SyncStatus::TxHashsetDownload => (), - _ => { - sync_state.update(SyncStatus::HeaderSync { - current_height: header_head.height, - highest_height: si.highest_height, - }); + let update_sync_state = match status { + SyncStatus::TxHashsetDownload => false, + SyncStatus::NoSync | SyncStatus::Initial => { + // Reset sync_head to header_head on transition to HeaderSync, + // but ONLY on initial transition to HeaderSync state. + let sync_head = chain.get_sync_head().unwrap(); + debug!( + LOGGER, + "sync: initial transition to HeaderSync. sync_head: {} at {}, reset to: {} at {}", + sync_head.hash(), + sync_head.height, + header_head.hash(), + header_head.height, + ); + chain.init_sync_head(&header_head).unwrap(); + history_locators.clear(); + true } + _ => true, }; + if update_sync_state { + sync_state.update(SyncStatus::HeaderSync { + current_height: header_head.height, + highest_height: si.highest_height, + }); + } + header_sync(peers.clone(), chain.clone(), &mut history_locators); } if fast_sync_enabled {