diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index d48219e14c..26fe7ca24e 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -1772,10 +1772,10 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { cfg.LogQueryLimit = ctx.Int(RPCGlobalLogQueryLimit.Name) } if ctx.IsSet(RPCTxSyncDefaultTimeoutFlag.Name) { - cfg.TxSyncDefaultTimeout = uint64(ctx.Duration(RPCTxSyncDefaultTimeoutFlag.Name).Milliseconds()) + cfg.TxSyncDefaultTimeout = ctx.Duration(RPCTxSyncDefaultTimeoutFlag.Name) } if ctx.IsSet(RPCTxSyncMaxTimeoutFlag.Name) { - cfg.TxSyncMaxTimeout = uint64(ctx.Duration(RPCTxSyncMaxTimeoutFlag.Name).Milliseconds()) + cfg.TxSyncMaxTimeout = ctx.Duration(RPCTxSyncMaxTimeoutFlag.Name) } if ctx.IsSet(RPCGlobalRangeLimitFlag.Name) { cfg.RangeLimit = ctx.Uint64(RPCGlobalRangeLimitFlag.Name) diff --git a/eth/api_backend.go b/eth/api_backend.go index 0174b690bb..3f826b7861 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -492,10 +492,10 @@ func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Blo return b.eth.stateAtTransaction(ctx, block, txIndex, reexec) } -func (b *EthAPIBackend) RPCTxSyncDefaultTimeout() uint64 { +func (b *EthAPIBackend) RPCTxSyncDefaultTimeout() time.Duration { return b.eth.config.TxSyncDefaultTimeout } -func (b *EthAPIBackend) RPCTxSyncMaxTimeout() uint64 { +func (b *EthAPIBackend) RPCTxSyncMaxTimeout() time.Duration { return b.eth.config.TxSyncMaxTimeout } diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index bad85cde68..8aa6e4ef09 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -72,10 +72,10 @@ var Defaults = Config{ RPCGasCap: 50000000, RPCEVMTimeout: 5 * time.Second, GPO: FullNodeGPO, - RPCTxFeeCap: 1, // 1 ether - TxSyncDefaultTimeout: uint64(20000), // 20 seconds in milliseconds - TxSyncMaxTimeout: uint64(60000), // 1 minute in milliseconds - SlowBlockThreshold: -1, // Disabled by default; set via --debug.logslowblock flag + RPCTxFeeCap: 1, // 1 ether + TxSyncDefaultTimeout: 20 * time.Second, + TxSyncMaxTimeout: 1 * time.Minute, + SlowBlockThreshold: -1, // Disabled by default; set via --debug.logslowblock flag RangeLimit: 0, } @@ -204,8 +204,8 @@ type Config struct { OverrideVerkle *uint64 `toml:",omitempty"` // EIP-7966: eth_sendRawTransactionSync timeouts - TxSyncDefaultTimeout uint64 `toml:",omitempty"` - TxSyncMaxTimeout uint64 `toml:",omitempty"` + TxSyncDefaultTimeout time.Duration `toml:",omitempty"` + TxSyncMaxTimeout time.Duration `toml:",omitempty"` // RangeLimit restricts the maximum range (end - start) for range queries. RangeLimit uint64 `toml:",omitempty"` diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 93d8cc57e7..6f94a409e5 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -61,13 +61,13 @@ func (c Config) MarshalTOML() (interface{}, error) { RPCGasCap uint64 RPCEVMTimeout time.Duration RPCTxFeeCap float64 - OverrideOsaka *uint64 `toml:",omitempty"` - OverrideBPO1 *uint64 `toml:",omitempty"` - OverrideBPO2 *uint64 `toml:",omitempty"` - OverrideVerkle *uint64 `toml:",omitempty"` - TxSyncDefaultTimeout uint64 `toml:",omitempty"` - TxSyncMaxTimeout uint64 `toml:",omitempty"` - RangeLimit uint64 `toml:",omitempty"` + OverrideOsaka *uint64 `toml:",omitempty"` + OverrideBPO1 *uint64 `toml:",omitempty"` + OverrideBPO2 *uint64 `toml:",omitempty"` + OverrideVerkle *uint64 `toml:",omitempty"` + TxSyncDefaultTimeout time.Duration `toml:",omitempty"` + TxSyncMaxTimeout time.Duration `toml:",omitempty"` + RangeLimit uint64 `toml:",omitempty"` } var enc Config enc.Genesis = c.Genesis @@ -171,13 +171,13 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { RPCGasCap *uint64 RPCEVMTimeout *time.Duration RPCTxFeeCap *float64 - OverrideOsaka *uint64 `toml:",omitempty"` - OverrideBPO1 *uint64 `toml:",omitempty"` - OverrideBPO2 *uint64 `toml:",omitempty"` - OverrideVerkle *uint64 `toml:",omitempty"` - TxSyncDefaultTimeout *uint64 `toml:",omitempty"` - TxSyncMaxTimeout *uint64 `toml:",omitempty"` - RangeLimit *uint64 `toml:",omitempty"` + OverrideOsaka *uint64 `toml:",omitempty"` + OverrideBPO1 *uint64 `toml:",omitempty"` + OverrideBPO2 *uint64 `toml:",omitempty"` + OverrideVerkle *uint64 `toml:",omitempty"` + TxSyncDefaultTimeout *time.Duration `toml:",omitempty"` + TxSyncMaxTimeout *time.Duration `toml:",omitempty"` + RangeLimit *uint64 `toml:",omitempty"` } var dec Config if err := unmarshal(&dec); err != nil { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index f81932e70f..e0baccbfe7 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1689,18 +1689,19 @@ func (api *TransactionAPI) SendRawTransactionSync(ctx context.Context, input hex } var ( - maxTimeoutMs = api.b.RPCTxSyncMaxTimeout() - defaultTimeoutMs = api.b.RPCTxSyncDefaultTimeout() - effectiveMs = defaultTimeoutMs + maxTimeout = api.b.RPCTxSyncMaxTimeout() + defaultTimeout = api.b.RPCTxSyncDefaultTimeout() + timeout = defaultTimeout ) if timeoutMs != nil && *timeoutMs > 0 { - if *timeoutMs > maxTimeoutMs { - effectiveMs = maxTimeoutMs + req := time.Duration(*timeoutMs) * time.Millisecond + if req > maxTimeout { + timeout = maxTimeout } else { - effectiveMs = *timeoutMs + timeout = req } } - receiptCtx, cancel := context.WithTimeout(ctx, time.Duration(effectiveMs)*time.Millisecond) + receiptCtx, cancel := context.WithTimeout(ctx, timeout) defer cancel() // Fast path. @@ -1715,10 +1716,7 @@ func (api *TransactionAPI) SendRawTransactionSync(ctx context.Context, input hex // If server-side wait window elapsed, return the structured timeout. if errors.Is(receiptCtx.Err(), context.DeadlineExceeded) { return nil, &txSyncTimeoutError{ - msg: fmt.Sprintf( - "The transaction was added to the transaction pool but wasn't processed in %v", - time.Duration(effectiveMs)*time.Millisecond, - ), + msg: fmt.Sprintf("The transaction was added to the transaction pool but wasn't processed in %v", timeout), hash: hash, } } diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 2179f9f7a0..3668bd0e14 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -447,8 +447,8 @@ type testBackend struct { sentTx *types.Transaction sentTxHash common.Hash - syncDefaultTimeout uint64 // in milliseconds - syncMaxTimeout uint64 // in milliseconds + syncDefaultTimeout time.Duration + syncMaxTimeout time.Duration } func fakeBlockHash(txh common.Hash) common.Hash { @@ -3949,20 +3949,20 @@ func (b configTimeBackend) CurrentHeader() *types.Header { return &types.Header{Time: b.time} } -func (b *testBackend) RPCTxSyncDefaultTimeout() uint64 { +func (b *testBackend) RPCTxSyncDefaultTimeout() time.Duration { if b.syncDefaultTimeout != 0 { return b.syncDefaultTimeout } - return 2000 // 2 seconds in milliseconds + return 2 * time.Second } -func (b *testBackend) RPCTxSyncMaxTimeout() uint64 { +func (b *testBackend) RPCTxSyncMaxTimeout() time.Duration { if b.syncMaxTimeout != 0 { return b.syncMaxTimeout } - return 300000 // 5 minutes in milliseconds + return 5 * time.Minute } -func (b *backendMock) RPCTxSyncDefaultTimeout() uint64 { return 2000 } // 2 seconds -func (b *backendMock) RPCTxSyncMaxTimeout() uint64 { return 300000 } // 5 minutes +func (b *backendMock) RPCTxSyncDefaultTimeout() time.Duration { return 2 * time.Second } +func (b *backendMock) RPCTxSyncMaxTimeout() time.Duration { return 5 * time.Minute } func makeSignedRaw(t *testing.T, api *TransactionAPI, from, to common.Address, value *big.Int) (hexutil.Bytes, *types.Transaction) { t.Helper() diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index 46f3067511..af3d592b82 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -49,12 +49,12 @@ type Backend interface { ChainDb() ethdb.Database AccountManager() *accounts.Manager ExtRPCEnabled() bool - 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. - RPCTxSyncDefaultTimeout() uint64 // default timeout for eth_sendRawTransactionSync in milliseconds - RPCTxSyncMaxTimeout() uint64 // maximum timeout for eth_sendRawTransactionSync in milliseconds + 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. + RPCTxSyncDefaultTimeout() time.Duration + RPCTxSyncMaxTimeout() time.Duration // Blockchain API SetHead(number uint64)