Skip to content

fix(p2p): reject reqresp requests larger than a single muxer frame#24554

Open
spalladino wants to merge 2 commits into
merge-train/spartan-v5from
spl/reqresp-single-frame-request-limit
Open

fix(p2p): reject reqresp requests larger than a single muxer frame#24554
spalladino wants to merge 2 commits into
merge-train/spartan-v5from
spl/reqresp-single-frame-request-limit

Conversation

@spalladino

@spalladino spalladino commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

A reqresp request payload must fit in a single muxer frame: yamux splits writes larger than 64KiB (minus the 12-byte frame header) into multiple frames, each of which arrives at the responder as a separate chunk, and the responder never reassembles a request from multiple chunks. A request type growing past that limit would surface as a confusing decoding error on the responder instead of failing at the sender.

  • Assert the payload size in sendRequestToPeer before dialing, throwing a descriptive OversizedReqRespRequestError locally. The check runs before the generic error handling so the remote peer is not penalized for a local bug.
  • Pin maxMessageSize on the yamux muxer to its library default (64KiB) so a dependency upgrade cannot silently change the limit the assertion relies on.
  • Tests: an oversized payload is rejected without dialing the peer and without penalizing it; a payload at exactly the limit round-trips successfully.

Related to #24552.

No current subprotocol can exceed the limit

The limit is 65,524 bytes (64KiB yamux frame minus the 12-byte header). No reqresp subprotocol today can produce a request anywhere near it, so this assertion cannot fire on legitimate traffic:

  • GOODBYE: 1 byte (the reason code).
  • PING: a few bytes.
  • STATUS: a StatusMessage (component versions string, block numbers, block hash) — tens of bytes.
  • AUTH: an AuthRequest (StatusMessage plus a 32-byte challenge) — tens of bytes.
  • TX: the request type is TxHashArray (4 + 32·n bytes), but this subprotocol currently has no sender — only the server-side handler remains.
  • BLOCK_TXS: the only request that scales with anything. Serialized as archiveRoot (32 bytes) + tx-indices BitVector (4 + ⌈N/8⌉ bytes, N = tx count of the proposal) + tx-hashes commitment (32 bytes) + optional full-hash vector (4 + 32·H bytes). Pinned-peer and smart-peer requests send indices only (H = 0). Dumb-peer requests include full hashes but chunk them to txBatchSize, which is always the default 8 in production (BatchTxRequester is constructed without opts, and the option is not wired to any config). N is capped at deserialization by MAX_TXS_PER_BLOCK = 2^16, so even a maliciously large proposal yields a worst-case request of ~8.5KB — about 13% of the limit. A realistic 32-tx block produces requests of a few hundred bytes.

Breaching the limit would take a proposal with ~460k txs (which BitVector.fromBuffer rejects at 2^16 anyway) or a txBatchSize over ~1,800 with full hashes enabled — neither is reachable today. The assertion exists so that if a future change makes a request type scale past the limit, it fails loudly at the sender instead of as a decoding error at the responder.

A reqresp request payload must arrive at the responder in a single chunk: yamux splits writes larger than one frame
(64KiB including the 12-byte header) into multiple frames, and the responder never reassembles them into one request.
Assert the size at the sender before dialing, so an oversized request type fails loudly locally instead of surfacing
as a decoding error on the responder. Pin the yamux maxMessageSize to its library default so an upgrade cannot
silently change the limit.
@spalladino spalladino added wip Work in progress and removed wip Work in progress labels Jul 6, 2026
@AztecBot

AztecBot commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Flakey Tests

🤖 says: This CI run detected 1 tests that failed, but were tolerated due to a .test_patterns.yml entry.

\033FLAKED\033 (8;;http://ci.aztec-labs.com/6f9031519f4072f3�6f9031519f4072f38;;�):  yarn-project/end-to-end/scripts/run_test.sh simple src/multi-node/block-production/multi_validator_node.parallel.test.ts "should build blocks & attest with multiple validator keys" (45s) (code: 0) group:e2e-p2p-epoch-flakes

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