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
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
}

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)
}
// 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