From 5c8dcfd3c368b6451f6da09b19aa6a08e884ea80 Mon Sep 17 00:00:00 2001 From: Emmanuel T Odeke Date: Fri, 31 Jan 2025 22:05:09 +0200 Subject: [PATCH] fix(tm2/pkg/bft/node): make Node.startRPC not leak listeners on any error (#3640) Once Node.startRPC encounters an error, previously it was discarding all the created listeners and leaking them unclosed. This change fixes that using Go's named return values. Fixes #3639 --- tm2/pkg/bft/node/node.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tm2/pkg/bft/node/node.go b/tm2/pkg/bft/node/node.go index c1afb2996fa..08f1b3c58f9 100644 --- a/tm2/pkg/bft/node/node.go +++ b/tm2/pkg/bft/node/node.go @@ -713,7 +713,17 @@ func (n *Node) configureRPC() { rpccore.SetConfig(*n.config.RPC) } -func (n *Node) startRPC() ([]net.Listener, error) { +func (n *Node) startRPC() (listeners []net.Listener, err error) { + defer func() { + if err != nil { + // Close all the created listeners on any error, instead of + // leaking them: https://github.com/gnolang/gno/issues/3639 + for _, ln := range listeners { + ln.Close() + } + } + }() + listenAddrs := splitAndTrimEmpty(n.config.RPC.ListenAddress, ",", " ") config := rpcserver.DefaultConfig() @@ -729,8 +739,8 @@ func (n *Node) startRPC() ([]net.Listener, error) { // we may expose the rpc over both a unix and tcp socket var rebuildAddresses bool - listeners := make([]net.Listener, len(listenAddrs)) - for i, listenAddr := range listenAddrs { + listeners = make([]net.Listener, 0, len(listenAddrs)) + for _, listenAddr := range listenAddrs { mux := http.NewServeMux() rpcLogger := n.Logger.With("module", "rpc-server") wmLogger := rpcLogger.With("protocol", "websocket") @@ -782,7 +792,7 @@ func (n *Node) startRPC() ([]net.Listener, error) { ) } - listeners[i] = listener + listeners = append(listeners, listener) } if rebuildAddresses { n.config.RPC.ListenAddress = joinListenerAddresses(listeners)