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
|
// ExecutionResult includes all output after executing given evm
|
||||||
// message no matter the execution itself is successful or not.
|
// message no matter the execution itself is successful or not.
|
||||||
type ExecutionResult struct {
|
type ExecutionResult struct {
|
||||||
UsedGas uint64 // Total used gas, not including the refunded gas
|
UsedGas uint64 // Total used gas, not including the refunded gas
|
||||||
RefundedGas uint64 // Total gas refunded after execution
|
MaxUsedGas uint64 // Maximum gas consumed during execution, excluding gas refunds.
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unwrap returns the internal evm error which allows us for further
|
// 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)
|
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.
|
// Compute refund counter, capped to a refund quotient.
|
||||||
gasRefund := st.calcRefund()
|
st.gasRemaining += st.calcRefund()
|
||||||
st.gasRemaining += gasRefund
|
|
||||||
if rules.IsPrague {
|
if rules.IsPrague {
|
||||||
// After EIP-7623: Data-heavy transactions pay the floor gas.
|
// After EIP-7623: Data-heavy transactions pay the floor gas.
|
||||||
if st.gasUsed() < floorDataGas {
|
if st.gasUsed() < floorDataGas {
|
||||||
|
|
@ -521,6 +524,9 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
||||||
t.OnGasChange(prev, st.gasRemaining, tracing.GasChangeTxDataFloor)
|
t.OnGasChange(prev, st.gasRemaining, tracing.GasChangeTxDataFloor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if peakGasUsed < floorDataGas {
|
||||||
|
peakGasUsed = floorDataGas
|
||||||
|
}
|
||||||
}
|
}
|
||||||
st.returnGas()
|
st.returnGas()
|
||||||
|
|
||||||
|
|
@ -549,10 +555,10 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ExecutionResult{
|
return &ExecutionResult{
|
||||||
UsedGas: st.gasUsed(),
|
UsedGas: st.gasUsed(),
|
||||||
RefundedGas: gasRefund,
|
MaxUsedGas: peakGasUsed,
|
||||||
Err: vmerr,
|
Err: vmerr,
|
||||||
ReturnData: ret,
|
ReturnData: ret,
|
||||||
}, nil
|
}, 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
|
// There's a fairly high chance for the transaction to execute successfully
|
||||||
// with gasLimit set to the first execution's usedGas + gasRefund. Explicitly
|
// with gasLimit set to the first execution's usedGas + gasRefund. Explicitly
|
||||||
// check that gas amount and use as a limit for the binary search.
|
// 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 {
|
if optimisticGasLimit < hi {
|
||||||
failed, _, err = execute(ctx, call, opts, optimisticGasLimit)
|
failed, _, err = execute(ctx, call, opts, optimisticGasLimit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue