diff --git a/netsync/blocklogger.go b/netsync/blocklogger.go index 31a6a4c509..eff4fa4755 100644 --- a/netsync/blocklogger.go +++ b/netsync/blocklogger.go @@ -82,3 +82,61 @@ func (b *blockProgressLogger) LogBlockHeight(block *btcutil.Block, chain *blockc func (b *blockProgressLogger) SetLastLogTime(time time.Time) { b.lastBlockLogTime = time } + +// peerLogger logs the progress of blocks downloaded from different peers during +// headers-first download. +type peerLogger struct { + lastPeerLogTime time.Time + peers map[string]int + + subsystemLogger btclog.Logger + sync.Mutex +} + +// newPeerLogger returns a new peerLogger with fields initialized. +func newPeerLogger(logger btclog.Logger) *peerLogger { + return &peerLogger{ + lastPeerLogTime: time.Now(), + subsystemLogger: logger, + peers: make(map[string]int), + } +} + +// LogPeers logs how many blocks have been received from which peers in the last +// 10 seconds. +func (p *peerLogger) LogPeers(peer string) { + p.Lock() + defer p.Unlock() + + count, found := p.peers[peer] + if found { + count++ + p.peers[peer] = count + } else { + p.peers[peer] = 1 + } + + now := time.Now() + duration := now.Sub(p.lastPeerLogTime) + if duration < time.Second*10 { + return + } + // Truncate the duration to 10s of milliseconds. + durationMillis := int64(duration / time.Millisecond) + tDuration := 10 * time.Millisecond * time.Duration(durationMillis/10) + + peerDownloadStr := "" + for peer, blockCount := range p.peers { + peerDownloadStr += fmt.Sprintf("%d blocks from %v, ", + blockCount, peer) + } + + p.subsystemLogger.Infof("Peer download stats in the last %s: %s", + tDuration, peerDownloadStr) + + // Reset fields. + p.lastPeerLogTime = now + for k := range p.peers { + delete(p.peers, k) + } +} diff --git a/netsync/manager.go b/netsync/manager.go index 5e0f396163..e3110e985d 100644 --- a/netsync/manager.go +++ b/netsync/manager.go @@ -236,6 +236,7 @@ type SyncManager struct { txMemPool *mempool.TxPool chainParams *chaincfg.Params progressLogger *blockProgressLogger + peerLogger *peerLogger msgChan chan interface{} wg sync.WaitGroup quit chan struct{} @@ -932,6 +933,10 @@ func (sm *SyncManager) handleBlockMsg(bmsg *blockMsg) { } } + if sm.headersFirstMode { + go sm.peerLogger.LogPeers(peer.Addr()) + } + // Since we may receive blocks out of order, attempt to find the next block // and any other descendent blocks that connect to it. processBlocks := make([]*blockMsg, 0, 1) @@ -1917,6 +1922,7 @@ func New(config *Config) (*SyncManager, error) { requestedBlocks: make(map[chainhash.Hash]struct{}), peerStates: make(map[*peerpkg.Peer]*peerSyncState), progressLogger: newBlockProgressLogger("Processed", log), + peerLogger: newPeerLogger(log), msgChan: make(chan interface{}, config.MaxPeers*3), headerList: list.New(), quit: make(chan struct{}),