From 59405c40d394552f1915caedd5f43d971c7ba1fd Mon Sep 17 00:00:00 2001 From: Minhyuk Kim Date: Tue, 5 Aug 2025 20:51:16 +0900 Subject: [PATCH] eth/gasestimator: check ErrGasLimitTooHigh conditions (#32348) This PR makes 2 changes to how [EIP-7825](https://github.com/ethereum/go-ethereum/pull/31824) behaves. When `eth_estimateGas` or `eth_createAccessList` is called without any gas limit in the payload, geth will choose the block's gas limit or the `RPCGasCap`, which can be larger than the `maxTxGas`. When this happens for `estimateGas`, the gas estimation just errors out and ends, when it should continue doing binary search to find the lowest possible gas limit. This PR will: - Add a check to see if `hi` is larger than `maxTxGas` and cap it to `maxTxGas` if it's larger. And add a special case handling for gas estimation execute when it errs with `ErrGasLimitTooHigh` --------- Co-authored-by: Gary Rong --- eth/gasestimator/gasestimator.go | 20 ++++++++++++++++++++ internal/ethapi/override/override_test.go | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/eth/gasestimator/gasestimator.go b/eth/gasestimator/gasestimator.go index 7e9d8125de..6e79fbd62b 100644 --- a/eth/gasestimator/gasestimator.go +++ b/eth/gasestimator/gasestimator.go @@ -62,6 +62,23 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin if call.GasLimit >= params.TxGas { hi = call.GasLimit } + + // Cap the maximum gas allowance according to EIP-7825 if the estimation targets Osaka + if hi > params.MaxTxGas { + blockNumber, blockTime := opts.Header.Number, opts.Header.Time + if opts.BlockOverrides != nil { + if opts.BlockOverrides.Number != nil { + blockNumber = opts.BlockOverrides.Number.ToInt() + } + if opts.BlockOverrides.Time != nil { + blockTime = uint64(*opts.BlockOverrides.Time) + } + } + if opts.Config.IsOsaka(blockNumber, blockTime) { + hi = params.MaxTxGas + } + } + // Normalize the max fee per gas the call is willing to spend. var feeCap *big.Int if call.GasFeeCap != nil { @@ -209,6 +226,9 @@ func execute(ctx context.Context, call *core.Message, opts *Options, gasLimit ui if errors.Is(err, core.ErrIntrinsicGas) { return true, nil, nil // Special case, raise gas limit } + if errors.Is(err, core.ErrGasLimitTooHigh) { + return true, nil, nil // Special case, lower gas limit + } return true, nil, err // Bail out } return result.Failed(), result, nil diff --git a/internal/ethapi/override/override_test.go b/internal/ethapi/override/override_test.go index 02a17c1331..41b4f2c253 100644 --- a/internal/ethapi/override/override_test.go +++ b/internal/ethapi/override/override_test.go @@ -31,6 +31,10 @@ import ( type precompileContract struct{} +func (p *precompileContract) Name() string { + panic("implement me") +} + func (p *precompileContract) RequiredGas(input []byte) uint64 { return 0 } func (p *precompileContract) Run(input []byte) ([]byte, error) { return nil, nil }