ethapi: add int refactor to backend for eth_sendRawTransactionSync

This commit is contained in:
Milan Saxena 2026-01-28 08:30:43 -08:00
parent 81a65831c4
commit 9bd3cf68da
No known key found for this signature in database
GPG key ID: 58D0249392334E42
7 changed files with 46 additions and 44 deletions

View file

@ -639,13 +639,13 @@ var (
RPCTxSyncDefaultTimeoutFlag = &cli.DurationFlag{ RPCTxSyncDefaultTimeoutFlag = &cli.DurationFlag{
Name: "rpc.txsync.defaulttimeout", Name: "rpc.txsync.defaulttimeout",
Usage: "Default timeout for eth_sendRawTransactionSync (e.g. 2s, 500ms)", Usage: "Default timeout for eth_sendRawTransactionSync (e.g. 2s, 500ms)",
Value: ethconfig.Defaults.TxSyncDefaultTimeout, Value: time.Duration(ethconfig.Defaults.TxSyncDefaultTimeout) * time.Millisecond,
Category: flags.APICategory, Category: flags.APICategory,
} }
RPCTxSyncMaxTimeoutFlag = &cli.DurationFlag{ RPCTxSyncMaxTimeoutFlag = &cli.DurationFlag{
Name: "rpc.txsync.maxtimeout", Name: "rpc.txsync.maxtimeout",
Usage: "Maximum allowed timeout for eth_sendRawTransactionSync (e.g. 5m)", Usage: "Maximum allowed timeout for eth_sendRawTransactionSync (e.g. 5m)",
Value: ethconfig.Defaults.TxSyncMaxTimeout, Value: time.Duration(ethconfig.Defaults.TxSyncMaxTimeout) * time.Millisecond,
Category: flags.APICategory, Category: flags.APICategory,
} }
RPCGlobalRangeLimitFlag = &cli.Uint64Flag{ RPCGlobalRangeLimitFlag = &cli.Uint64Flag{
@ -1772,10 +1772,10 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
cfg.LogQueryLimit = ctx.Int(RPCGlobalLogQueryLimit.Name) cfg.LogQueryLimit = ctx.Int(RPCGlobalLogQueryLimit.Name)
} }
if ctx.IsSet(RPCTxSyncDefaultTimeoutFlag.Name) { if ctx.IsSet(RPCTxSyncDefaultTimeoutFlag.Name) {
cfg.TxSyncDefaultTimeout = ctx.Duration(RPCTxSyncDefaultTimeoutFlag.Name) cfg.TxSyncDefaultTimeout = uint64(ctx.Duration(RPCTxSyncDefaultTimeoutFlag.Name).Milliseconds())
} }
if ctx.IsSet(RPCTxSyncMaxTimeoutFlag.Name) { if ctx.IsSet(RPCTxSyncMaxTimeoutFlag.Name) {
cfg.TxSyncMaxTimeout = ctx.Duration(RPCTxSyncMaxTimeoutFlag.Name) cfg.TxSyncMaxTimeout = uint64(ctx.Duration(RPCTxSyncMaxTimeoutFlag.Name).Milliseconds())
} }
if ctx.IsSet(RPCGlobalRangeLimitFlag.Name) { if ctx.IsSet(RPCGlobalRangeLimitFlag.Name) {
cfg.RangeLimit = ctx.Uint64(RPCGlobalRangeLimitFlag.Name) cfg.RangeLimit = ctx.Uint64(RPCGlobalRangeLimitFlag.Name)

View file

@ -492,10 +492,10 @@ func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Blo
return b.eth.stateAtTransaction(ctx, block, txIndex, reexec) return b.eth.stateAtTransaction(ctx, block, txIndex, reexec)
} }
func (b *EthAPIBackend) RPCTxSyncDefaultTimeout() time.Duration { func (b *EthAPIBackend) RPCTxSyncDefaultTimeout() uint64 {
return b.eth.config.TxSyncDefaultTimeout return b.eth.config.TxSyncDefaultTimeout
} }
func (b *EthAPIBackend) RPCTxSyncMaxTimeout() time.Duration { func (b *EthAPIBackend) RPCTxSyncMaxTimeout() uint64 {
return b.eth.config.TxSyncMaxTimeout return b.eth.config.TxSyncMaxTimeout
} }

View file

@ -72,9 +72,9 @@ var Defaults = Config{
RPCGasCap: 50000000, RPCGasCap: 50000000,
RPCEVMTimeout: 5 * time.Second, RPCEVMTimeout: 5 * time.Second,
GPO: FullNodeGPO, GPO: FullNodeGPO,
RPCTxFeeCap: 1, // 1 ether RPCTxFeeCap: 1, // 1 ether
TxSyncDefaultTimeout: 20 * time.Second, TxSyncDefaultTimeout: uint64(20000), // 20 seconds in milliseconds
TxSyncMaxTimeout: 1 * time.Minute, TxSyncMaxTimeout: uint64(60000), // 1 minute in milliseconds
SlowBlockThreshold: time.Second * 2, SlowBlockThreshold: time.Second * 2,
RangeLimit: 0, RangeLimit: 0,
} }
@ -203,8 +203,8 @@ type Config struct {
OverrideVerkle *uint64 `toml:",omitempty"` OverrideVerkle *uint64 `toml:",omitempty"`
// EIP-7966: eth_sendRawTransactionSync timeouts // EIP-7966: eth_sendRawTransactionSync timeouts
TxSyncDefaultTimeout time.Duration `toml:",omitempty"` TxSyncDefaultTimeout uint64 `toml:",omitempty"`
TxSyncMaxTimeout time.Duration `toml:",omitempty"` TxSyncMaxTimeout uint64 `toml:",omitempty"`
// RangeLimit restricts the maximum range (end - start) for range queries. // RangeLimit restricts the maximum range (end - start) for range queries.
RangeLimit uint64 `toml:",omitempty"` RangeLimit uint64 `toml:",omitempty"`

View file

@ -61,13 +61,13 @@ func (c Config) MarshalTOML() (interface{}, error) {
RPCGasCap uint64 RPCGasCap uint64
RPCEVMTimeout time.Duration RPCEVMTimeout time.Duration
RPCTxFeeCap float64 RPCTxFeeCap float64
OverrideOsaka *uint64 `toml:",omitempty"` OverrideOsaka *uint64 `toml:",omitempty"`
OverrideBPO1 *uint64 `toml:",omitempty"` OverrideBPO1 *uint64 `toml:",omitempty"`
OverrideBPO2 *uint64 `toml:",omitempty"` OverrideBPO2 *uint64 `toml:",omitempty"`
OverrideVerkle *uint64 `toml:",omitempty"` OverrideVerkle *uint64 `toml:",omitempty"`
TxSyncDefaultTimeout time.Duration `toml:",omitempty"` TxSyncDefaultTimeout uint64 `toml:",omitempty"`
TxSyncMaxTimeout time.Duration `toml:",omitempty"` TxSyncMaxTimeout uint64 `toml:",omitempty"`
RangeLimit uint64 `toml:",omitempty"` RangeLimit uint64 `toml:",omitempty"`
} }
var enc Config var enc Config
enc.Genesis = c.Genesis enc.Genesis = c.Genesis
@ -171,13 +171,13 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error {
RPCGasCap *uint64 RPCGasCap *uint64
RPCEVMTimeout *time.Duration RPCEVMTimeout *time.Duration
RPCTxFeeCap *float64 RPCTxFeeCap *float64
OverrideOsaka *uint64 `toml:",omitempty"` OverrideOsaka *uint64 `toml:",omitempty"`
OverrideBPO1 *uint64 `toml:",omitempty"` OverrideBPO1 *uint64 `toml:",omitempty"`
OverrideBPO2 *uint64 `toml:",omitempty"` OverrideBPO2 *uint64 `toml:",omitempty"`
OverrideVerkle *uint64 `toml:",omitempty"` OverrideVerkle *uint64 `toml:",omitempty"`
TxSyncDefaultTimeout *time.Duration `toml:",omitempty"` TxSyncDefaultTimeout *uint64 `toml:",omitempty"`
TxSyncMaxTimeout *time.Duration `toml:",omitempty"` TxSyncMaxTimeout *uint64 `toml:",omitempty"`
RangeLimit *uint64 `toml:",omitempty"` RangeLimit *uint64 `toml:",omitempty"`
} }
var dec Config var dec Config
if err := unmarshal(&dec); err != nil { if err := unmarshal(&dec); err != nil {

View file

@ -1689,19 +1689,18 @@ func (api *TransactionAPI) SendRawTransactionSync(ctx context.Context, input hex
} }
var ( var (
maxTimeout = api.b.RPCTxSyncMaxTimeout() maxTimeoutMs = api.b.RPCTxSyncMaxTimeout()
defaultTimeout = api.b.RPCTxSyncDefaultTimeout() defaultTimeoutMs = api.b.RPCTxSyncDefaultTimeout()
timeout = defaultTimeout effectiveMs = defaultTimeoutMs
) )
if timeoutMs != nil && *timeoutMs > 0 { if timeoutMs != nil && *timeoutMs > 0 {
req := time.Duration(*timeoutMs) * time.Millisecond if *timeoutMs > maxTimeoutMs {
if req > maxTimeout { effectiveMs = maxTimeoutMs
timeout = maxTimeout
} else { } else {
timeout = req effectiveMs = *timeoutMs
} }
} }
receiptCtx, cancel := context.WithTimeout(ctx, timeout) receiptCtx, cancel := context.WithTimeout(ctx, time.Duration(effectiveMs)*time.Millisecond)
defer cancel() defer cancel()
// Fast path. // Fast path.
@ -1716,7 +1715,10 @@ func (api *TransactionAPI) SendRawTransactionSync(ctx context.Context, input hex
// If server-side wait window elapsed, return the structured timeout. // If server-side wait window elapsed, return the structured timeout.
if errors.Is(receiptCtx.Err(), context.DeadlineExceeded) { if errors.Is(receiptCtx.Err(), context.DeadlineExceeded) {
return nil, &txSyncTimeoutError{ return nil, &txSyncTimeoutError{
msg: fmt.Sprintf("The transaction was added to the transaction pool but wasn't processed in %v", timeout), msg: fmt.Sprintf(
"The transaction was added to the transaction pool but wasn't processed in %v",
time.Duration(effectiveMs)*time.Millisecond,
),
hash: hash, hash: hash,
} }
} }

View file

@ -447,8 +447,8 @@ type testBackend struct {
sentTx *types.Transaction sentTx *types.Transaction
sentTxHash common.Hash sentTxHash common.Hash
syncDefaultTimeout time.Duration syncDefaultTimeout uint64 // in milliseconds
syncMaxTimeout time.Duration syncMaxTimeout uint64 // in milliseconds
} }
func fakeBlockHash(txh common.Hash) common.Hash { func fakeBlockHash(txh common.Hash) common.Hash {
@ -3949,20 +3949,20 @@ func (b configTimeBackend) CurrentHeader() *types.Header {
return &types.Header{Time: b.time} return &types.Header{Time: b.time}
} }
func (b *testBackend) RPCTxSyncDefaultTimeout() time.Duration { func (b *testBackend) RPCTxSyncDefaultTimeout() uint64 {
if b.syncDefaultTimeout != 0 { if b.syncDefaultTimeout != 0 {
return b.syncDefaultTimeout return b.syncDefaultTimeout
} }
return 2 * time.Second return 2000 // 2 seconds in milliseconds
} }
func (b *testBackend) RPCTxSyncMaxTimeout() time.Duration { func (b *testBackend) RPCTxSyncMaxTimeout() uint64 {
if b.syncMaxTimeout != 0 { if b.syncMaxTimeout != 0 {
return b.syncMaxTimeout return b.syncMaxTimeout
} }
return 5 * time.Minute return 300000 // 5 minutes in milliseconds
} }
func (b *backendMock) RPCTxSyncDefaultTimeout() time.Duration { return 2 * time.Second } func (b *backendMock) RPCTxSyncDefaultTimeout() uint64 { return 2000 } // 2 seconds
func (b *backendMock) RPCTxSyncMaxTimeout() time.Duration { return 5 * time.Minute } func (b *backendMock) RPCTxSyncMaxTimeout() uint64 { return 300000 } // 5 minutes
func makeSignedRaw(t *testing.T, api *TransactionAPI, from, to common.Address, value *big.Int) (hexutil.Bytes, *types.Transaction) { func makeSignedRaw(t *testing.T, api *TransactionAPI, from, to common.Address, value *big.Int) (hexutil.Bytes, *types.Transaction) {
t.Helper() t.Helper()

View file

@ -53,8 +53,8 @@ type Backend interface {
RPCEVMTimeout() time.Duration // global timeout 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 RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs
UnprotectedAllowed() bool // allows only for EIP155 transactions. UnprotectedAllowed() bool // allows only for EIP155 transactions.
RPCTxSyncDefaultTimeout() time.Duration RPCTxSyncDefaultTimeout() uint64 // default timeout for eth_sendRawTransactionSync in milliseconds
RPCTxSyncMaxTimeout() time.Duration RPCTxSyncMaxTimeout() uint64 // maximum timeout for eth_sendRawTransactionSync in milliseconds
// Blockchain API // Blockchain API
SetHead(number uint64) SetHead(number uint64)