Skip to content

fix(spec-specs, tests): reject empty and 0xff-prefixed transaction bytes - #3861

Merged
marioevz merged 3 commits into
ethereum:forks/bogotafrom
EddyW19:fix/decode-transaction-empty-bytes
Oct 19, 2026
Merged

marioevz merged 3 commits into
ethereum:forks/bogotafrom
EddyW19:fix/decode-transaction-empty-bytes

Conversation

@EddyW19

@EddyW19 EddyW19 commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Description

decode_transaction reads tx[0] without checking the length of the byte string. Block bodies carry typed transactions as byte strings, so a block with an empty entry (0x80) crashes apply_body with an IndexError instead of being rejected as invalid. This goes back to Berlin.

Since #2365, Amsterdam and Bogota also hit assert tx[0] <= 0xFE when the first byte is 0xff, so that crashes with an AssertionError. EIP-2718 reserves 0xff, so it's now handled like any other unknown type and raises TransactionTypeError.

An empty transaction now raises InvalidBlock. Added decoding tests for both cases on every fork with typed transactions; they fail on current forks/bogota (16 IndexError, 4 AssertionError) and pass with this change.

Related Issues or PRs

Same kind of problem as #3828: malformed input crashed block processing instead of being rejected.

Checklist

  • Ran fast static checks to avoid CI fails, see Code Standards & Verifying Changes: just static
  • PR title has the form <type>(<area>): <description>, where <type> and <area> come from an appropriate C-<type>, respectively A-<area>, label. The title should match the target squash commit message.

Cute Animal Picture

cute animal

Typed transactions sit in the block body as byte strings, and
`decode_transaction` read `tx[0]` without checking the length. An
empty byte string crashed `apply_body` with an `IndexError` instead of
invalidating the block (Berlin onwards). Since Amsterdam, a first byte
of 0xff also tripped `assert tx[0] <= 0xFE`; EIP-2718 reserves 0xff,
so treat it as an unknown type like any other.

Raise `InvalidBlock` for an empty transaction and `TransactionTypeError`
for 0xff, and add decoding tests for every fork with typed
transactions.

@marioevz marioevz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for fixing. We need to implement a reference spec test for this so implementations can use it to test. Please see comment below.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We also need a transaction_test in tests/frontier/validation/test_transaction_rlp.py.

@EddyW19 EddyW19 Oct 19, 2026 •

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.

Added test_invalid_envelope to test_transaction_rlp.py: an empty transaction and one with the reserved 0xff type byte, as transaction_tests from Frontier on. Without the spec fix, decoding these crashes on 11 of the 32 cases.

Cover the inputs fixed in the spec with `transaction_test`s, so clients
can check them too: an empty transaction, and one whose first byte is
the 0xff type reserved by EIP-2718. Both are invalid from Frontier on.
@EddyW19 EddyW19 changed the title fix(spec-specs): reject empty and 0xff-prefixed transaction bytes fix(spec-specs, tests): reject empty and 0xff-prefixed transaction bytes Oct 19, 2026
@codecov

codecov Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 95.09%. Comparing base (c13a779) to head (fe36d2c).
⚠️ Report is 3 commits behind head on forks/bogota.

Files with missing lines Patch % Lines
src/ethereum/forks/bogota/transactions.py 66.66% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@               Coverage Diff                @@
##           forks/bogota    #3861      +/-   ##
================================================
+ Coverage         94.99%   95.09%   +0.09%     
================================================
  Files               673      673              
  Lines             40888    40904      +16     
  Branches           3769     3778       +9     
================================================
+ Hits              38843    38896      +53     
+ Misses             1428     1397      -31     
+ Partials            617      611       -6     
Flag Coverage Δ
unittests 95.08% <95.00%> (+0.08%) ⬆️

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.

@marioevz marioevz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, great catch. Thanks for implementing!

Comment thread tests/frontier/validation/test_transaction_rlp.py
@marioevz
marioevz merged commit 8349ed4 into ethereum:forks/bogota Oct 19, 2026
28 checks passed
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