Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rpc: add configurable http and eth_call timeout #4372

Merged
merged 4 commits into from Feb 27, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions cmd/harmony/config_migrations.go
Expand Up @@ -340,6 +340,23 @@ func init() {
return confTree
}

migrations["2.5.12"] = func(confTree *toml.Tree) *toml.Tree {
if confTree.Get("HTTP.ReadTimeout") == nil {
confTree.Set("HTTP.ReadTimeout", defaultConfig.HTTP.ReadTimeout)
}
if confTree.Get("HTTP.WriteTimeout") == nil {
confTree.Set("HTTP.WriteTimeout", defaultConfig.HTTP.WriteTimeout)
}
if confTree.Get("HTTP.IdleTimeout") == nil {
confTree.Set("HTTP.IdleTimeout", defaultConfig.HTTP.IdleTimeout)
}
if confTree.Get("RPCOpt.EvmCallTimeout") == nil {
confTree.Set("RPCOpt.EvmCallTimeout", defaultConfig.RPCOpt.EvmCallTimeout)
}
confTree.Set("Version", "2.5.13")
return confTree
}

// check that the latest version here is the same as in default.go
largestKey := getNextVersion(migrations)
if largestKey != tomlConfigVersion {
Expand Down
6 changes: 5 additions & 1 deletion cmd/harmony/default.go
Expand Up @@ -5,7 +5,7 @@ import (
nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
)

const tomlConfigVersion = "2.5.12"
const tomlConfigVersion = "2.5.13"

const (
defNetworkType = nodeconfig.Mainnet
Expand Down Expand Up @@ -44,6 +44,9 @@ var defaultConfig = harmonyconfig.HarmonyConfig{
Port: nodeconfig.DefaultRPCPort,
AuthPort: nodeconfig.DefaultAuthRPCPort,
RosettaPort: nodeconfig.DefaultRosettaPort,
ReadTimeout: nodeconfig.DefaultHTTPTimeoutRead,
WriteTimeout: nodeconfig.DefaultHTTPTimeoutWrite,
IdleTimeout: nodeconfig.DefaultHTTPTimeoutIdle,
},
WS: harmonyconfig.WsConfig{
Enabled: true,
Expand All @@ -59,6 +62,7 @@ var defaultConfig = harmonyconfig.HarmonyConfig{
RpcFilterFile: "./.hmy/rpc_filter.txt",
RateLimterEnabled: true,
RequestsPerSecond: nodeconfig.DefaultRPCRateLimit,
EvmCallTimeout: nodeconfig.DefaultEvmCallTimeout,
},
BLSKeys: harmonyconfig.BlsConfig{
KeyDir: "./.hmy/blskeys",
Expand Down
39 changes: 38 additions & 1 deletion cmd/harmony/flags.go
Expand Up @@ -75,6 +75,9 @@ var (
httpPortFlag,
httpAuthPortFlag,
httpRosettaPortFlag,
httpReadTimeoutFlag,
httpWriteTimeoutFlag,
httpIdleTimeoutFlag,
}

wsFlags = []cli.Flag{
Expand All @@ -92,6 +95,7 @@ var (
rpcFilterFileFlag,
rpcRateLimiterEnabledFlag,
rpcRateLimitFlag,
rpcEvmCallTimeoutFlag,
}

blsFlags = append(newBLSFlags, legacyBLSFlags...)
Expand Down Expand Up @@ -695,6 +699,21 @@ var (
Usage: "rosetta port to listen for HTTP requests",
DefValue: defaultConfig.HTTP.RosettaPort,
}
httpReadTimeoutFlag = cli.StringFlag{
Name: "http.timeout.read",
Usage: "maximum duration to read the entire request, including the body",
DefValue: defaultConfig.HTTP.ReadTimeout,
}
httpWriteTimeoutFlag = cli.StringFlag{
Name: "http.timeout.write",
Usage: "maximum duration before timing out writes of the response",
DefValue: defaultConfig.HTTP.WriteTimeout,
}
httpIdleTimeoutFlag = cli.StringFlag{
Name: "http.timeout.idle",
Usage: "maximum amount of time to wait for the next request when keep-alives are enabled",
DefValue: defaultConfig.HTTP.IdleTimeout,
}
)

func applyHTTPFlags(cmd *cobra.Command, config *harmonyconfig.HarmonyConfig) {
Expand Down Expand Up @@ -732,6 +751,16 @@ func applyHTTPFlags(cmd *cobra.Command, config *harmonyconfig.HarmonyConfig) {
config.HTTP.Enabled = true
}

if cli.IsFlagChanged(cmd, httpReadTimeoutFlag) {
config.HTTP.ReadTimeout = cli.GetStringFlagValue(cmd, httpReadTimeoutFlag)
}
if cli.IsFlagChanged(cmd, httpWriteTimeoutFlag) {
config.HTTP.WriteTimeout = cli.GetStringFlagValue(cmd, httpWriteTimeoutFlag)
}
if cli.IsFlagChanged(cmd, httpIdleTimeoutFlag) {
config.HTTP.IdleTimeout = cli.GetStringFlagValue(cmd, httpIdleTimeoutFlag)
}

}

// ws flags
Expand Down Expand Up @@ -821,6 +850,12 @@ var (
Usage: "the number of requests per second for RPCs",
DefValue: defaultConfig.RPCOpt.RequestsPerSecond,
}

rpcEvmCallTimeoutFlag = cli.StringFlag{
Name: "rpc.evm-call-timeout",
Usage: "timeout for evm execution (eth_call); 0 means infinite timeout",
DefValue: defaultConfig.RPCOpt.EvmCallTimeout,
}
)

func applyRPCOptFlags(cmd *cobra.Command, config *harmonyconfig.HarmonyConfig) {
Expand All @@ -845,7 +880,9 @@ func applyRPCOptFlags(cmd *cobra.Command, config *harmonyconfig.HarmonyConfig) {
if cli.IsFlagChanged(cmd, rpcRateLimitFlag) {
config.RPCOpt.RequestsPerSecond = cli.GetIntFlagValue(cmd, rpcRateLimitFlag)
}

if cli.IsFlagChanged(cmd, rpcEvmCallTimeoutFlag) {
config.RPCOpt.EvmCallTimeout = cli.GetStringFlagValue(cmd, rpcEvmCallTimeoutFlag)
}
}

// bls flags
Expand Down
58 changes: 58 additions & 0 deletions cmd/harmony/flags_test.go
Expand Up @@ -77,6 +77,9 @@ func TestHarmonyFlags(t *testing.T) {
AuthPort: 9501,
RosettaEnabled: false,
RosettaPort: 9700,
ReadTimeout: defaultConfig.HTTP.ReadTimeout,
WriteTimeout: defaultConfig.HTTP.WriteTimeout,
IdleTimeout: defaultConfig.HTTP.IdleTimeout,
},
RPCOpt: harmonyconfig.RpcOptConfig{
DebugEnabled: false,
Expand All @@ -86,6 +89,7 @@ func TestHarmonyFlags(t *testing.T) {
RpcFilterFile: "./.hmy/rpc_filter.txt",
RateLimterEnabled: true,
RequestsPerSecond: 1000,
EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout,
},
WS: harmonyconfig.WsConfig{
Enabled: true,
Expand Down Expand Up @@ -531,6 +535,9 @@ func TestRPCFlags(t *testing.T) {
Port: defaultConfig.HTTP.Port,
AuthPort: defaultConfig.HTTP.AuthPort,
RosettaPort: defaultConfig.HTTP.RosettaPort,
ReadTimeout: defaultConfig.HTTP.ReadTimeout,
WriteTimeout: defaultConfig.HTTP.WriteTimeout,
IdleTimeout: defaultConfig.HTTP.IdleTimeout,
},
},
{
Expand All @@ -542,6 +549,9 @@ func TestRPCFlags(t *testing.T) {
Port: 9001,
AuthPort: defaultConfig.HTTP.AuthPort,
RosettaPort: defaultConfig.HTTP.RosettaPort,
ReadTimeout: defaultConfig.HTTP.ReadTimeout,
WriteTimeout: defaultConfig.HTTP.WriteTimeout,
IdleTimeout: defaultConfig.HTTP.IdleTimeout,
},
},
{
Expand All @@ -553,6 +563,9 @@ func TestRPCFlags(t *testing.T) {
Port: defaultConfig.HTTP.Port,
AuthPort: 9001,
RosettaPort: defaultConfig.HTTP.RosettaPort,
ReadTimeout: defaultConfig.HTTP.ReadTimeout,
WriteTimeout: defaultConfig.HTTP.WriteTimeout,
IdleTimeout: defaultConfig.HTTP.IdleTimeout,
},
},
{
Expand All @@ -564,6 +577,9 @@ func TestRPCFlags(t *testing.T) {
Port: 9001,
AuthPort: defaultConfig.HTTP.AuthPort,
RosettaPort: 10001,
ReadTimeout: defaultConfig.HTTP.ReadTimeout,
WriteTimeout: defaultConfig.HTTP.WriteTimeout,
IdleTimeout: defaultConfig.HTTP.IdleTimeout,
},
},
{
Expand All @@ -575,6 +591,9 @@ func TestRPCFlags(t *testing.T) {
Port: defaultConfig.HTTP.Port,
AuthPort: defaultConfig.HTTP.AuthPort,
RosettaPort: 10001,
ReadTimeout: defaultConfig.HTTP.ReadTimeout,
WriteTimeout: defaultConfig.HTTP.WriteTimeout,
IdleTimeout: defaultConfig.HTTP.IdleTimeout,
},
},
{
Expand All @@ -586,6 +605,23 @@ func TestRPCFlags(t *testing.T) {
Port: 9501,
AuthPort: 9502,
RosettaPort: 9701,
ReadTimeout: defaultConfig.HTTP.ReadTimeout,
WriteTimeout: defaultConfig.HTTP.WriteTimeout,
IdleTimeout: defaultConfig.HTTP.IdleTimeout,
},
},
{
args: []string{"--http.timeout.read", "10s", "--http.timeout.write", "20s", "--http.timeout.idle", "30s"},
expConfig: harmonyconfig.HttpConfig{
Enabled: true,
RosettaEnabled: false,
IP: defaultConfig.HTTP.IP,
Port: defaultConfig.HTTP.Port,
AuthPort: defaultConfig.HTTP.AuthPort,
RosettaPort: defaultConfig.HTTP.RosettaPort,
ReadTimeout: "10s",
WriteTimeout: "20s",
IdleTimeout: "30s",
},
},
}
Expand Down Expand Up @@ -699,6 +735,7 @@ func TestRPCOptFlags(t *testing.T) {
RpcFilterFile: "./.hmy/rpc_filter.txt",
RateLimterEnabled: true,
RequestsPerSecond: 1000,
EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout,
},
},

Expand All @@ -712,6 +749,7 @@ func TestRPCOptFlags(t *testing.T) {
RpcFilterFile: "./.hmy/rpc_filter.txt",
RateLimterEnabled: true,
RequestsPerSecond: 1000,
EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout,
},
},

Expand All @@ -725,6 +763,7 @@ func TestRPCOptFlags(t *testing.T) {
RpcFilterFile: "./.hmy/rpc_filter.txt",
RateLimterEnabled: true,
RequestsPerSecond: 1000,
EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout,
},
},

Expand All @@ -738,6 +777,7 @@ func TestRPCOptFlags(t *testing.T) {
RpcFilterFile: "./.hmy/rpc_filter.txt",
RateLimterEnabled: true,
RequestsPerSecond: 1000,
EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout,
},
},

Expand All @@ -751,6 +791,7 @@ func TestRPCOptFlags(t *testing.T) {
RpcFilterFile: "./rmf.toml",
RateLimterEnabled: true,
RequestsPerSecond: 1000,
EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout,
},
},

Expand All @@ -764,6 +805,7 @@ func TestRPCOptFlags(t *testing.T) {
RpcFilterFile: "./.hmy/rpc_filter.txt",
RateLimterEnabled: true,
RequestsPerSecond: 1000,
EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout,
},
},

Expand All @@ -777,6 +819,7 @@ func TestRPCOptFlags(t *testing.T) {
RpcFilterFile: "./.hmy/rpc_filter.txt",
RateLimterEnabled: true,
RequestsPerSecond: 2000,
EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout,
},
},

Expand All @@ -790,6 +833,21 @@ func TestRPCOptFlags(t *testing.T) {
RpcFilterFile: "./.hmy/rpc_filter.txt",
RateLimterEnabled: false,
RequestsPerSecond: 2000,
EvmCallTimeout: defaultConfig.RPCOpt.EvmCallTimeout,
},
},

{
args: []string{"--rpc.evm-call-timeout", "10s"},
expConfig: harmonyconfig.RpcOptConfig{
DebugEnabled: false,
EthRPCsEnabled: true,
StakingRPCsEnabled: true,
LegacyRPCsEnabled: true,
RpcFilterFile: "./.hmy/rpc_filter.txt",
RateLimterEnabled: true,
RequestsPerSecond: 1000,
EvmCallTimeout: "10s",
},
},
}
Expand Down
18 changes: 1 addition & 17 deletions cmd/harmony/main.go
Expand Up @@ -334,23 +334,7 @@ func setupNodeAndRun(hc harmonyconfig.HarmonyConfig) {
}

// Parse RPC config
nodeConfig.RPCServer = nodeconfig.RPCServerConfig{
HTTPEnabled: hc.HTTP.Enabled,
HTTPIp: hc.HTTP.IP,
HTTPPort: hc.HTTP.Port,
HTTPAuthPort: hc.HTTP.AuthPort,
WSEnabled: hc.WS.Enabled,
WSIp: hc.WS.IP,
WSPort: hc.WS.Port,
WSAuthPort: hc.WS.AuthPort,
DebugEnabled: hc.RPCOpt.DebugEnabled,
EthRPCsEnabled: hc.RPCOpt.EthRPCsEnabled,
StakingRPCsEnabled: hc.RPCOpt.StakingRPCsEnabled,
LegacyRPCsEnabled: hc.RPCOpt.LegacyRPCsEnabled,
RpcFilterFile: hc.RPCOpt.RpcFilterFile,
RateLimiterEnabled: hc.RPCOpt.RateLimterEnabled,
RequestsPerSecond: hc.RPCOpt.RequestsPerSecond,
}
nodeConfig.RPCServer = hc.ToRPCServerConfig()

// Parse rosetta config
nodeConfig.RosettaServer = nodeconfig.RosettaServerConfig{
Expand Down