rpc: add configurable timeouts to http server (#979)

* Add configurable timeouts to http server

Closes: #963

* add flags

* changelog

* fix toml
This commit is contained in:
yihuang 2022-03-09 15:31:51 +08:00 committed by GitHub
parent 67fba0a813
commit dbe9f705cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 71 additions and 34 deletions

View File

@ -46,6 +46,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (rpc) [tharsis#975](https://github.com/tharsis/ethermint/pull/975) Fix unexpected `nil` values for `reward`, returned by `EffectiveGasTipValue(blockBaseFee)` in the `eth_feeHistory` RPC method. * (rpc) [tharsis#975](https://github.com/tharsis/ethermint/pull/975) Fix unexpected `nil` values for `reward`, returned by `EffectiveGasTipValue(blockBaseFee)` in the `eth_feeHistory` RPC method.
### Improvements
- (rpc) [tharsis#979](https://github.com/tharsis/ethermint/pull/979) Add configurable timeouts to http server
## [v0.10.1] - 2022-03-04 ## [v0.10.1] - 2022-03-04
### Bug Fixes ### Bug Fixes

View File

@ -41,6 +41,10 @@ const (
DefaultEVMTimeout = 5 * time.Second DefaultEVMTimeout = 5 * time.Second
// default 1.0 eth // default 1.0 eth
DefaultTxFeeCap float64 = 1.0 DefaultTxFeeCap float64 = 1.0
DefaultHTTPTimeout = 30 * time.Second
DefaultHTTPIdleTimeout = 120 * time.Second
) )
var evmTracers = []string{"json", "markdown", "struct", "access_list"} var evmTracers = []string{"json", "markdown", "struct", "access_list"}
@ -86,6 +90,10 @@ type JSONRPCConfig struct {
LogsCap int32 `mapstructure:"logs-cap"` LogsCap int32 `mapstructure:"logs-cap"`
// BlockRangeCap defines the max block range allowed for `eth_getLogs` query. // BlockRangeCap defines the max block range allowed for `eth_getLogs` query.
BlockRangeCap int32 `mapstructure:"block-range-cap"` 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. // TLSConfig defines the certificate and matching private key for the server.
@ -170,17 +178,19 @@ func GetAPINamespaces() []string {
// DefaultJSONRPCConfig returns an EVM config with the JSON-RPC API enabled by default // DefaultJSONRPCConfig returns an EVM config with the JSON-RPC API enabled by default
func DefaultJSONRPCConfig() *JSONRPCConfig { func DefaultJSONRPCConfig() *JSONRPCConfig {
return &JSONRPCConfig{ return &JSONRPCConfig{
Enable: true, Enable: true,
API: GetDefaultAPINamespaces(), API: GetDefaultAPINamespaces(),
Address: DefaultJSONRPCAddress, Address: DefaultJSONRPCAddress,
WsAddress: DefaultJSONRPCWsAddress, WsAddress: DefaultJSONRPCWsAddress,
GasCap: DefaultGasCap, GasCap: DefaultGasCap,
EVMTimeout: DefaultEVMTimeout, EVMTimeout: DefaultEVMTimeout,
TxFeeCap: DefaultTxFeeCap, TxFeeCap: DefaultTxFeeCap,
FilterCap: DefaultFilterCap, FilterCap: DefaultFilterCap,
FeeHistoryCap: DefaultFeeHistoryCap, FeeHistoryCap: DefaultFeeHistoryCap,
BlockRangeCap: DefaultBlockRangeCap, BlockRangeCap: DefaultBlockRangeCap,
LogsCap: DefaultLogsCap, LogsCap: DefaultLogsCap,
HTTPTimeout: DefaultHTTPTimeout,
HTTPIdleTimeout: DefaultHTTPIdleTimeout,
} }
} }
@ -214,6 +224,14 @@ func (c JSONRPCConfig) Validate() error {
return errors.New("JSON-RPC block range cap cannot be negative") 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 // TODO: validate APIs
seenAPIs := make(map[string]bool) seenAPIs := make(map[string]bool)
for _, api := range c.API { for _, api := range c.API {
@ -262,17 +280,19 @@ func GetConfig(v *viper.Viper) Config {
Tracer: v.GetString("evm.tracer"), Tracer: v.GetString("evm.tracer"),
}, },
JSONRPC: JSONRPCConfig{ JSONRPC: JSONRPCConfig{
Enable: v.GetBool("json-rpc.enable"), Enable: v.GetBool("json-rpc.enable"),
API: v.GetStringSlice("json-rpc.api"), API: v.GetStringSlice("json-rpc.api"),
Address: v.GetString("json-rpc.address"), Address: v.GetString("json-rpc.address"),
WsAddress: v.GetString("json-rpc.ws-address"), WsAddress: v.GetString("json-rpc.ws-address"),
GasCap: v.GetUint64("json-rpc.gas-cap"), GasCap: v.GetUint64("json-rpc.gas-cap"),
FilterCap: v.GetInt32("json-rpc.filter-cap"), FilterCap: v.GetInt32("json-rpc.filter-cap"),
FeeHistoryCap: v.GetInt32("json-rpc.feehistory-cap"), FeeHistoryCap: v.GetInt32("json-rpc.feehistory-cap"),
TxFeeCap: v.GetFloat64("json-rpc.txfee-cap"), TxFeeCap: v.GetFloat64("json-rpc.txfee-cap"),
EVMTimeout: v.GetDuration("json-rpc.evm-timeout"), EVMTimeout: v.GetDuration("json-rpc.evm-timeout"),
LogsCap: v.GetInt32("json-rpc.logs-cap"), LogsCap: v.GetInt32("json-rpc.logs-cap"),
BlockRangeCap: v.GetInt32("json-rpc.block-range-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{ TLS: TLSConfig{
CertificatePath: v.GetString("tls.certificate-path"), CertificatePath: v.GetString("tls.certificate-path"),

View File

@ -53,6 +53,12 @@ logs-cap = {{ .JSONRPC.LogsCap }}
# BlockRangeCap defines the max block range allowed for 'eth_getLogs' query. # BlockRangeCap defines the max block range allowed for 'eth_getLogs' query.
block-range-cap = {{ .JSONRPC.BlockRangeCap }} 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 ### ### TLS Configuration ###
############################################################################### ###############################################################################

View File

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

View File

@ -59,8 +59,11 @@ func StartJSONRPC(ctx *server.Context, clientCtx client.Context, tmRPCAddr, tmEn
} }
httpSrv := &http.Server{ httpSrv := &http.Server{
Addr: config.JSONRPC.Address, Addr: config.JSONRPC.Address,
Handler: handlerWithCors.Handler(r), Handler: handlerWithCors.Handler(r),
ReadTimeout: config.JSONRPC.HTTPTimeout,
WriteTimeout: config.JSONRPC.HTTPTimeout,
IdleTimeout: config.JSONRPC.HTTPIdleTimeout,
} }
httpSrvDone := make(chan struct{}, 1) httpSrvDone := make(chan struct{}, 1)

View File

@ -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().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().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.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.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().Int32(srvflags.JSONRPCBlockRangeCap, config.DefaultBlockRangeCap, "Sets the max block range allowed for `eth_getLogs` query")