From 6a9b99fe25f60054dc93307eb99c599a6122b810 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Tue, 8 Mar 2022 10:22:20 +0800 Subject: [PATCH] Add configurable timeouts to http server Closes: #963 --- server/config/config.go | 64 +++++++++++++++++++++++++++-------------- server/config/toml.go | 6 ++++ server/json_rpc.go | 7 +++-- 3 files changed, 53 insertions(+), 24 deletions(-) diff --git a/server/config/config.go b/server/config/config.go index 9a018f8125..4909d50708 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -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"} @@ -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. @@ -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, } } @@ -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 { @@ -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"), diff --git a/server/config/toml.go b/server/config/toml.go index 24233dcb2e..8cd0fedc0f 100644 --- a/server/config/toml.go +++ b/server/config/toml.go @@ -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 ### ############################################################################### diff --git a/server/json_rpc.go b/server/json_rpc.go index 4c893d714e..244ad4dc98 100644 --- a/server/json_rpc.go +++ b/server/json_rpc.go @@ -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)