code: func (b *blockManager) handleDonePeerMsg(peers *list.List, sp *ServerPeer) {
  	// Remove the peer from the list of candidate peers.
  	for e := peers.Front(); e != nil; e = e.Next() {
  		if e.Value == sp {
  			peers.Remove(e)
  			break
  		}
  	}
  
  	log.Infof("Lost peer %s", sp)
  
  	// Attempt to find a new peer to sync from if the quitting peer is the
  	// sync peer.  Also, reset the header state.
  	if b.SyncPeer() != nil && b.SyncPeer() == sp {
  		b.syncPeerMutex.Lock()
  		b.syncPeer = nil
  		b.syncPeerMutex.Unlock()
  		header, height, err := b.server.BlockHeaders.ChainTip()
  		if err != nil {
  			return
  		}
  		b.headerList.ResetHeaderState(headerlist.Node{
  			Header: *header,
  			Height: int32(height),
  		})
  		b.startSync(peers)
  	}
  }
docs: // handleDonePeerMsg deals with peers that have signalled they are done.  It
  // removes the peer as a candidate for syncing and in the case where it was the
  // current sync peer, attempts to select a new best peer to sync from.  It is
  // invoked from the syncHandler goroutine.