Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ 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 but include the refunded gas
UsedGas uint64 // Total used gas, refunded gas is deducted
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)
}
Expand Down Expand Up @@ -478,9 +479,13 @@ func (st *stateTransition) execute(owner common.Address) (*ExecutionResult, erro
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 {
Expand All @@ -490,6 +495,9 @@ func (st *stateTransition) execute(owner common.Address) (*ExecutionResult, erro
t.OnGasChange(prev, st.gasRemaining, tracing.GasChangeTxDataFloor)
}
}
if peakGasUsed < floorDataGas {
peakGasUsed = floorDataGas
}
}
st.returnGas()

Expand All @@ -514,6 +522,7 @@ func (st *stateTransition) execute(owner common.Address) (*ExecutionResult, erro

return &ExecutionResult{
UsedGas: st.gasUsed(),
MaxUsedGas: peakGasUsed,
Err: vmerr,
ReturnData: ret,
}, nil
Expand Down
2 changes: 2 additions & 0 deletions ethclient/ethclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -833,13 +833,15 @@ type SimulateCallResult struct {
ReturnValue []byte `json:"returnData"`
Logs []*types.Log `json:"logs"`
GasUsed uint64 `json:"gasUsed"`
MaxUsedGas uint64 `json:"maxUsedGas"`
Status uint64 `json:"status"`
Error *CallError `json:"error,omitempty"`
}

type simulateCallResultMarshaling struct {
ReturnValue hexutil.Bytes
GasUsed hexutil.Uint64
MaxUsedGas hexutil.Uint64
Status hexutil.Uint64
}

Expand Down
6 changes: 6 additions & 0 deletions ethclient/ethclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,12 @@ func TestSimulateV1(t *testing.T) {
if results[0].Calls[0].Error != nil {
t.Errorf("expected no error, got %v", results[0].Calls[0].Error)
}
if results[0].Calls[0].MaxUsedGas == 0 {
t.Error("expected maxUsedGas to be set")
}
if results[0].Calls[0].MaxUsedGas < results[0].Calls[0].GasUsed {
t.Errorf("expected maxUsedGas >= gasUsed, got %d < %d", results[0].Calls[0].MaxUsedGas, results[0].Calls[0].GasUsed)
}
}

// TestSimulateV1WithBlockOverrides tests simulate v 1 with block overrides.
Expand Down
6 changes: 6 additions & 0 deletions ethclient/gen_simulate_call_result.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion internal/ethapi/simulate.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type simCallResult struct {
ReturnValue hexutil.Bytes `json:"returnData"`
Logs []*types.Log `json:"logs"`
GasUsed hexutil.Uint64 `json:"gasUsed"`
MaxUsedGas hexutil.Uint64 `json:"maxUsedGas"`
Status hexutil.Uint64 `json:"status"`
Comment thread
gzliudan marked this conversation as resolved.
Error *callError `json:"error,omitempty"`
}
Expand Down Expand Up @@ -225,7 +226,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
gasUsed += result.UsedGas
receipts[i] = core.MakeReceipt(evm, result, sim.state, blockContext.BlockNumber, common.Hash{}, tx, gasUsed, root)
logs := tracer.Logs()
callRes := simCallResult{ReturnValue: result.Return(), Logs: logs, GasUsed: hexutil.Uint64(result.UsedGas)}
callRes := simCallResult{ReturnValue: result.Return(), Logs: logs, GasUsed: hexutil.Uint64(result.UsedGas), MaxUsedGas: hexutil.Uint64(result.MaxUsedGas)}
if result.Failed() {
callRes.Status = hexutil.Uint64(types.ReceiptStatusFailed)
if errors.Is(result.Err, vm.ErrExecutionReverted) {
Expand Down
Loading