Skip to content

core: fix EIP-7778 block gas accounting to exclude refunds#33754

Closed
qu0b wants to merge 1 commit intoethereum:bal-devnet-2from
qu0b:qu0b/fix/eip-7778-block-gas-accounting
Closed

core: fix EIP-7778 block gas accounting to exclude refunds#33754
qu0b wants to merge 1 commit intoethereum:bal-devnet-2from
qu0b:qu0b/fix/eip-7778-block-gas-accounting

Conversation

@qu0b
Copy link
Copy Markdown
Contributor

@qu0b qu0b commented Feb 4, 2026

Summary

  • Separates post-refund gas (for receipt CumulativeGasUsed) from pre-refund gas (for block header.GasUsed) in EIP-7778 (Block Gas Accounting Without Refunds)
  • ApplyTransactionWithEVM now returns (receipt, blockGasUsed, error) — receipt uses post-refund gas, blockGasUsed uses pre-refund for Amsterdam
  • All callers updated: state_processor, chain_makers, parallel_state_processor, miner/worker, t8ntool, simulate, tracers

Problem

EIP-7778 requires block-level gas to exclude refunds, but receipts must continue using post-refund CumulativeGasUsed. The previous code used a single gas value for both purposes, causing:

  1. Miner's header.GasUsed (post-refund) diverging from validator's expected value (pre-refund), rejecting all refund-heavy blocks
  2. Receipt root hash mismatches with other clients (e.g., Besu) since CumulativeGasUsed was incorrectly set to pre-refund gas

Test plan

  • Built fixed geth image and ran local Kurtosis devnet (lighthouse+geth supernode, lodestar+besu×2)
  • Verified geth and besu agree on block hashes through 120+ slots with spamoor transactions (evm-fuzz, eoatx, uniswap-swaps)
  • No invalid gas used or receipt root hash mismatch errors after Gloas fork
  • Both EL clients in sync at identical block heights throughout the test

🤖 Generated with Claude Code

@qu0b qu0b requested a review from rjl493456442 as a code owner February 4, 2026 11:22
@qu0b qu0b force-pushed the qu0b/fix/eip-7778-block-gas-accounting branch from 95334ea to 514bde1 Compare February 4, 2026 11:24
@qu0b qu0b requested review from fjl, lightclient and s1na as code owners February 4, 2026 11:24
EIP-7778 requires block-level gas accounting to exclude refunds, but
receipts must continue using post-refund CumulativeGasUsed. The previous
code used a single gas value for both purposes, causing:
1. Miner's header.GasUsed (post-refund) diverging from validator's
   expected value (pre-refund), rejecting all refund-heavy blocks.
2. Receipt root hash mismatches with other clients (e.g., Besu) since
   CumulativeGasUsed was incorrectly set to pre-refund gas.

Fix by returning two gas values from ApplyTransactionWithEVM:
- receipt: contains post-refund CumulativeGasUsed (unchanged behavior)
- blockGasUsed: pre-refund gas for Amsterdam, post-refund otherwise

All callers updated: state_processor, chain_makers, parallel processor,
miner/worker, t8ntool, simulate, tracers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@qu0b qu0b force-pushed the qu0b/fix/eip-7778-block-gas-accounting branch from 514bde1 to b6c983d Compare February 4, 2026 13:04
snapshot = statedb.Snapshot()
prevGas = gaspool.Gas()
)
receipt, err := core.ApplyTransactionWithEVM(msg, gaspool, statedb, vmContext.BlockNumber, blockHash, pre.Env.Timestamp, tx, &gasUsed, evm)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The receipt.GasUsed contains the gas used as it counts towards the block gas limit (the gas charged to the account + any gas that was returned via refunds). Thus, I think there's no need to return this value separately and we can simplify the fix that this PR makes.

Going to try to see if I can make the fix accordingly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to close this PR if you have a better solution, but please keep in mind: ethereum/EIPs#11191

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no. I'm wrong receipt.GasUsed subtracts refunds.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the issue right now is afaik is in the block building. On the verification side, Geth seems to be correct (we pass all the tests for 7778). This PR does fix other spots (chain makers, t8n), and we want to incorporate a fix into those areas.

@jwasinger
Copy link
Copy Markdown
Contributor

I think we can make this fix in a way that decreases the size of the diff: include the block gas used in the Receipt type. It already contains non-consensus fields so we can include it there.

@jwasinger
Copy link
Copy Markdown
Contributor

I'm gonna go with #33761 . Thanks for this, but I feel like the other PR is a simpler and cleaner solution.

@jwasinger jwasinger closed this Feb 4, 2026
jwasinger added a commit that referenced this pull request Feb 4, 2026
alternative to #33754

Adds an extra non-consensus field on the `Receipt`: `BlockGasUsed`. This
reflects the gas used as it counts towards the block gas limit, whereas
the existing field `GasUsed` is the consensus field: the gas used with
refunds subtracted.

Changes an incorrect comment describing the field
`ExecutionResult.UsedGas`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants