Skip to content

Commit

Permalink
rpc: add configurable timeouts to http server (evmos#979)
Browse files Browse the repository at this point in the history
* Add configurable timeouts to http server

Closes: evmos#963

* add flags

* changelog

* fix toml
  • Loading branch information
yihuang committed Mar 24, 2022
1 parent acc87bf commit cffcb5d
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 34 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ Ref: https://keepachangelog.com/en/1.0.0/

## Unreleased

### Improvements

- (rpc) [tharsis#979](https://github.com/tharsis/ethermint/pull/979) Add configurable timeouts to http server

### Bug Fixes

* (rpc) [#970] (https://github.com/tharsis/ethermint/pull/970) Fix unexpected nil reward values on `eth_feeHistory` response
Expand Down
64 changes: 42 additions & 22 deletions server/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ const (
DefaultEVMTimeout = 5 * time.Second
// default 1.0 eth
DefaultTxFeeCap float64 = 1.0

DefaultHTTPTimeout = 30 * time.Second

DefaultHTTPIdleTimeout = 120 * time.Second
)

var evmTracers = []string{"json", "markdown", "struct", "access_list"}
Expand Down Expand Up @@ -86,6 +90,10 @@ type JSONRPCConfig struct {
LogsCap int32 `mapstructure:"logs-cap"`
// BlockRangeCap defines the max block range allowed for `eth_getLogs` query.
BlockRangeCap int32 `mapstructure:"block-range-cap"`
// HTTPTimeout is the read/write timeout of http json-rpc server.
HTTPTimeout time.Duration `mapstructure:"http-timeout"`
// HTTPIdleTimeout is the idle timeout of http json-rpc server.
HTTPIdleTimeout time.Duration `mapstructure:"http-idle-timeout"`
}

// TLSConfig defines the certificate and matching private key for the server.
Expand Down Expand Up @@ -170,17 +178,19 @@ func GetAPINamespaces() []string {
// DefaultJSONRPCConfig returns an EVM config with the JSON-RPC API enabled by default
func DefaultJSONRPCConfig() *JSONRPCConfig {
return &JSONRPCConfig{
Enable: true,
API: GetDefaultAPINamespaces(),
Address: DefaultJSONRPCAddress,
WsAddress: DefaultJSONRPCWsAddress,
GasCap: DefaultGasCap,
EVMTimeout: DefaultEVMTimeout,
TxFeeCap: DefaultTxFeeCap,
FilterCap: DefaultFilterCap,
FeeHistoryCap: DefaultFeeHistoryCap,
BlockRangeCap: DefaultBlockRangeCap,
LogsCap: DefaultLogsCap,
Enable: true,
API: GetDefaultAPINamespaces(),
Address: DefaultJSONRPCAddress,
WsAddress: DefaultJSONRPCWsAddress,
GasCap: DefaultGasCap,
EVMTimeout: DefaultEVMTimeout,
TxFeeCap: DefaultTxFeeCap,
FilterCap: DefaultFilterCap,
FeeHistoryCap: DefaultFeeHistoryCap,
BlockRangeCap: DefaultBlockRangeCap,
LogsCap: DefaultLogsCap,
HTTPTimeout: DefaultHTTPTimeout,
HTTPIdleTimeout: DefaultHTTPIdleTimeout,
}
}

Expand Down Expand Up @@ -214,6 +224,14 @@ func (c JSONRPCConfig) Validate() error {
return errors.New("JSON-RPC block range cap cannot be negative")
}

if c.HTTPTimeout < 0 {
return errors.New("JSON-RPC HTTP timeout duration cannot be negative")
}

if c.HTTPIdleTimeout < 0 {
return errors.New("JSON-RPC HTTP idle timeout duration cannot be negative")
}

// TODO: validate APIs
seenAPIs := make(map[string]bool)
for _, api := range c.API {
Expand Down Expand Up @@ -262,17 +280,19 @@ func GetConfig(v *viper.Viper) Config {
Tracer: v.GetString("evm.tracer"),
},
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"),
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"),
},
TLS: TLSConfig{
CertificatePath: v.GetString("tls.certificate-path"),
Expand Down
6 changes: 6 additions & 0 deletions server/config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ logs-cap = {{ .JSONRPC.LogsCap }}
# BlockRangeCap defines the max block range allowed for 'eth_getLogs' query.
block-range-cap = {{ .JSONRPC.BlockRangeCap }}
# HTTPTimeout is the read/write timeout of http json-rpc server.
http-timeout = "{{ .JSONRPC.HTTPTimeout }}"
# HTTPIdleTimeout is the idle timeout of http json-rpc server.
http-idle-timeout = "{{ .JSONRPC.HTTPIdleTimeout }}"
###############################################################################
### TLS Configuration ###
###############################################################################
Expand Down
22 changes: 12 additions & 10 deletions server/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,18 @@ const (

// JSON-RPC flags
const (
JSONRPCEnable = "json-rpc.enable"
JSONRPCAPI = "json-rpc.api"
JSONRPCAddress = "json-rpc.address"
JSONWsAddress = "json-rpc.ws-address"
JSONRPCGasCap = "json-rpc.gas-cap"
JSONRPCEVMTimeout = "json-rpc.evm-timeout"
JSONRPCTxFeeCap = "json-rpc.txfee-cap"
JSONRPCFilterCap = "json-rpc.filter-cap"
JSONRPCLogsCap = "json-rpc.logs-cap"
JSONRPCBlockRangeCap = "json-rpc.block-range-cap"
JSONRPCEnable = "json-rpc.enable"
JSONRPCAPI = "json-rpc.api"
JSONRPCAddress = "json-rpc.address"
JSONWsAddress = "json-rpc.ws-address"
JSONRPCGasCap = "json-rpc.gas-cap"
JSONRPCEVMTimeout = "json-rpc.evm-timeout"
JSONRPCTxFeeCap = "json-rpc.txfee-cap"
JSONRPCFilterCap = "json-rpc.filter-cap"
JSONRPCLogsCap = "json-rpc.logs-cap"
JSONRPCBlockRangeCap = "json-rpc.block-range-cap"
JSONRPCHTTPTimeout = "json-rpc.http-timeout"
JSONRPCHTTPIdleTimeout = "json-rpc.http-idle-timeout"
)

// EVM flags
Expand Down
7 changes: 5 additions & 2 deletions server/json_rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ func StartJSONRPC(ctx *server.Context, clientCtx client.Context, tmRPCAddr, tmEn
}

httpSrv := &http.Server{
Addr: config.JSONRPC.Address,
Handler: handlerWithCors.Handler(r),
Addr: config.JSONRPC.Address,
Handler: handlerWithCors.Handler(r),
ReadTimeout: config.JSONRPC.HTTPTimeout,
WriteTimeout: config.JSONRPC.HTTPTimeout,
IdleTimeout: config.JSONRPC.HTTPIdleTimeout,
}
httpSrvDone := make(chan struct{}, 1)

Expand Down
2 changes: 2 additions & 0 deletions server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ which accepts a path for the resulting pprof file.
cmd.Flags().Float64(srvflags.JSONRPCTxFeeCap, config.DefaultTxFeeCap, "Sets a cap on transaction fee that can be sent via the RPC APIs (1 = default 1 photon)")
cmd.Flags().Int32(srvflags.JSONRPCFilterCap, config.DefaultFilterCap, "Sets the global cap for total number of filters that can be created")
cmd.Flags().Duration(srvflags.JSONRPCEVMTimeout, config.DefaultEVMTimeout, "Sets a timeout used for eth_call (0=infinite)")
cmd.Flags().Duration(srvflags.JSONRPCHTTPTimeout, config.DefaultHTTPTimeout, "Sets a read/write timeout for json-rpc http server (0=infinite)")
cmd.Flags().Duration(srvflags.JSONRPCHTTPIdleTimeout, config.DefaultHTTPIdleTimeout, "Sets a idle timeout for json-rpc http server (0=infinite)")
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")

Expand Down

0 comments on commit cffcb5d

Please sign in to comment.