Skip to content

fix: reject blocks that contain blob-bearing transactions#191

Merged
matthias-wright merged 1 commit into
audit-may-2026from
m/blob-hashes
Jun 30, 2026
Merged

fix: reject blocks that contain blob-bearing transactions#191
matthias-wright merged 1 commit into
audit-may-2026from
m/blob-hashes

Conversation

@matthias-wright

Copy link
Copy Markdown
Collaborator

Note: this PR builds on #190 because it addresses a similar edge case, and the code changes are overlapping.

This addresses #184.

We currently don't support blobs, so this PR adds checks that reject blob-bearing transactions.

Changes:

  • Adds checks to handle_verify that ensure that blob_gas_used is 0.
  • Adds a unit test to ensure that blocks with blob_gas_used > 0 are rejected.

@evonide

evonide commented May 22, 2026

Copy link
Copy Markdown

LGTM. This PR rejects blob-consuming payloads before consensus accepts them so Summit no longer certifies blob payloads without the versioned-hash data needed for Engine API validation.

@sebastian-osec

Copy link
Copy Markdown

I agree this rejects the honest/common blob-consuming payload case where blob_gas_used > 0, but I think the security invariant needs to be enforced from transaction contents, not only from the payload’s declared blob gas field.

blob_gas_used is part of the proposer-supplied payload. A Byzantine proposer could set blob_gas_used = 0 while including an EIP-4844/blob transaction in payload.payload_inner.payload_inner.transactions. In that case handle_verify would pass the new check, while EngineClient::check_payload still calls engine_newPayloadV4(..., Vec::new(), ...).

The added test also uses transactions: Vec::new() and manually sets payload.blob_gas_used = 131_072, so it proves the declared-gas branch rejects, but it does not test an actual blob transaction or the attacker-controlled-field bypass.

I think the PR should either:

  1. parse the execution payload transactions and reject any EIP-4844/blob transaction, or
  2. carry consensus-committed versioned hashes/blob commitment data through Block and pass them to new_payload_v4.

@matthias-wright

Copy link
Copy Markdown
Collaborator Author

Yeah, I agree that the blob_gas_used guard is not sufficient to prevent blob transaction.
I do think that rejecting certain transaction types should be the responsibility of the EL.
Summit should not inspect EL payloads directly.
Does option 2 imply removing the blob_gas_used guard, and letting the EL handle this completely?

@sebastian-osec

Copy link
Copy Markdown

I do not think option 2 requires removing the blob_gas_used guard. Keeping it as a cheap early rejection for the common unsupported-blob case seems fine.

But I think the actual #184 fix should still be to carry consensus-committed blob validation data through Block and pass it to new_payload_v4.

The reason is that blob_gas_used is only a proposer-supplied payload field, so it is not strong enough to be the security boundary by itself. new_payload_v4 is the EL validation point, and for V4 blob payloads it needs the expected versioned_hashes. Right now Summit still calls new_payload_v4(..., Vec::new(), ...), so the block format still cannot faithfully revalidate blob-bearing payloads.

So I think the guard can stay, but the complete fix is to commit the versioned hashes/blob commitment data in the Summit block and thread that into EngineClient::check_payload.

@matthias-wright

Copy link
Copy Markdown
Collaborator Author

I agree that blob_gas_used can be easily altered by the proposer.

However, since all honest validators will pass versioned_hashes=[] to new_payload_v4, the EL will reject any payloads that contain blob transactions: https://github.com/SeismicSystems/seismic-reth/blob/4bbc6502ea566171decc97adc0c39106967e5ad9/crates/payload/validator/src/cancun.rs#L93

All honest validators call new_payload_v4 in CertifiableAutomaton::certify, preventing a blob-bearing payload from getting finalized.

@matthias-wright matthias-wright changed the base branch from main to audit-may-2026 June 30, 2026 06:44
@sebastian-osec

Copy link
Copy Markdown

Got it. I agree that if Summit's current invariant is "no blob transactions are supported", then passing versioned_hashes=[] to new_payload_v4 makes the EL reject actual blob transactions even if blob_gas_used is spoofed to 0.

@matthias-wright matthias-wright merged commit efa56d6 into audit-may-2026 Jun 30, 2026
4 checks passed
@matthias-wright matthias-wright deleted the m/blob-hashes branch June 30, 2026 09:03
matthias-wright added a commit that referenced this pull request Jun 30, 2026
Builds on #191 (which builds on #190).

This addresses #200.

Changes:
-Adds a check for the fee recipient to handle_verify. This check is only performed, if the treasury_address is non-zero. If the treasury_address is set to the zero address, then block proposers may chose any fee recipient.
-Adds unit tests for verifying this.
matthias-wright added a commit that referenced this pull request Jun 30, 2026
Builds on #206 (which builds on #191 and #190).

This addresses #209.

Changes:
-In handle_verify, checks that the prev_randao is zero.
-Adds unit tests.
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.

3 participants