Skip to content

Commit 537c56e

Browse files
committed
add idletimeout for http
1 parent eb211dd commit 537c56e

1 file changed

Lines changed: 30 additions & 1 deletion

File tree

relayer/chains/evm/client.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"context"
55
"fmt"
66
"math/big"
7+
"net/http"
8+
"strings"
79
"sync"
810
"time"
911

@@ -12,6 +14,7 @@ import (
1214
"github.com/ethereum/go-ethereum/common/hexutil"
1315
gethtypes "github.com/ethereum/go-ethereum/core/types"
1416
"github.com/ethereum/go-ethereum/ethclient"
17+
"github.com/ethereum/go-ethereum/rpc"
1518

1619
"github.com/bandprotocol/falcon/relayer/alert"
1720
"github.com/bandprotocol/falcon/relayer/chains"
@@ -59,6 +62,32 @@ type client struct {
5962
alert alert.Alert
6063
}
6164

65+
// idleConnTimeout is intentionally shorter than the typical load-balancer idle
66+
// timeout (e.g. AWS ALB default is 60 s) so Go closes idle keep-alive
67+
// connections before the LB does, preventing "connection reset by peer" errors
68+
// caused by the LB sending a TCP RST on a stale connection that Go's transport
69+
// would otherwise attempt to reuse.
70+
const idleConnTimeout = 30 * time.Second
71+
72+
// dialEVMEndpoint connects to an EVM-compatible RPC endpoint.
73+
// For HTTP/HTTPS endpoints it injects a custom transport with a short
74+
// IdleConnTimeout to avoid stale-connection resets from load balancers.
75+
// For WebSocket endpoints it falls back to the standard ethclient dialer.
76+
func dialEVMEndpoint(ctx context.Context, endpoint string) (*ethclient.Client, error) {
77+
lower := strings.ToLower(endpoint)
78+
if strings.HasPrefix(lower, "http://") || strings.HasPrefix(lower, "https://") {
79+
transport := &http.Transport{
80+
IdleConnTimeout: idleConnTimeout,
81+
}
82+
rpcCli, err := rpc.DialOptions(ctx, endpoint, rpc.WithHTTPClient(&http.Client{Transport: transport}))
83+
if err != nil {
84+
return nil, err
85+
}
86+
return ethclient.NewClient(rpcCli), nil
87+
}
88+
return ethclient.DialContext(ctx, endpoint)
89+
}
90+
6291
// NewClient creates a new EVM client from config file and load keys.
6392
func NewClient(chainName string, cfg *EVMChainProviderConfig, log logger.Logger, alert alert.Alert) *client {
6493
return &client{
@@ -84,7 +113,7 @@ func (c *client) Connect(ctx context.Context) error {
84113
wg.Add(1)
85114
go func(endpoint string) {
86115
defer wg.Done()
87-
client, err := ethclient.Dial(endpoint)
116+
client, err := dialEVMEndpoint(ctx, endpoint)
88117
if err != nil {
89118
c.Log.Warn(
90119
"Failed to connect to EVM chain",

0 commit comments

Comments
 (0)