forked from forks/go-ethereum
core, eth/gasestimator: introduce MaxGasUsed for estimation (#31735)
This PR improves gas estimation for data-heavy transactions which hit the floor data gas cost.
This commit is contained in:
parent
86a492471a
commit
79807bc3b1
2 changed files with 17 additions and 11 deletions
|
|
@ -34,10 +34,10 @@ import (
|
|||
// ExecutionResult includes all output after executing given evm
|
||||
// message no matter the execution itself is successful or not.
|
||||
type ExecutionResult struct {
|
||||
UsedGas uint64 // Total used gas, not including the refunded gas
|
||||
RefundedGas uint64 // Total gas refunded after execution
|
||||
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)
|
||||
UsedGas uint64 // Total used gas, not including the refunded gas
|
||||
MaxUsedGas uint64 // Maximum gas consumed during execution, excluding gas refunds.
|
||||
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)
|
||||
}
|
||||
|
||||
// Unwrap returns the internal evm error which allows us for further
|
||||
|
|
@ -509,9 +509,12 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
ret, st.gasRemaining, vmerr = st.evm.Call(msg.From, st.to(), msg.Data, st.gasRemaining, value)
|
||||
}
|
||||
|
||||
// Record the gas used excluding gas refunds. This value represents the actual
|
||||
// gas allowance required to complete execution.
|
||||
peakGasUsed := st.gasUsed()
|
||||
|
||||
// Compute refund counter, capped to a refund quotient.
|
||||
gasRefund := st.calcRefund()
|
||||
st.gasRemaining += gasRefund
|
||||
st.gasRemaining += st.calcRefund()
|
||||
if rules.IsPrague {
|
||||
// After EIP-7623: Data-heavy transactions pay the floor gas.
|
||||
if st.gasUsed() < floorDataGas {
|
||||
|
|
@ -521,6 +524,9 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
t.OnGasChange(prev, st.gasRemaining, tracing.GasChangeTxDataFloor)
|
||||
}
|
||||
}
|
||||
if peakGasUsed < floorDataGas {
|
||||
peakGasUsed = floorDataGas
|
||||
}
|
||||
}
|
||||
st.returnGas()
|
||||
|
||||
|
|
@ -549,10 +555,10 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
|||
}
|
||||
|
||||
return &ExecutionResult{
|
||||
UsedGas: st.gasUsed(),
|
||||
RefundedGas: gasRefund,
|
||||
Err: vmerr,
|
||||
ReturnData: ret,
|
||||
UsedGas: st.gasUsed(),
|
||||
MaxUsedGas: peakGasUsed,
|
||||
Err: vmerr,
|
||||
ReturnData: ret,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin
|
|||
// There's a fairly high chance for the transaction to execute successfully
|
||||
// with gasLimit set to the first execution's usedGas + gasRefund. Explicitly
|
||||
// check that gas amount and use as a limit for the binary search.
|
||||
optimisticGasLimit := (result.UsedGas + result.RefundedGas + params.CallStipend) * 64 / 63
|
||||
optimisticGasLimit := (result.MaxUsedGas + params.CallStipend) * 64 / 63
|
||||
if optimisticGasLimit < hi {
|
||||
failed, _, err = execute(ctx, call, opts, optimisticGasLimit)
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Reference in a new issue