From b07b71f3ddb539fd5a77afc4064749f5f33ea21e Mon Sep 17 00:00:00 2001 From: Oren Date: Thu, 23 Nov 2023 10:59:29 +0200 Subject: [PATCH] Optimize gas estimation From my tests, it reduces the number of tx simulations for each gas estimation down from 16-18 to just 2 for most transactions (actually for all the transactions that I've tried). --- core/state_transition.go | 2 ++ internal/ethapi/api.go | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/core/state_transition.go b/core/state_transition.go index 612fdd7813..01fe81db47 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -35,6 +35,7 @@ type ExecutionResult struct { UsedGas uint64 // Total used gas but include the refunded gas Err error // Any error encountered during the execution(listed in core/vm/errors.go) ReturnData []byte // Returned data from evm(function result or data supplied with revert opcode) + GasRefund uint64 // Total gas refunded } // Unwrap returns the internal evm error which allows us for further @@ -445,6 +446,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { UsedGas: st.gasUsed(), Err: vmerr, ReturnData: ret, + GasRefund: st.state.GetRefund(), }, nil } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 38a7924124..2d29942383 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1279,6 +1279,14 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr } return 0, fmt.Errorf("gas required exceeds allowance (%d)", hi) } + + // Optimization: if the transaction succeeded with gasLimit set to the first execution's + // usedGas + gasRefund, then return that value immediately. Else, continue with the binary search. + _, _, err = executeEstimate(ctx, b, args, state.Copy(), header, gasCap, result.UsedGas + result.GasRefund) + if err == nil { + return hexutil.Uint64(result.UsedGas + result.GasRefund), nil + } + // For almost any transaction, the gas consumed by the unconstrained execution above // lower-bounds the gas limit required for it to succeed. One exception is those txs that // explicitly check gas remaining in order to successfully execute within a given limit, but we