diff --git a/internal/p2p/peermanager.go b/internal/p2p/peermanager.go index eee4cb28c..450f854df 100644 --- a/internal/p2p/peermanager.go +++ b/internal/p2p/peermanager.go @@ -130,6 +130,10 @@ type PeerManagerOptions struct { // retry times, to avoid thundering herds. 0 disables jitter. RetryTimeJitter time.Duration + // Maximum number of times we will try to dial a peer before + // marking it inactive. + MaxFailedDialAttempts uint32 + // PeerScores sets fixed scores for specific peers. It is mainly used // for testing. A score of 0 is ignored. PeerScores map[types.NodeID]PeerScore @@ -542,6 +546,17 @@ func (m *PeerManager) DialFailed(ctx context.Context, address NodeAddress) error addressInfo.LastDialFailure = time.Now().UTC() addressInfo.DialFailures++ + + var totalDialFailures uint32 + for _, addr := range peer.AddressInfo { + totalDialFailures += addr.DialFailures + } + + if m.options.MaxFailedDialAttempts > 0 && totalDialFailures > m.options.MaxFailedDialAttempts { + peer.Inactive = true + m.metrics.PeersInactivated.Add(1) + } + if err := m.store.Set(peer); err != nil { return err } diff --git a/node/setup.go b/node/setup.go index 60f50b4f9..4d1ee503d 100644 --- a/node/setup.go +++ b/node/setup.go @@ -230,6 +230,7 @@ func createPeerManager( SelfAddress: selfAddr, MaxConnected: maxConns, MaxConnectedUpgrade: maxUpgradeConns, + MaxFailedDialAttempts: 1024, MaxPeers: maxUpgradeConns + 2*maxConns, MinRetryTime: 250 * time.Millisecond, MaxRetryTime: 30 * time.Minute,