Skip to content

Commit 79807bc

Browse files
authored
core, eth/gasestimator: introduce MaxGasUsed for estimation (#31735)
This PR improves gas estimation for data-heavy transactions which hit the floor data gas cost.
1 parent 86a4924 commit 79807bc

File tree

2 files changed

+17
-11
lines changed

2 files changed

+17
-11
lines changed

core/state_transition.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ import (
3434
// ExecutionResult includes all output after executing given evm
3535
// message no matter the execution itself is successful or not.
3636
type ExecutionResult struct {
37-
UsedGas uint64 // Total used gas, not including the refunded gas
38-
RefundedGas uint64 // Total gas refunded after execution
39-
Err error // Any error encountered during the execution(listed in core/vm/errors.go)
40-
ReturnData []byte // Returned data from evm(function result or data supplied with revert opcode)
37+
UsedGas uint64 // Total used gas, not including the refunded gas
38+
MaxUsedGas uint64 // Maximum gas consumed during execution, excluding gas refunds.
39+
Err error // Any error encountered during the execution(listed in core/vm/errors.go)
40+
ReturnData []byte // Returned data from evm(function result or data supplied with revert opcode)
4141
}
4242

4343
// Unwrap returns the internal evm error which allows us for further
@@ -509,9 +509,12 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
509509
ret, st.gasRemaining, vmerr = st.evm.Call(msg.From, st.to(), msg.Data, st.gasRemaining, value)
510510
}
511511

512+
// Record the gas used excluding gas refunds. This value represents the actual
513+
// gas allowance required to complete execution.
514+
peakGasUsed := st.gasUsed()
515+
512516
// Compute refund counter, capped to a refund quotient.
513-
gasRefund := st.calcRefund()
514-
st.gasRemaining += gasRefund
517+
st.gasRemaining += st.calcRefund()
515518
if rules.IsPrague {
516519
// After EIP-7623: Data-heavy transactions pay the floor gas.
517520
if st.gasUsed() < floorDataGas {
@@ -521,6 +524,9 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
521524
t.OnGasChange(prev, st.gasRemaining, tracing.GasChangeTxDataFloor)
522525
}
523526
}
527+
if peakGasUsed < floorDataGas {
528+
peakGasUsed = floorDataGas
529+
}
524530
}
525531
st.returnGas()
526532

@@ -549,10 +555,10 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
549555
}
550556

551557
return &ExecutionResult{
552-
UsedGas: st.gasUsed(),
553-
RefundedGas: gasRefund,
554-
Err: vmerr,
555-
ReturnData: ret,
558+
UsedGas: st.gasUsed(),
559+
MaxUsedGas: peakGasUsed,
560+
Err: vmerr,
561+
ReturnData: ret,
556562
}, nil
557563
}
558564

eth/gasestimator/gasestimator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin
144144
// There's a fairly high chance for the transaction to execute successfully
145145
// with gasLimit set to the first execution's usedGas + gasRefund. Explicitly
146146
// check that gas amount and use as a limit for the binary search.
147-
optimisticGasLimit := (result.UsedGas + result.RefundedGas + params.CallStipend) * 64 / 63
147+
optimisticGasLimit := (result.MaxUsedGas + params.CallStipend) * 64 / 63
148148
if optimisticGasLimit < hi {
149149
failed, _, err = execute(ctx, call, opts, optimisticGasLimit)
150150
if err != nil {

0 commit comments

Comments
 (0)