Skip to content

*: bound allocation and decode work for p2p messages - #4810

Open
OisinKyne wants to merge 1 commit into
mainfrom
oisin/p2p-incremental-read
Open

OisinKyne wants to merge 1 commit into
mainfrom
oisin/p2p-incremental-read

Conversation

@OisinKyne

@OisinKyne OisinKyne commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Hardens the handling of messages received from peers, so a peer cannot make a node allocate or decode far more than it actually sends.

  • Incremental frame allocation. pbio.NewDelimitedReader allocates the full declared length (up to 128MB) before reading the body. The new p2p reader keeps pbio's wire format and errors (io.ErrShortBuffer over the limit, io.EOF/io.ErrUnexpectedEOF on truncation, unwrapped stream errors so IsRelayError still matches), but starts with at most 64KB and doubles only as bytes arrive. dkg/sync's readSizedProto uses the same helper. It also previously did a single Read and failed if the message arrived in several reads; it now reads the full frame. This makes the "Allocation size of p2p messages" entry in KNOWN_ISSUES.md accurate.
  • Parsigex set cardinality. Sets with more partial signatures than the cluster has validators are rejected before ParSignedDataSetFromProto SSZ/JSON-decodes each entry (taken from core/parsigex: bound work triggered by received messages #4637).

Max message sizes are unchanged: the 128MB default, every WithReadLimit (consensus, peerinfo, payloadex) and dkg/sync's 32MB.

Testing: FuzzDelimitedReader checks that the reader returns the same messages and errors as pbio on arbitrary input, including the max-size boundary, oversized declared lengths, truncated bodies and overlong varints. BenchmarkDelimitedReader shows the same cost up to 4KB, and up to ~2x time and allocation for frames above 64KB from the buffer doubling (about 0.6ms per extra MB).

From #4637, the 32MB parsigex read limit was dropped, since it changes a limit and its rationale (up-front allocation) is removed here. The expired-duty check was also dropped, since replaying current duties costs the same. #4639 (resource manager) is out of scope.

category: bug
ticket: none

@codecov

codecov Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.74%. Comparing base (e7d8587) to head (f9e5494).

Files with missing lines Patch % Lines
p2p/delimited.go 89.18% 4 Missing ⚠️
app/app.go 0.00% 1 Missing ⚠️
dkg/sync/server.go 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4810      +/-   ##
==========================================
+ Coverage   67.72%   67.74%   +0.01%     
==========================================
  Files         255      256       +1     
  Lines       33711    33750      +39     
==========================================
+ Hits        22832    22864      +32     
- Misses      10878    10885       +7     
  Partials        1        1              

☔ 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.

Replaces pbio.NewDelimitedReader with a reader using the same wire format
and error semantics that grows its buffer as bytes arrive instead of
allocating the declared length up front, so a peer declaring a large frame
but sending little cannot pin a large buffer. Applies the same to
dkg/sync readSizedProto, which now also reads the whole frame instead of
failing on a short read. Per-protocol read limits and the 128MB maximum
are unchanged.

Parsigex now rejects partial signature sets larger than the cluster's
validator count before decoding them, since each entry is unmarshalled
before any of it is authenticated.

Adds a fuzz test comparing the reader against pbio and a benchmark.

category: bug
ticket: none

Co-authored-by: Andrei Smirnov <6468078+pinebit@users.noreply.github.com>
@OisinKyne
OisinKyne force-pushed the oisin/p2p-incremental-read branch from 7f7d62d to f9e5494 Compare November 4, 2026 01:40
@sonarqubecloud

sonarqubecloud Bot commented Nov 4, 2026

Copy link
Copy Markdown

@OisinKyne
OisinKyne marked this pull request as ready for review November 4, 2026 01:43
@OisinKyne OisinKyne changed the title p2p: allocate received frames incrementally *: bound allocation and decode work for p2p messages Nov 4, 2026
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.

1 participant