From e2775ba0e3dccad48831b0a136115cf4bfce37b2 Mon Sep 17 00:00:00 2001 From: Roman Useinov Date: Wed, 17 Jul 2019 06:37:27 +0200 Subject: [PATCH 1/2] abci/server: recover from app panics in socket server (#3809) fixes #3800 --- CHANGELOG_PENDING.md | 1 + abci/server/socket_server.go | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index f211a27f3..5dbc1ddb7 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -17,5 +17,6 @@ ### FEATURES: ### IMPROVEMENTS: +- [abci] \#3809 Recover from application panics in `server/socket_server.go` to allow socket cleanup (@ruseinov) ### BUG FIXES: diff --git a/abci/server/socket_server.go b/abci/server/socket_server.go index 4b92f04cf..38649ac7f 100644 --- a/abci/server/socket_server.go +++ b/abci/server/socket_server.go @@ -146,6 +146,16 @@ func (s *SocketServer) waitForClose(closeConn chan error, connID int) { func (s *SocketServer) handleRequests(closeConn chan error, conn net.Conn, responses chan<- *types.Response) { var count int var bufReader = bufio.NewReader(conn) + + defer func() { + // make sure to recover from any app-related panics to allow proper socket cleanup + r := recover() + if r != nil { + closeConn <- fmt.Errorf("recovered from panic: %v", r) + s.appMtx.Unlock() + } + }() + for { var req = &types.Request{} @@ -154,7 +164,7 @@ func (s *SocketServer) handleRequests(closeConn chan error, conn net.Conn, respo if err == io.EOF { closeConn <- err } else { - closeConn <- fmt.Errorf("Error reading message: %v", err.Error()) + closeConn <- fmt.Errorf("error reading message: %v", err) } return } From 7924c7681528d7f95229d72c154c8cd35543577d Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Tue, 2 Jul 2019 21:19:58 +0400 Subject: [PATCH 2/2] 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 5dbc1ddb7..d913443a2 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -20,3 +20,5 @@ - [abci] \#3809 Recover from application panics in `server/socket_server.go` to allow socket cleanup (@ruseinov) ### 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 eabbc4d61..e0d7c0d72 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 }