diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index f211a27f3..d913443a2 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -17,5 +17,8 @@ ### FEATURES: ### IMPROVEMENTS: +- [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/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 } 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 }