From d0414768195807044fa8614b07f4e0035fd5f9e1 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Tue, 2 Jul 2019 21:19:58 +0400 Subject: [PATCH] p2p: dial addrs which came from seed instead of calling ensurePeers (#3762) Calling ensurePeers outside of ensurePeersRoutine can lead to nodes disconnecting from us due to "sent next PEX request too soon" error. Solution is to just dial addrs we got from src instead of calling ensurePeers. Refs #2093 Fixes #3338 --- CHANGELOG_PENDING.md | 2 ++ p2p/pex/pex_reactor.go | 29 ++++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 9c94c55e7..fa81d9bbb 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -31,3 +31,5 @@ program](https://hackerone.com/tendermint). - [rpc] \#3700 Make possible to set absolute paths for TLS cert and key (@climber73) ### BUG FIXES: +- [p2p] \#3338 Prevent "sent next PEX request too soon" errors by not calling + ensurePeers outside of ensurePeersRoutine diff --git a/p2p/pex/pex_reactor.go b/p2p/pex/pex_reactor.go index e77fa8eaa..20862d323 100644 --- a/p2p/pex/pex_reactor.go +++ b/p2p/pex/pex_reactor.go @@ -340,6 +340,15 @@ func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error { if err != nil { return err } + + srcIsSeed := false + for _, seedAddr := range r.seedAddrs { + if seedAddr.Equals(srcAddr) { + srcIsSeed = true + break + } + } + for _, netAddr := range addrs { // Validate netAddr. Disconnect from a peer if it sends us invalid data. if netAddr == nil { @@ -365,13 +374,23 @@ func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error { } // If this address came from a seed node, try to connect to it without - // waiting. - for _, seedAddr := range r.seedAddrs { - if seedAddr.Equals(srcAddr) { - r.ensurePeers() - } + // waiting (#2093) + if srcIsSeed { + r.Logger.Info("Will dial address, which came from seed", "addr", netAddr, "seed", srcAddr) + go func(addr *p2p.NetAddress) { + err := r.dialPeer(addr) + if err != nil { + switch err.(type) { + case errMaxAttemptsToDial, errTooEarlyToDial: + r.Logger.Debug(err.Error(), "addr", addr) + default: + r.Logger.Error(err.Error(), "addr", addr) + } + } + }(netAddr) } } + return nil }