From a015d8231ecc77d1fb27b1923f4cf9e55acb2aaf Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Mon, 15 Apr 2019 20:34:46 -0700 Subject: [PATCH] netsync/manager: split out handlePeerDone helpers Preemptively splits out portions of the handlePeerDone method so that they can be used in the stall detection logic added in the next commit. --- netsync/manager.go | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/netsync/manager.go b/netsync/manager.go index 8444c898..37c26707 100644 --- a/netsync/manager.go +++ b/netsync/manager.go @@ -418,6 +418,19 @@ func (sm *SyncManager) handleDonePeerMsg(peer *peerpkg.Peer) { log.Infof("Lost peer %s", peer) + sm.clearRequestedState(state) + + if peer == sm.syncPeer { + // Update the sync peer. The server has already disconnected the + // peer before signaling to the sync manager. + sm.updateSyncPeer(false) + } +} + +// clearRequestedState wipes all expected transactions and blocks from the sync +// manager's requested maps that were requested under a peer's sync state, This +// allows them to be rerequested by a subsequent sync peer. +func (sm *SyncManager) clearRequestedState(state *peerSyncState) { // Remove requested transactions from the global map so that they will // be fetched from elsewhere next time we get an inv. for txHash := range state.requestedTxns { @@ -431,18 +444,29 @@ func (sm *SyncManager) handleDonePeerMsg(peer *peerpkg.Peer) { for blockHash := range state.requestedBlocks { delete(sm.requestedBlocks, blockHash) } +} - // Attempt to find a new peer to sync from if the quitting peer is the - // sync peer. Also, reset the headers-first state if in headers-first - // mode so - if sm.syncPeer == peer { - sm.syncPeer = nil - if sm.headersFirstMode { - best := sm.chain.BestSnapshot() - sm.resetHeaderState(&best.Hash, best.Height) - } - sm.startSync() +// updateSyncPeer choose a new sync peer to replace the current one. If +// dcSyncPeer is true, this method will also disconnect the current sync peer. +// If we are in header first mode, any header state related to prefetching is +// also reset in preparation for the next sync peer. +func (sm *SyncManager) updateSyncPeer(dcSyncPeer bool) { + log.Infof("Updating sync peer, no progress since: %v", + time.Since(sm.lastProgressTime)) + + // First, disconnect the current sync peer if requested. + if dcSyncPeer { + sm.syncPeer.Disconnect() } + + // Reset any header state before we choose our next active sync peer. + if sm.headersFirstMode { + best := sm.chain.BestSnapshot() + sm.resetHeaderState(&best.Hash, best.Height) + } + + sm.syncPeer = nil + sm.startSync() } // handleTxMsg handles transaction messages from all peers.