From 7b6f06917e640eaf1a74ad5e9e8408fbcab5546e Mon Sep 17 00:00:00 2001 From: norwnd Date: Wed, 16 Oct 2024 00:50:26 +0300 Subject: [PATCH 1/2] spv: delay reconnect attempts --- spv/sync.go | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/spv/sync.go b/spv/sync.go index 1cf9a57c3..e9b7221eb 100644 --- a/spv/sync.go +++ b/spv/sync.go @@ -480,7 +480,9 @@ var errBreaksMinVersionTarget = errors.New("peer uses too low version to satisif // connectAndRunPeer connects to and runs the syncing process with the specified // peer. It blocks until the peer disconnects and logs any errors. -func (s *Syncer) connectAndRunPeer(ctx context.Context, raddr string, persistent bool) { +// connectAndRunPeer returns backoff flag indicating whether it is advised to +// wait a bit before attempting to connect to this peer again. +func (s *Syncer) connectAndRunPeer(ctx context.Context, raddr string, persistent bool) (backoff bool) { // Attempt connection to peer. rp, err := s.lp.ConnectOutbound(ctx, raddr, reqSvcs) if err != nil { @@ -491,6 +493,7 @@ func (s *Syncer) connectAndRunPeer(ctx context.Context, raddr string, persistent s.remotesMu.Unlock() if !errors.Is(err, context.Canceled) { log.Warnf("Peering attempt failed: %v", err) + backoff = true } return } @@ -535,6 +538,7 @@ func (s *Syncer) connectAndRunPeer(ctx context.Context, raddr string, persistent log.Infof("Lost peer %v", raddr) } rp.Disconnect(err) + backoff = true return } @@ -545,6 +549,7 @@ func (s *Syncer) connectAndRunPeer(ctx context.Context, raddr string, persistent } else { log.Infof("Lost peer %v", raddr) } + return } func (s *Syncer) breaksMinVersionTarget(rp *p2p.RemotePeer) bool { @@ -569,13 +574,17 @@ func (s *Syncer) breaksMinVersionTarget(rp *p2p.RemotePeer) bool { func (s *Syncer) connectToPersistent(ctx context.Context, raddr string) error { for { - s.connectAndRunPeer(ctx, raddr, true) - - // Retry persistent peer after 5 seconds. select { case <-ctx.Done(): return ctx.Err() - case <-time.After(5 * time.Second): + default: + } + + backoff := s.connectAndRunPeer(ctx, raddr, true) + if backoff { + // Delay next connect attempt to save resources and not overwhelm peers, + // it's unlikely to succeed anyway if we do retry immediately. + time.Sleep(5 * time.Second) } } } @@ -607,9 +616,14 @@ func (s *Syncer) connectToCandidates(ctx context.Context) error { wg.Add(1) go func() { + defer wg.Done() raddr := na.String() - s.connectAndRunPeer(ctx, raddr, false) - wg.Done() + backoff := s.connectAndRunPeer(ctx, raddr, false) + if backoff { + // Delay next connect attempt to save resources and not overwhelm peers, + // it's unlikely to succeed anyway if we do retry immediately. + time.Sleep(5 * time.Second) + } <-sem }() } From 91dff3439c05f1b9a9ec29e7044994565368b0f4 Mon Sep 17 00:00:00 2001 From: norwnd Date: Fri, 18 Oct 2024 21:47:58 +0300 Subject: [PATCH 2/2] dont back off when context canceled --- spv/sync.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spv/sync.go b/spv/sync.go index e9b7221eb..486f193a9 100644 --- a/spv/sync.go +++ b/spv/sync.go @@ -534,11 +534,11 @@ func (s *Syncer) connectAndRunPeer(ctx context.Context, raddr string, persistent if err != nil { if !errors.Is(err, context.Canceled) { log.Warnf("Unable to complete startup sync with peer %v: %v", raddr, err) + backoff = true } else { log.Infof("Lost peer %v", raddr) } rp.Disconnect(err) - backoff = true return }