Skip to content

Double check gas tracing with EIP-8037 #20086

Description

@yperbasis

All state gas changes use tracing.GasChangeIgnored (interpreter.go:434, operations_acl.go:390). This means tracers (debug_traceTransaction, etc.) cannot see state gas consumption. May
need a new GasChangeReason for observability. Question: how does geth do it?

See also PR #20067.


Also, Claude's points about execution/vm/interpreter.go:
Issue: Tracing underflow for state-gas-bearing opcodes

For CREATE, CREATE2, and SSTORE (new slot), the dynamic gas function returns dynamicCost.State > 0, and the interpreter loop adds it to cost:

// line 471
cost += dynamicCost.State

But gasCopy (line 396) captures only regular gas:
gasCopy = callContext.gas // regular gas only

Then the tracing callback at line 482:
tracer.OnGasChange(gasCopy, gasCopy-cost, tracing.GasChangeCallOpCode)

Since cost = constantGas + dynamicCost.Regular + dynamicCost.State but gasCopy is regular-only, this underflows whenever dynamicCost.State > (gasCopy - constantGas - dynamicCost.Regular). That's easily
triggered: at 60M gas limit, a CREATE's state gas is 112 * 1174 ≈ 131k, and an SSTORE new-slot is 32 * 1174 ≈ 37.5k. If most of the transaction's gas is in the state reservoir (regular gas is modest), gasCopy -
cost wraps to a huge uint64 that the tracer sees as garbage.

The fix is straightforward: don't include dynamicCost.State in cost (it's documented as "for tracing"), or use a separate variable for the state dimension.


Minor observation: callGas tracing variable conflates dimensions too

// line 452
callGas = operation.constantGas + dynamicCost.Regular - evm.CallGasTemp()

This is fine for the traceGas helper (it only uses callGas for CALL variants, which have dynamicCost.State = 0). But traceGas returns cost for non-CALL opcodes (line 383-386), which again includes state gas for
CREATE/SSTORE. This affects the TraceDynamicGas debug output at line 453-454 — it would print inflated costs. Low severity since it's debug-only output.

Metadata

Metadata

Assignees

Labels

Glamsterdamhttps://eips.ethereum.org/EIPS/eip-7773

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions