Skip to content

feat(specs): implement frame tx - #3114

Open
lightclient wants to merge 9 commits into
ethereum:forks/amsterdamfrom
lightclient:eips/bogota/eip-8141
Open

feat(specs): implement frame tx#3114
lightclient wants to merge 9 commits into
ethereum:forks/amsterdamfrom
lightclient:eips/bogota/eip-8141

Conversation

@lightclient

Copy link
Copy Markdown
Member

Based on #3113.

🗒️ Description

Adds EIP-8141 implementation and some tests. Vibed with Fable.

🔗 Related Issues or PRs

#2829

  • All: Ran fast static checks to avoid unnecessary CI fails, see also Code Standards and Verifying Changes:
    just static
  • All: PR title have the form <type>(<area>):, where <type> and <area> come from an approrpriate C-<type>, respectively A-<area>, label. The title should match the a target squash commit message.
  • All: Considered updating the online docs in the ./docs/ directory.
  • All: Set appropriate labels for the changes (only maintainers can apply labels).
  • Tests: For PRs implementing a missed test case, update the post-mortem document to add an entry the list.
  • Ported Tests: Add the following docstring to manually enhanced tests from ./tests/ported_static/:
    @manually-enhanced: Do not overwrite. Post-state expectations corrected
    manually (see PR #2784).
    

Cute Animal Picture

Screenshot 2026-07-06 at 08 59 25

Implements the frame transaction (type 0x06) per the current EIP-8141
draft:

- FrameTransaction, Frame, and TransactionSignature types with static
  validation, canonical signature hash (elided empty-msg signatures),
  and protocol signature validation (secp256k1, P-256, arbitrary)
- derived transaction gas limit: intrinsic cost, per-frame cost,
  EIP-7623 calldata cost of the encoded frame/signature lists,
  signature verification gas, and the sum of frame gas limits
- frame execution loop: DEFAULT/VERIFY/SENDER modes, per-frame gas
  accounting, shared warm-access journal, transient storage discard
  between frames, atomic batch rollback and skipping
- APPROVE (0xaa): journaled approvals that revert with the granting
  call; payment approval increments the sender nonce and collects the
  maximum cost from the payer
- introspection opcodes TXPARAM (0xb0), FRAMEDATALOAD (0xb1),
  FRAMEDATACOPY (0xb2), FRAMEPARAM (0xb3), SIGPARAM (0xb4)
- default code for codeless accounts and the expiry verifier frame
  constraints
- frame transaction receipt ([cumulative_gas_used, payer,
  [status, gas_used, logs]]) with skipped-frame status 0x3
- EIP-3607 exemption for frame transaction senders
Mirror ordinary calldata pricing: the encoded signature and frame
lists are charged at the standard token cost inside the derived gas
limit, and the final gas used is floored at the EIP-7976 floor token
cost over all encoded bytes plus the frame transaction intrinsic
cost. A transaction whose floor exceeds its derived gas limit is
invalid.
Adds EIP-8141 frame transaction support to execution_testing and the
EELS t8n:

- Frame and FrameSignature test types; Transaction type 6 handling
  with the canonical signature hash (empty-msg signature entries
  elided) and automatic signing of secp256k1 entries from the sender
  or per-entry secret keys
- Bogota fork (Amsterdam + tx type 6) and Amsterdam->Bogota transition
- frame transaction fixture types, including the EIP-8141 receipt
  payload ([cumulative_gas_used, payer, [status, gas_used, logs]]) so
  fixture receipt roots re-encode correctly
- APPROVE/TXPARAM/FRAMEDATALOAD/FRAMEDATACOPY/FRAMEPARAM/SIGPARAM
  opcodes for bytecode construction
- type-6 transaction exceptions mapped to the EELS error names
- t8n: frame transaction JSON loading (frames/signatures/sender) and
  frame receipt output (payer, frameReceipts)
Broad-stroke coverage of EIP-8141: default-code transfer, contract
sender approving via APPROVE, EOA paymaster, atomic batch rollback,
TXPARAM introspection, and invalid transactions (SENDER frame before
approval, reverting VERIFY frame).
Adds verify_frame_transaction_receipt, run only for frame
transactions on top of the generic receipt checks: it validates the
receipt payer and the per-frame receipt entries (status, gas used,
and logs) against expected_receipt. Non-frame uses of
expected_receipt are unaffected.

The frame transaction tests now assert the payer and per-frame
statuses, including the unrolled (0x0) and skipped (0x3) statuses of
both atomic batch failure orderings.
Validating the geth implementation against the EELS-produced fixtures
surfaced three differences:

- do not read the frame caller's balance for zero-value frames; the
  gratuitous read placed the entry point in the block access list
- report frame transactions as succeeded in the t8n receipt output:
  transactions that make it into a block are valid regardless of
  individual frame results
- derive the t8n receipt logs bloom from the frame logs instead of
  emitting zeroes

Also maps the type-6 transaction exceptions for the geth t8n.
@codecov

codecov Bot commented Jul 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0.04476% with 4466 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.72%. Comparing base (f878b22) to head (e6cf876).
⚠️ Report is 5 commits behind head on forks/amsterdam.

Files with missing lines Patch % Lines
src/ethereum/forks/bogota/fork.py 0.00% 554 Missing ⚠️
src/ethereum/forks/bogota/transactions.py 0.00% 474 Missing ⚠️
...rc/ethereum/forks/bogota/vm/instructions/system.py 0.00% 343 Missing ⚠️
...hereum/forks/bogota/vm/instructions/environment.py 0.00% 319 Missing ⚠️
src/ethereum/forks/bogota/vm/gas.py 0.00% 251 Missing ⚠️
src/ethereum/forks/bogota/block_access_lists.py 0.00% 195 Missing ⚠️
src/ethereum/forks/bogota/state_tracker.py 0.00% 180 Missing ⚠️
.../ethereum/forks/bogota/vm/instructions/__init__.py 0.00% 175 Missing ⚠️
src/ethereum/forks/bogota/vm/__init__.py 0.00% 143 Missing ⚠️
src/ethereum/forks/bogota/vm/interpreter.py 0.00% 135 Missing ⚠️
... and 38 more

❗ There is a different number of reports uploaded between BASE (f878b22) and HEAD (e6cf876). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (f878b22) HEAD (e6cf876)
unittests 6 5
Additional details and impacted files
@@                 Coverage Diff                  @@
##           forks/amsterdam    #3114       +/-   ##
====================================================
- Coverage            93.30%   81.72%   -11.59%     
====================================================
  Files                  624      673       +49     
  Lines                36986    41454     +4468     
  Branches              3383     3945      +562     
====================================================
- Hits                 34511    33878      -633     
- Misses                1693     7082     +5389     
+ Partials               782      494      -288     
Flag Coverage Δ
unittests 81.72% <0.04%> (-11.59%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@SamWilsn

SamWilsn commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

You've probably already seen #3047 which is where I started my implementation. I'm gonna guess that Fable's is better than mine, but might be worth comparing.

@lightclient

Copy link
Copy Markdown
Member Author

I didn't see this when I opened this! But will look now

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