From c12bd2f58eb0f83741c6b7f89b73da2a23147359 Mon Sep 17 00:00:00 2001 From: winged-pegasus <55340199+winged-pegasus@users.noreply.github.com> Date: Wed, 18 Feb 2026 18:08:26 -0900 Subject: [PATCH] add reconnect fallback if no peers are found with variable reconnect time (#511) Co-authored-by: Tyler Sturos <55340199+tjsturos@users.noreply.github.com> --- config/p2p.go | 5 +++++ node/p2p/blossomsub.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/config/p2p.go b/config/p2p.go index 41a5e67..3a3c722 100644 --- a/config/p2p.go +++ b/config/p2p.go @@ -18,6 +18,7 @@ const ( defaultPingTimeout = 5 * time.Second defaultPingPeriod = 30 * time.Second defaultPingAttempts = 3 + defaultPeerReconnectInterval = 60 * time.Second defaultStreamListenMultiaddr = "/ip4/0.0.0.0/tcp/8340" ) @@ -76,6 +77,7 @@ type P2PConfig struct { ValidateWorkers int `yaml:"validateWorkers"` SubscriptionQueueSize int `yaml:"subscriptionQueueSize"` PeerOutboundQueueSize int `yaml:"peerOutboundQueueSize"` + PeerReconnectCheckInterval time.Duration `yaml:"peerReconnectCheckInterval"` } // WithDefaults returns a copy of the P2PConfig with any missing fields set to @@ -220,5 +222,8 @@ func (c P2PConfig) WithDefaults() P2PConfig { if cpy.PeerOutboundQueueSize == 0 { cpy.PeerOutboundQueueSize = blossomsub.DefaultPeerOutboundQueueSize } + if cpy.PeerReconnectCheckInterval == 0 { + cpy.PeerReconnectCheckInterval = defaultPeerReconnectInterval + } return cpy } diff --git a/node/p2p/blossomsub.go b/node/p2p/blossomsub.go index fa8e52a..a1fcdfd 100644 --- a/node/p2p/blossomsub.go +++ b/node/p2p/blossomsub.go @@ -872,16 +872,45 @@ func (b *BlossomSub) background(ctx context.Context) { refreshScores := time.NewTicker(DecayInterval) defer refreshScores.Stop() + peerReconnectInterval := b.p2pConfig.PeerReconnectCheckInterval + peerReconnect := time.NewTicker(peerReconnectInterval) + defer peerReconnect.Stop() + for { select { case <-refreshScores.C: b.refreshScores() + case <-peerReconnect.C: + b.checkAndReconnectPeers(ctx) case <-ctx.Done(): return } } } +func (b *BlossomSub) checkAndReconnectPeers(ctx context.Context) { + peerCount := len(b.h.Network().Peers()) + if peerCount > 0 { + return + } + + b.logger.Warn( + "no peers connected, attempting to re-bootstrap and discover", + zap.Duration("check_interval", b.p2pConfig.PeerReconnectCheckInterval), + ) + + if err := b.DiscoverPeers(ctx); err != nil { + b.logger.Error("peer reconnect failed", zap.Error(err)) + } + + newCount := len(b.h.Network().Peers()) + if newCount > 0 { + b.logger.Info("peer reconnect succeeded", zap.Int("peers", newCount)) + } else { + b.logger.Warn("peer reconnect: still no peers found, will retry at next interval") + } +} + func (b *BlossomSub) refreshScores() { b.peerScoreMx.Lock()