diff --git a/eth/gasestimator/gasestimator.go b/eth/gasestimator/gasestimator.go index f07f98956e..0625575bd2 100644 --- a/eth/gasestimator/gasestimator.go +++ b/eth/gasestimator/gasestimator.go @@ -49,17 +49,21 @@ type Options struct { // Estimate returns the lowest possible gas limit that allows the transaction to // run successfully with the provided context options. It returns an error if the // transaction would always revert, or if there are unexpected failures. -func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uint64) (uint64, []byte, error) { +func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uint64, blockGasLimit uint64) (uint64, []byte, error) { // Binary search the gas limit, as it may need to be higher than the amount used var ( lo uint64 // lowest-known gas limit where tx execution fails hi uint64 // lowest-known gas limit where tx execution succeeds ) + // Determine the highest gas limit can be used during the estimation. hi = opts.Header.GasLimit if call.GasLimit >= params.TxGas { hi = call.GasLimit } + if hi > blockGasLimit { + hi = blockGasLimit + } // Normalize the max fee per gas the call is willing to spend. var feeCap *big.Int if call.GasFeeCap != nil { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index d308cead62..67e0d394f5 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1202,9 +1202,19 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr if err := args.CallDefaults(gasCap, header.BaseFee, b.ChainConfig().ChainID); err != nil { return 0, err } + call := args.ToMessage(header.BaseFee) + + block, err := b.BlockByNumberOrHash(ctx, blockNrOrHash) + if err != nil { + return 0, err + } + if block == nil { + return 0, errors.New("block not found") + } // Run the gas estimation andwrap any revertals into a custom return - estimate, revert, err := gasestimator.Estimate(ctx, call, opts, gasCap) + estimate, revert, err := gasestimator.Estimate(ctx, call, opts, gasCap, block.GasLimit()) + if err != nil { if len(revert) > 0 { return 0, newRevertError(revert)