Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Add support for MaxOpenConnections #1229

Merged
merged 8 commits into from
Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Ref: https://keepachangelog.com/en/1.0.0/

## Unreleased

### Improvements

* (rpc) [#1229](https://github.com/evmos/ethermint/pull/1229) Add support for configuring RPC `MaxOpenConnections`

### State Machine Breaking

* (deps) [\#1159](https://github.com/evmos/ethermint/pull/1159) Bump Geth version to `v1.10.19`.
Expand Down
2 changes: 1 addition & 1 deletion rpc/websockets.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ type websocketsServer struct {
logger log.Logger
}

func NewWebsocketsServer(clientCtx client.Context, logger log.Logger, tmWSClient *rpcclient.WSClient, cfg config.Config) WebsocketsServer {
func NewWebsocketsServer(clientCtx client.Context, logger log.Logger, tmWSClient *rpcclient.WSClient, cfg *config.Config) WebsocketsServer {
logger = logger.With("api", "websocket-server")
_, port, _ := net.SplitHostPort(cfg.JSONRPC.Address)

Expand Down
33 changes: 20 additions & 13 deletions server/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ const (
DefaultHTTPIdleTimeout = 120 * time.Second
// DefaultAllowUnprotectedTxs value is false
DefaultAllowUnprotectedTxs = false
// DefaultMaxOpenConnections represents the amount of open connections (unlimited = 0)
DefaultMaxOpenConnections = 0
)

var evmTracers = []string{"json", "markdown", "struct", "access_list"}
Expand Down Expand Up @@ -103,6 +105,9 @@ type JSONRPCConfig struct {
// AllowUnprotectedTxs restricts unprotected (non EIP155 signed) transactions to be submitted via
// the node's RPC when global parameter is disabled.
AllowUnprotectedTxs bool `mapstructure:"allow-unprotected-txs"`
// MaxOpenConnections sets the maximum number of simultaneous connections
// for the server listener.
MaxOpenConnections int `mapstructure:"max-open-connections"`
}

// TLSConfig defines the certificate and matching private key for the server.
Expand Down Expand Up @@ -202,6 +207,7 @@ func DefaultJSONRPCConfig() *JSONRPCConfig {
HTTPTimeout: DefaultHTTPTimeout,
HTTPIdleTimeout: DefaultHTTPIdleTimeout,
AllowUnprotectedTxs: DefaultAllowUnprotectedTxs,
MaxOpenConnections: DefaultMaxOpenConnections,
}
}

Expand Down Expand Up @@ -292,19 +298,20 @@ func GetConfig(v *viper.Viper) Config {
MaxTxGasWanted: v.GetUint64("evm.max-tx-gas-wanted"),
},
JSONRPC: JSONRPCConfig{
Enable: v.GetBool("json-rpc.enable"),
API: v.GetStringSlice("json-rpc.api"),
Address: v.GetString("json-rpc.address"),
WsAddress: v.GetString("json-rpc.ws-address"),
GasCap: v.GetUint64("json-rpc.gas-cap"),
FilterCap: v.GetInt32("json-rpc.filter-cap"),
FeeHistoryCap: v.GetInt32("json-rpc.feehistory-cap"),
TxFeeCap: v.GetFloat64("json-rpc.txfee-cap"),
EVMTimeout: v.GetDuration("json-rpc.evm-timeout"),
LogsCap: v.GetInt32("json-rpc.logs-cap"),
BlockRangeCap: v.GetInt32("json-rpc.block-range-cap"),
HTTPTimeout: v.GetDuration("json-rpc.http-timeout"),
HTTPIdleTimeout: v.GetDuration("json-rpc.http-idle-timeout"),
Enable: v.GetBool("json-rpc.enable"),
API: v.GetStringSlice("json-rpc.api"),
Address: v.GetString("json-rpc.address"),
WsAddress: v.GetString("json-rpc.ws-address"),
GasCap: v.GetUint64("json-rpc.gas-cap"),
FilterCap: v.GetInt32("json-rpc.filter-cap"),
FeeHistoryCap: v.GetInt32("json-rpc.feehistory-cap"),
TxFeeCap: v.GetFloat64("json-rpc.txfee-cap"),
EVMTimeout: v.GetDuration("json-rpc.evm-timeout"),
LogsCap: v.GetInt32("json-rpc.logs-cap"),
BlockRangeCap: v.GetInt32("json-rpc.block-range-cap"),
HTTPTimeout: v.GetDuration("json-rpc.http-timeout"),
HTTPIdleTimeout: v.GetDuration("json-rpc.http-idle-timeout"),
MaxOpenConnections: v.GetInt("json-rpc.max-open-connections"),
},
TLS: TLSConfig{
CertificatePath: v.GetString("tls.certificate-path"),
Expand Down
4 changes: 4 additions & 0 deletions server/config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ http-idle-timeout = "{{ .JSONRPC.HTTPIdleTimeout }}"
# the node's RPC when the global parameter is disabled.
allow-unprotected-txs = {{ .JSONRPC.AllowUnprotectedTxs }}

# MaxOpenConnections sets the maximum number of simultaneous connections
# for the server listener.
max-open-connections = {{ .JSONRPC.MaxOpenConnections }}

###############################################################################
### TLS Configuration ###
###############################################################################
Expand Down
1 change: 1 addition & 0 deletions server/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const (
JSONRPCHTTPTimeout = "json-rpc.http-timeout"
JSONRPCHTTPIdleTimeout = "json-rpc.http-idle-timeout"
JSONRPCAllowUnprotectedTxs = "json-rpc.allow-unprotected-txs"
JSONRPCMaxOpenConnections = "json-rpc.max-open-connections"
)

// EVM flags
Expand Down
9 changes: 7 additions & 2 deletions server/json_rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
)

// StartJSONRPC starts the JSON-RPC server
func StartJSONRPC(ctx *server.Context, clientCtx client.Context, tmRPCAddr, tmEndpoint string, config config.Config) (*http.Server, chan struct{}, error) {
func StartJSONRPC(ctx *server.Context, clientCtx client.Context, tmRPCAddr, tmEndpoint string, config *config.Config) (*http.Server, chan struct{}, error) {
tmWsClient := ConnectTmWS(tmRPCAddr, tmEndpoint, ctx.Logger)

logger := ctx.Logger.With("module", "geth")
Expand Down Expand Up @@ -70,10 +70,15 @@ func StartJSONRPC(ctx *server.Context, clientCtx client.Context, tmRPCAddr, tmEn
}
httpSrvDone := make(chan struct{}, 1)

ln, err := Listen(httpSrv.Addr, config)
if err != nil {
return nil, nil, err
}

errCh := make(chan error)
go func() {
ctx.Logger.Info("Starting JSON-RPC server", "address", config.JSONRPC.Address)
if err := httpSrv.ListenAndServe(); err != nil {
if err := httpSrv.Serve(ln); err != nil {
if err == http.ErrServerClosed {
close(httpSrvDone)
return
Expand Down
3 changes: 2 additions & 1 deletion server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ which accepts a path for the resulting pprof file.
cmd.Flags().Bool(srvflags.JSONRPCAllowUnprotectedTxs, config.DefaultAllowUnprotectedTxs, "Allow for unprotected (non EIP155 signed) transactions to be submitted via the node's RPC when the global parameter is disabled")
cmd.Flags().Int32(srvflags.JSONRPCLogsCap, config.DefaultLogsCap, "Sets the max number of results can be returned from single `eth_getLogs` query")
cmd.Flags().Int32(srvflags.JSONRPCBlockRangeCap, config.DefaultBlockRangeCap, "Sets the max block range allowed for `eth_getLogs` query")
cmd.Flags().Int(srvflags.JSONRPCMaxOpenConnections, config.DefaultMaxOpenConnections, "Sets the maximum number of simultaneous connections for the server listener")

cmd.Flags().String(srvflags.EVMTracer, config.DefaultEVMTracer, "the EVM tracer type to collect execution traces from the EVM transaction execution (json|struct|access_list|markdown)")
cmd.Flags().Uint64(srvflags.EVMMaxTxGasWanted, config.DefaultMaxTxGasWanted, "the gas wanted for each eth tx returned in ante handler in check tx mode")
Expand Down Expand Up @@ -426,7 +427,7 @@ func startInProcess(ctx *server.Context, clientCtx client.Context, appCreator ty

tmEndpoint := "/websocket"
tmRPCAddr := cfg.RPC.ListenAddress
httpSrv, httpSrvDone, err = StartJSONRPC(ctx, clientCtx, tmRPCAddr, tmEndpoint, config)
httpSrv, httpSrvDone, err = StartJSONRPC(ctx, clientCtx, tmRPCAddr, tmEndpoint, &config)
if err != nil {
return err
}
Expand Down
21 changes: 20 additions & 1 deletion server/util.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package server

import (
"net"
"net/http"
"time"

"github.com/evmos/ethermint/server/config"
"github.com/gorilla/mux"
"github.com/improbable-eng/grpc-web/go/grpcweb"
"github.com/spf13/cobra"
"golang.org/x/net/netutil"

sdkserver "github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/server/types"
Expand All @@ -17,7 +20,7 @@ import (
rpcclient "github.com/tendermint/tendermint/rpc/jsonrpc/client"
)

// add server commands
// AddCommands adds server commands
func AddCommands(rootCmd *cobra.Command, defaultNodeHome string, appCreator types.AppCreator, appExport types.AppExporter, addStartFlags types.ModuleInitFlags) {
tendermintCmd := &cobra.Command{
Use: "tendermint",
Expand Down Expand Up @@ -97,3 +100,19 @@ func MountGRPCWebServices(
})
}
}

// Listen starts a net.Listener on the tcp network on the given address.
// If there is a specified MaxOpenConnections in the config, it will also set the limitListener.
func Listen(addr string, config *config.Config) (net.Listener, error) {
facs95 marked this conversation as resolved.
Show resolved Hide resolved
if addr == "" {
addr = ":http"
}
ln, err := net.Listen("tcp", addr)
if err != nil {
return nil, err
}
if config.JSONRPC.MaxOpenConnections > 0 {
ln = netutil.LimitListener(ln, config.JSONRPC.MaxOpenConnections)
}
return ln, err
}
2 changes: 1 addition & 1 deletion testutil/network/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func startInProcess(cfg Config, val *Validator) error {
tmEndpoint := "/websocket"
tmRPCAddr := val.RPCAddress

val.jsonrpc, val.jsonrpcDone, err = server.StartJSONRPC(val.Ctx, val.ClientCtx, tmRPCAddr, tmEndpoint, *val.AppConfig)
val.jsonrpc, val.jsonrpcDone, err = server.StartJSONRPC(val.Ctx, val.ClientCtx, tmRPCAddr, tmEndpoint, val.AppConfig)
if err != nil {
return err
}
Expand Down