From 922d31004db8af13c48d86525a5867bab0bf3934 Mon Sep 17 00:00:00 2001 From: Noam Hurwitz Date: Sun, 26 Sep 2021 13:15:26 -0700 Subject: [PATCH 1/3] eth,rpc: allow for flag configured timeouts for eth_call --- cmd/geth/main.go | 1 + cmd/geth/usage.go | 1 + cmd/utils/flags.go | 8 ++++++++ eth/api_backend.go | 5 +++++ eth/ethconfig/config.go | 12 ++++++++---- eth/ethconfig/gen_config.go | 6 ++++++ graphql/graphql.go | 10 ++++------ internal/ethapi/api.go | 2 +- internal/ethapi/backend.go | 8 +++++--- les/api_backend.go | 5 +++++ 10 files changed, 44 insertions(+), 14 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index d003d590ed28e..1667e9b48b2ca 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -173,6 +173,7 @@ var ( utils.IPCPathFlag, utils.InsecureUnlockAllowedFlag, utils.RPCGlobalGasCapFlag, + utils.RPCGlobalCallTimeoutFlag, utils.RPCGlobalTxFeeCapFlag, utils.AllowUnprotectedTxs, } diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 16446f83e24c3..8ea0b1e77204f 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -150,6 +150,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.GraphQLCORSDomainFlag, utils.GraphQLVirtualHostsFlag, utils.RPCGlobalGasCapFlag, + utils.RPCGlobalCallTimeoutFlag, utils.RPCGlobalTxFeeCapFlag, utils.AllowUnprotectedTxs, utils.JSpathFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 52c15c68ec320..63be0ebe3e22f 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -493,6 +493,11 @@ var ( Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)", Value: ethconfig.Defaults.RPCGasCap, } + RPCGlobalCallTimeoutFlag = cli.DurationFlag{ + Name: "rpc.calltimeout", + Usage: "Sets a timeout used for eth_call (0=infinite)", + Value: ethconfig.Defaults.RPCCallTimeout, + } RPCGlobalTxFeeCapFlag = cli.Float64Flag{ Name: "rpc.txfeecap", Usage: "Sets a cap on transaction fee (in ether) that can be sent via the RPC APIs (0 = no cap)", @@ -1563,6 +1568,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } else { log.Info("Global gas cap disabled") } + if ctx.GlobalIsSet(RPCGlobalCallTimeoutFlag.Name) { + cfg.RPCCallTimeout = ctx.GlobalDuration(RPCGlobalCallTimeoutFlag.Name) + } if ctx.GlobalIsSet(RPCGlobalTxFeeCapFlag.Name) { cfg.RPCTxFeeCap = ctx.GlobalFloat64(RPCGlobalTxFeeCapFlag.Name) } diff --git a/eth/api_backend.go b/eth/api_backend.go index 7b40a7edd3a11..6ce7a8ec88e86 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -20,6 +20,7 @@ import ( "context" "errors" "math/big" + "time" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts" @@ -315,6 +316,10 @@ func (b *EthAPIBackend) RPCGasCap() uint64 { return b.eth.config.RPCGasCap } +func (b *EthAPIBackend) RPCCallTimeout() time.Duration { + return b.eth.config.RPCCallTimeout +} + func (b *EthAPIBackend) RPCTxFeeCap() float64 { return b.eth.config.RPCTxFeeCap } diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 89cdb75597e08..8b71341b5e0bc 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -87,10 +87,11 @@ var Defaults = Config{ GasPrice: big.NewInt(params.GWei), Recommit: 3 * time.Second, }, - TxPool: core.DefaultTxPoolConfig, - RPCGasCap: 50000000, - GPO: FullNodeGPO, - RPCTxFeeCap: 1, // 1 ether + TxPool: core.DefaultTxPoolConfig, + RPCGasCap: 50000000, + RPCCallTimeout: 5 * time.Second, + GPO: FullNodeGPO, + RPCTxFeeCap: 1, // 1 ether } func init() { @@ -188,6 +189,9 @@ type Config struct { // RPCGasCap is the global gas cap for eth-call variants. RPCGasCap uint64 + // RPCCallTimeout is the global timeout for eth-call. + RPCCallTimeout time.Duration + // RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for // send-transction variants. The unit is ether. RPCTxFeeCap float64 diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 2310dd44997b6..e2947c87fb023 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -55,6 +55,7 @@ func (c Config) MarshalTOML() (interface{}, error) { EnablePreimageRecording bool DocRoot string `toml:"-"` RPCGasCap uint64 + RPCCallTimeout time.Duration RPCTxFeeCap float64 Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` @@ -98,6 +99,7 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.EnablePreimageRecording = c.EnablePreimageRecording enc.DocRoot = c.DocRoot enc.RPCGasCap = c.RPCGasCap + enc.RPCCallTimeout = c.RPCCallTimeout enc.RPCTxFeeCap = c.RPCTxFeeCap enc.Checkpoint = c.Checkpoint enc.CheckpointOracle = c.CheckpointOracle @@ -145,6 +147,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { EnablePreimageRecording *bool DocRoot *string `toml:"-"` RPCGasCap *uint64 + RPCCallTimeout *time.Duration RPCTxFeeCap *float64 Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` @@ -265,6 +268,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.RPCGasCap != nil { c.RPCGasCap = *dec.RPCGasCap } + if dec.RPCCallTimeout != nil { + c.RPCCallTimeout = *dec.RPCCallTimeout + } if dec.RPCTxFeeCap != nil { c.RPCTxFeeCap = *dec.RPCTxFeeCap } diff --git a/graphql/graphql.go b/graphql/graphql.go index 4dd96c4b9db18..d131be6c71fe3 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -21,10 +21,6 @@ import ( "context" "errors" "fmt" - "math/big" - "strconv" - "time" - "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -34,6 +30,8 @@ import ( "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/rpc" + "math/big" + "strconv" ) var ( @@ -954,7 +952,7 @@ func (b *Block) Call(ctx context.Context, args struct { return nil, err } } - result, err := ethapi.DoCall(ctx, b.backend, args.Data, *b.numberOrHash, nil, 5*time.Second, b.backend.RPCGasCap()) + result, err := ethapi.DoCall(ctx, b.backend, args.Data, *b.numberOrHash, nil, b.backend.RPCCallTimeout(), b.backend.RPCGasCap()) if err != nil { return nil, err } @@ -1024,7 +1022,7 @@ func (p *Pending) Call(ctx context.Context, args struct { Data ethapi.TransactionArgs }) (*CallResult, error) { pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) - result, err := ethapi.DoCall(ctx, p.backend, args.Data, pendingBlockNr, nil, 5*time.Second, p.backend.RPCGasCap()) + result, err := ethapi.DoCall(ctx, p.backend, args.Data, pendingBlockNr, nil, p.backend.RPCCallTimeout(), p.backend.RPCGasCap()) if err != nil { return nil, err } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 6997f2c82878d..1d667ab161fe9 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -972,7 +972,7 @@ func (e *revertError) ErrorData() interface{} { // Note, this function doesn't make and changes in the state/blockchain and is // useful to execute and retrieve values. func (s *PublicBlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Bytes, error) { - result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, 5*time.Second, s.b.RPCGasCap()) + result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, s.b.RPCCallTimeout(), s.b.RPCGasCap()) if err != nil { return nil, err } diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 1624f49635b33..97ea22cb634c8 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -20,6 +20,7 @@ package ethapi import ( "context" "math/big" + "time" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts" @@ -47,9 +48,10 @@ type Backend interface { ChainDb() ethdb.Database AccountManager() *accounts.Manager ExtRPCEnabled() bool - RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection - RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs - UnprotectedAllowed() bool // allows only for EIP155 transactions. + RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection + RPCCallTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection + RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs + UnprotectedAllowed() bool // allows only for EIP155 transactions. // Blockchain API SetHead(number uint64) diff --git a/les/api_backend.go b/les/api_backend.go index e12984cb49e36..ce2abf684a624 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -20,6 +20,7 @@ import ( "context" "errors" "math/big" + "time" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts" @@ -293,6 +294,10 @@ func (b *LesApiBackend) RPCGasCap() uint64 { return b.eth.config.RPCGasCap } +func (b *LesApiBackend) RPCCallTimeout() time.Duration { + return b.eth.config.RPCCallTimeout +} + func (b *LesApiBackend) RPCTxFeeCap() float64 { return b.eth.config.RPCTxFeeCap } From 90f5cc91619a5c91d77d42e5e2a890c5a14139e1 Mon Sep 17 00:00:00 2001 From: Noam Hurwitz Date: Sun, 26 Sep 2021 13:36:30 -0700 Subject: [PATCH 2/3] lint: account for package-local import order --- graphql/graphql.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/graphql/graphql.go b/graphql/graphql.go index d131be6c71fe3..426cde622d699 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -21,6 +21,9 @@ import ( "context" "errors" "fmt" + "math/big" + "strconv" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -30,8 +33,6 @@ import ( "github.com/ethereum/go-ethereum/eth/filters" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/rpc" - "math/big" - "strconv" ) var ( From acb2c3fb378f3be67cbcdb435d5da4e85f8a541f Mon Sep 17 00:00:00 2001 From: Noam Hurwitz Date: Tue, 28 Sep 2021 08:52:51 -0700 Subject: [PATCH 3/3] cr: rename `rpc.calltimeout` to `rpc.evmtimeout` --- cmd/geth/main.go | 2 +- cmd/geth/usage.go | 2 +- cmd/utils/flags.go | 10 +++++----- eth/api_backend.go | 4 ++-- eth/ethconfig/config.go | 14 +++++++------- eth/ethconfig/gen_config.go | 10 +++++----- graphql/graphql.go | 4 ++-- internal/ethapi/api.go | 2 +- internal/ethapi/backend.go | 8 ++++---- les/api_backend.go | 4 ++-- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 1667e9b48b2ca..d18fd1e25ed75 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -173,7 +173,7 @@ var ( utils.IPCPathFlag, utils.InsecureUnlockAllowedFlag, utils.RPCGlobalGasCapFlag, - utils.RPCGlobalCallTimeoutFlag, + utils.RPCGlobalEVMTimeoutFlag, utils.RPCGlobalTxFeeCapFlag, utils.AllowUnprotectedTxs, } diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 8ea0b1e77204f..5d82baceaae95 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -150,7 +150,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{ utils.GraphQLCORSDomainFlag, utils.GraphQLVirtualHostsFlag, utils.RPCGlobalGasCapFlag, - utils.RPCGlobalCallTimeoutFlag, + utils.RPCGlobalEVMTimeoutFlag, utils.RPCGlobalTxFeeCapFlag, utils.AllowUnprotectedTxs, utils.JSpathFlag, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 63be0ebe3e22f..3934ee6ca4595 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -493,10 +493,10 @@ var ( Usage: "Sets a cap on gas that can be used in eth_call/estimateGas (0=infinite)", Value: ethconfig.Defaults.RPCGasCap, } - RPCGlobalCallTimeoutFlag = cli.DurationFlag{ - Name: "rpc.calltimeout", + RPCGlobalEVMTimeoutFlag = cli.DurationFlag{ + Name: "rpc.evmtimeout", Usage: "Sets a timeout used for eth_call (0=infinite)", - Value: ethconfig.Defaults.RPCCallTimeout, + Value: ethconfig.Defaults.RPCEVMTimeout, } RPCGlobalTxFeeCapFlag = cli.Float64Flag{ Name: "rpc.txfeecap", @@ -1568,8 +1568,8 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } else { log.Info("Global gas cap disabled") } - if ctx.GlobalIsSet(RPCGlobalCallTimeoutFlag.Name) { - cfg.RPCCallTimeout = ctx.GlobalDuration(RPCGlobalCallTimeoutFlag.Name) + if ctx.GlobalIsSet(RPCGlobalEVMTimeoutFlag.Name) { + cfg.RPCEVMTimeout = ctx.GlobalDuration(RPCGlobalEVMTimeoutFlag.Name) } if ctx.GlobalIsSet(RPCGlobalTxFeeCapFlag.Name) { cfg.RPCTxFeeCap = ctx.GlobalFloat64(RPCGlobalTxFeeCapFlag.Name) diff --git a/eth/api_backend.go b/eth/api_backend.go index 6ce7a8ec88e86..d9539a1a2967d 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -316,8 +316,8 @@ func (b *EthAPIBackend) RPCGasCap() uint64 { return b.eth.config.RPCGasCap } -func (b *EthAPIBackend) RPCCallTimeout() time.Duration { - return b.eth.config.RPCCallTimeout +func (b *EthAPIBackend) RPCEVMTimeout() time.Duration { + return b.eth.config.RPCEVMTimeout } func (b *EthAPIBackend) RPCTxFeeCap() float64 { diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 8b71341b5e0bc..52391d417db0b 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -87,11 +87,11 @@ var Defaults = Config{ GasPrice: big.NewInt(params.GWei), Recommit: 3 * time.Second, }, - TxPool: core.DefaultTxPoolConfig, - RPCGasCap: 50000000, - RPCCallTimeout: 5 * time.Second, - GPO: FullNodeGPO, - RPCTxFeeCap: 1, // 1 ether + TxPool: core.DefaultTxPoolConfig, + RPCGasCap: 50000000, + RPCEVMTimeout: 5 * time.Second, + GPO: FullNodeGPO, + RPCTxFeeCap: 1, // 1 ether } func init() { @@ -189,8 +189,8 @@ type Config struct { // RPCGasCap is the global gas cap for eth-call variants. RPCGasCap uint64 - // RPCCallTimeout is the global timeout for eth-call. - RPCCallTimeout time.Duration + // RPCEVMTimeout is the global timeout for eth-call. + RPCEVMTimeout time.Duration // RPCTxFeeCap is the global transaction fee(price * gaslimit) cap for // send-transction variants. The unit is ether. diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index e2947c87fb023..ed4c9285082d9 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -55,7 +55,7 @@ func (c Config) MarshalTOML() (interface{}, error) { EnablePreimageRecording bool DocRoot string `toml:"-"` RPCGasCap uint64 - RPCCallTimeout time.Duration + RPCEVMTimeout time.Duration RPCTxFeeCap float64 Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` @@ -99,7 +99,7 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.EnablePreimageRecording = c.EnablePreimageRecording enc.DocRoot = c.DocRoot enc.RPCGasCap = c.RPCGasCap - enc.RPCCallTimeout = c.RPCCallTimeout + enc.RPCEVMTimeout = c.RPCEVMTimeout enc.RPCTxFeeCap = c.RPCTxFeeCap enc.Checkpoint = c.Checkpoint enc.CheckpointOracle = c.CheckpointOracle @@ -147,7 +147,7 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { EnablePreimageRecording *bool DocRoot *string `toml:"-"` RPCGasCap *uint64 - RPCCallTimeout *time.Duration + RPCEVMTimeout *time.Duration RPCTxFeeCap *float64 Checkpoint *params.TrustedCheckpoint `toml:",omitempty"` CheckpointOracle *params.CheckpointOracleConfig `toml:",omitempty"` @@ -268,8 +268,8 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.RPCGasCap != nil { c.RPCGasCap = *dec.RPCGasCap } - if dec.RPCCallTimeout != nil { - c.RPCCallTimeout = *dec.RPCCallTimeout + if dec.RPCEVMTimeout != nil { + c.RPCEVMTimeout = *dec.RPCEVMTimeout } if dec.RPCTxFeeCap != nil { c.RPCTxFeeCap = *dec.RPCTxFeeCap diff --git a/graphql/graphql.go b/graphql/graphql.go index 426cde622d699..60e40df70457e 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -953,7 +953,7 @@ func (b *Block) Call(ctx context.Context, args struct { return nil, err } } - result, err := ethapi.DoCall(ctx, b.backend, args.Data, *b.numberOrHash, nil, b.backend.RPCCallTimeout(), b.backend.RPCGasCap()) + result, err := ethapi.DoCall(ctx, b.backend, args.Data, *b.numberOrHash, nil, b.backend.RPCEVMTimeout(), b.backend.RPCGasCap()) if err != nil { return nil, err } @@ -1023,7 +1023,7 @@ func (p *Pending) Call(ctx context.Context, args struct { Data ethapi.TransactionArgs }) (*CallResult, error) { pendingBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) - result, err := ethapi.DoCall(ctx, p.backend, args.Data, pendingBlockNr, nil, p.backend.RPCCallTimeout(), p.backend.RPCGasCap()) + result, err := ethapi.DoCall(ctx, p.backend, args.Data, pendingBlockNr, nil, p.backend.RPCEVMTimeout(), p.backend.RPCGasCap()) if err != nil { return nil, err } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 1d667ab161fe9..5d2a28c586699 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -972,7 +972,7 @@ func (e *revertError) ErrorData() interface{} { // Note, this function doesn't make and changes in the state/blockchain and is // useful to execute and retrieve values. func (s *PublicBlockChainAPI) Call(ctx context.Context, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride) (hexutil.Bytes, error) { - result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, s.b.RPCCallTimeout(), s.b.RPCGasCap()) + result, err := DoCall(ctx, s.b, args, blockNrOrHash, overrides, s.b.RPCEVMTimeout(), s.b.RPCGasCap()) if err != nil { return nil, err } diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 97ea22cb634c8..bc60fb2a64f6c 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -48,10 +48,10 @@ type Backend interface { ChainDb() ethdb.Database AccountManager() *accounts.Manager ExtRPCEnabled() bool - RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection - RPCCallTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection - RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs - UnprotectedAllowed() bool // allows only for EIP155 transactions. + RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection + RPCEVMTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection + RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs + UnprotectedAllowed() bool // allows only for EIP155 transactions. // Blockchain API SetHead(number uint64) diff --git a/les/api_backend.go b/les/api_backend.go index ce2abf684a624..d5144dfbfb578 100644 --- a/les/api_backend.go +++ b/les/api_backend.go @@ -294,8 +294,8 @@ func (b *LesApiBackend) RPCGasCap() uint64 { return b.eth.config.RPCGasCap } -func (b *LesApiBackend) RPCCallTimeout() time.Duration { - return b.eth.config.RPCCallTimeout +func (b *LesApiBackend) RPCEVMTimeout() time.Duration { + return b.eth.config.RPCEVMTimeout } func (b *LesApiBackend) RPCTxFeeCap() float64 {