diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 70b361d26..08f53c6e0 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -23,6 +23,7 @@ Special thanks to external contributors on this release: - P2P Protocol - [p2p] \#7035 Remove legacy P2P routing implementation and associated configuration options. (@tychoish) + - [p2p] \#7265 Peer manager reduces peer score for each failed dial attempts for peers that have not successfully dialed. (@tychoish) - Go API diff --git a/internal/p2p/peermanager.go b/internal/p2p/peermanager.go index 7ccc0d59c..8c37cc1ff 100644 --- a/internal/p2p/peermanager.go +++ b/internal/p2p/peermanager.go @@ -532,6 +532,7 @@ func (m *PeerManager) DialFailed(address NodeAddress) error { if !ok { return nil // Assume the address has been removed, ignore. } + addressInfo.LastDialFailure = time.Now().UTC() addressInfo.DialFailures++ if err := m.store.Set(peer); err != nil { @@ -602,6 +603,7 @@ func (m *PeerManager) Dialed(address NodeAddress) error { addressInfo.LastDialSuccess = now // If not found, assume address has been removed. } + if err := m.store.Set(peer); err != nil { return err } @@ -660,6 +662,11 @@ func (m *PeerManager) Accepted(peerID types.NodeID) error { peer = m.newPeerInfo(peerID) } + // reset this to avoid penalizing peers for their past transgressions + for _, addr := range peer.AddressInfo { + addr.DialFailures = 0 + } + // If all connections slots are full, but we allow upgrades (and we checked // above that we have upgrade capacity), then we can look for a lower-scored // peer to replace and if found accept the connection anyway and evict it. @@ -1287,15 +1294,23 @@ func (p *peerInfo) Score() PeerScore { return PeerScorePersistent } - if p.MutableScore <= 0 { + score := p.MutableScore + + for _, addr := range p.AddressInfo { + // DialFailures is reset when dials succeed, so this + // is either the number of dial failures or 0. + score -= int64(addr.DialFailures) + } + + if score <= 0 { return 0 } - if p.MutableScore >= math.MaxUint8 { + if score >= math.MaxUint8 { return PeerScore(math.MaxUint8) } - return PeerScore(p.MutableScore) + return PeerScore(score) } // Validate validates the peer info.