Skip to content

test(tip1016): add e2e tests for gas estimation, payload packing, pool rejection, and EIP-7702 delegation pricing#3371

Open
fgimenez wants to merge 48 commits intotip1016from
fgimenez/tip1016-e2e
Open

test(tip1016): add e2e tests for gas estimation, payload packing, pool rejection, and EIP-7702 delegation pricing#3371
fgimenez wants to merge 48 commits intotip1016from
fgimenez/tip1016-e2e

Conversation

@fgimenez
Copy link
Copy Markdown
Member

Adds 8 integration tests covering TIP-1016 gaps not addressed by upstream EIP-8037 tests or the existing PR #2684 tests. All tests are Tempo-specific and adaptive to both T2 (no state gas split) and T3 (state gas active).

  • eth_estimateGas returns total gas (exec + state), not just execution gas
  • Payload builder packs blocks by regular gas, preventing under-packing when txs have high state gas
  • Dual lane gas accounting uses regular gas for capacity checks
  • Pool rejects Tempo txs with gas_limit below intrinsic total (exec + state)
  • EIP-7702 KeyAuthorization to new account accepted and included with correct delegation pricing
  • 24KB contract deployment verifies state gas exemption for large code deposits
  • GAS opcode returns execution gas only, excluding state reservoir
  • SSTORE zero->nonzero->zero refund produces minimal net state gas

rakita and others added 30 commits March 27, 2026 16:40
Bump dependencies to EIP-8037 (State Gas Reservoir Model) branches:
- reth: 2a94eed → ff2f857e (eip8037 branch)
- revm: patched via local path at 3a29466d (rakita/state-gas branch)
- alloy-evm: patched to a8da352a (eip8037 branch)
- revm-inspectors: patched to 50676ae7 (eip8037 branch)

Adapt to API changes: PrecompileOutput now uses GasTracker instead of
gas_used/gas_refunded fields, PrecompileResult error type changed to
PrecompileFailure, InitialAndFloorGas.initial_gas renamed to
initial_total_gas, Handler trait methods gained EIP-8037 parameters,
ResultGas removed with_limit(), and commit_transaction returns GasOutput.
Let `?` auto-convert via `From<PrecompileError> for PrecompileFailure`
instead of wrapping explicitly with `PrecompileFailure::from(...)`.
Remove serde-bincode-compat features and RlpBincode impls removed
upstream, drop redundant SignedTransaction/InMemorySize impls now
covered by blanket impls, and migrate spent() to total_gas_spent()
for EIP-8037.
Bump dependencies to EIP-8037 (State Gas Reservoir Model) branches:
- reth: 2a94eed → ff2f857e (eip8037 branch)
- revm: patched via local path at 3a29466d (rakita/state-gas branch)
- alloy-evm: patched to a8da352a (eip8037 branch)
- revm-inspectors: patched to 50676ae7 (eip8037 branch)

Adapt to API changes: PrecompileOutput now uses GasTracker instead of
gas_used/gas_refunded fields, PrecompileResult error type changed to
PrecompileFailure, InitialAndFloorGas.initial_gas renamed to
initial_total_gas, Handler trait methods gained EIP-8037 parameters,
ResultGas removed with_limit(), and commit_transaction returns GasOutput.
Bump dependencies to EIP-8037 (State Gas Reservoir Model) branches:
- reth: 2a94eed → ff2f857e (eip8037 branch)
- revm: patched via local path at 3a29466d (rakita/state-gas branch)
- alloy-evm: patched to a8da352a (eip8037 branch)
- revm-inspectors: patched to 50676ae7 (eip8037 branch)

Adapt to API changes: PrecompileOutput now uses GasTracker instead of
gas_used/gas_refunded fields, PrecompileResult error type changed to
PrecompileFailure, InitialAndFloorGas.initial_gas renamed to
initial_total_gas, Handler trait methods gained EIP-8037 parameters,
ResultGas removed with_limit(), and commit_transaction returns GasOutput.
…(TIP-1016) (#2734)

Closes CHAIN-791

Adds block-level plumbing to track execution gas and storage creation
gas separately in `TempoBlockExecutor`.

- Added `cumulative_full_gas_used` and `cumulative_storage_creation_gas`
fields to `TempoBlockExecutor`
- `commit_transaction` now computes `execution_gas = full_gas -
storage_creation_gas` and only execution gas counts toward block gas
limits (`non_shared_gas_left`, `non_payment_gas_left`)
- Receipts and `cumulative_full_gas_used` continue to track full gas
(execution + storage creation)
- `finish()` returns execution gas (not full gas) for the block header
gas field
- `storage_creation_gas` is hardcoded to `0` with a TODO — it will be
populated once handler-level tracking lands (CHAIN-789 / PR #2714)

Note: hardfork gating is not required. With `storage_creation_gas = 0`,
all gas accounting is identical to the current behavior. The hardfork
gate (T2) lives in the handler layer, not here. This is pure plumbing
that becomes active only when upstream EVM tracking is enabled.
… (TIP-1016) (#2714)

Closes CHAIN-789

Introduces state gas tracking in the EVM handler for the T2 hardfork.
State gas separates the cost of state-touching operations (account
creation, contract deployment) from execution gas, enabling the
reservoir model and tx cap bypass for state-heavy transactions.

`crates/evm/src/lib.rs`:
- Set `cfg_env.enable_state_gas = spec.is_t2()` in both `evm_env` and
`next_evm_env`

`crates/revm/src/handler.rs`
- `adjusted_initial_gas`: propagate `initial_state_gas` through
`InitialAndFloorGas::new_with_state_gas`
- `calculate_aa_batch_intrinsic_gas`: track `new_account_state_gas +
create_state_gas` for AA CREATE calls
- Multi-call gas reconstruction: use flattened `Gas::new_spent` +
`erase_cost` pattern (robust under EIP-8037 reservoir model) and
accumulate `state_gas_spent` across calls
- Tx gas limit cap bypass: upstream revm already skips the cap check
when `enable_state_gas` is true
- `reimburse_caller`: no changes needed — `gas.used()` already includes
state gas through the reservoir flattening in `last_frame_result`
Co-authored-by: rakita <rakita@users.noreply.github.com>
…or of inner executor's block_regular_gas_used
Root cause: In the new revm, initial_total_gas must include initial_state_gas.
Tempo's nonce==0 and auth list gas additions were adding the execution portion
(e.g. 5000) to initial_total_gas but a much larger state portion (e.g. 245000)
to initial_state_gas, violating the invariant.

Fix: Add both execution + state portions to initial_total_gas when adding state
gas, maintaining initial_total_gas >= initial_state_gas.

Also fix adjusted_initial_gas to not double-count state gas since evm_initial_gas
already includes init_and_floor_gas.initial_state_gas in the new revm.

- Fix nonce==0 gas additions in validate_initial_tx_gas and AA batch path
- Fix auth list gas additions
- Fix validation check (total already includes state)
- Increase tip20 test gas limit for higher intrinsic gas
@fgimenez fgimenez requested a review from rakita March 30, 2026 15:01
@fgimenez fgimenez added the C-test A change that impacts how or what we test label Mar 30, 2026
@fgimenez fgimenez force-pushed the fgimenez/tip1016-e2e branch from 2121acc to fecd01c Compare March 30, 2026 16:46
// two full SSTOREs (2 x 250k = 500k). The refund should bring the net cost
// close to just the warm access cost.
assert!(
receipts_total_gas < 500_000,
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.

Would be good to use exact value.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yep done

.expect("receipts should be available");
let user_receipt = receipts
.iter()
.find(|r| r.gas_used > 21_000)
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.

Exact value

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

Comment on lines +1573 to +1574
assert!(before > 0, "gasleft_before should be non-zero");
assert!(after > 0, "gasleft_after should be non-zero");
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.

This is not that valuable to have

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

agree, removed

Comment on lines +1588 to +1614
// On T3 (TIP-1016 active): GAS returns gas_left only (excludes reservoir).
// Two SSTOREs x 5k exec = ~10k, plus PUSH opcodes ~12 gas total -> ~10k.
//
// On T2 (no state gas split): GAS returns full gas.
// Two SSTOREs x 250k = ~500k, plus PUSH opcodes -> ~500k.
//
// Either way, GAS should never return state gas reservoir balance.
// We assert the value is reasonable for either hardfork.
assert!(
gas_consumed >= 5_000,
"at minimum, SSTORE should consume 5k execution gas, got {gas_consumed}"
);

// The key T3 assertion: if state gas is split, consumed should be < 50k (two 5k SSTOREs).
// If state gas is NOT split (T1), consumed will be ~500k (two 250k SSTOREs).
// We log the result for debugging.
if gas_consumed < 50_000 {
// T3 behavior: GAS returns execution gas only
} else {
// T2 behavior: GAS returns total gas (state gas not yet split)
assert!(
gas_consumed < 600_000,
"T2: gas consumed by two SSTOREs should be ~500k, got {gas_consumed}"
);
}

Ok(())
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.

Lets test exact values, clanker is not great with gas.

This gas_consumed < 50k t3/t2 logic does not make sense

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this was removed

Copy link
Copy Markdown
Contributor

@rakita rakita left a comment

Choose a reason for hiding this comment

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

lgtm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-test A change that impacts how or what we test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants