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).
This commit is contained in:
Oren 2023-11-23 10:59:29 +02:00
parent eec37e3b71
commit b07b71f3dd
2 changed files with 10 additions and 0 deletions

View file

@ -35,6 +35,7 @@ type ExecutionResult struct {
UsedGas uint64 // Total used gas but include the refunded gas UsedGas uint64 // Total used gas but include the refunded gas
Err error // Any error encountered during the execution(listed in core/vm/errors.go) 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) 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 // Unwrap returns the internal evm error which allows us for further
@ -445,6 +446,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
UsedGas: st.gasUsed(), UsedGas: st.gasUsed(),
Err: vmerr, Err: vmerr,
ReturnData: ret, ReturnData: ret,
GasRefund: st.state.GetRefund(),
}, nil }, nil
} }

View file

@ -1279,6 +1279,14 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr
} }
return 0, fmt.Errorf("gas required exceeds allowance (%d)", hi) 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 // 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 // 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 // explicitly check gas remaining in order to successfully execute within a given limit, but we