Skip to content

fix: harden Hello & ChainExchange protocol handling#6976

Merged
LesnyRumcajs merged 4 commits intomainfrom
harden-hello
Apr 29, 2026
Merged

fix: harden Hello & ChainExchange protocol handling#6976
LesnyRumcajs merged 4 commits intomainfrom
harden-hello

Conversation

@LesnyRumcajs
Copy link
Copy Markdown
Member

@LesnyRumcajs LesnyRumcajs commented Apr 28, 2026

Summary of changes

Changes introduced in this pull request:

  • different limits on responses for Hello and ChainExchange to avoid excessive allocations
  • timeouts to avoid stalling the connection/stream

Reference issue to close (if applicable)

Closes

Other information and links

Change checklist

  • I have performed a self-review of my own code,
  • I have made corresponding changes to the documentation. All new code adheres to the team's documentation standards,
  • I have added tests that prove my fix is effective or that my feature works (if possible),
  • I have made sure the CHANGELOG is up-to-date. All user-facing changes should be reflected in this document.

Outside contributions

  • I have read and agree to the CONTRIBUTING document.
  • I have read and agree to the AI Policy document. I understand that failure to comply with the guidelines will lead to rejection of the pull request.

Summary by CodeRabbit

  • Bug Fixes
    • Prevented hanging peer connections by adding decode timeouts for protocol exchanges.
    • Introduced per-protocol message size limits to avoid resource exhaustion and improve stability.
    • Centralized and hardened response decoding to enforce timeouts and size bounds.
    • Reduced noisy timeout logging to lower log volume and improve observability.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

Walkthrough

Introduce a per-protocol CodecConfig and parameterize CborRequestResponse with it. Add HelloCodecConfig and ChainExchangeCodecConfig with explicit byte limits and decode timeouts. Centralize timed decoding using per-config limits/timeouts and return io::ErrorKind::TimedOut on timeout (logged at debug).

Changes

Cohort / File(s) Summary
Changelog
CHANGELOG.md
Add "Fixed" entry documenting Hello and ChainExchange response timeout and bounds for PR #6976.
Hello codec
src/libp2p/hello/codec.rs
Add HelloCodecConfig implementing CodecConfig; set MAX_REQUEST_BYTES = 4096, MAX_RESPONSE_BYTES = 32, DECODE_TIMEOUT = 10s; update HelloCodec alias to include the config.
ChainExchange codec
src/libp2p/chain_exchange/mod.rs
Add ChainExchangeCodecConfig implementing CodecConfig; set MAX_REQUEST_BYTES = 4096, MAX_RESPONSE_BYTES = 120 * 1024 * 1024, DECODE_TIMEOUT = 60s; update ChainExchangeCodec alias to include the config.
RPC codec & decoding
src/libp2p/rpc/mod.rs
Introduce CodecConfig trait; make CborRequestResponse generic over C: CodecConfig; add PhantomData<C>; centralize request/response decoding via a timed decode path using per-config limits/timeouts; change timeout handling to return io::ErrorKind::TimedOut and log at debug; update trait/impl signatures and defaults.

Sequence Diagram(s)

sequenceDiagram
    participant Peer as Peer
    participant Codec as CborRequestResponse (param C)
    participant Timed as timed_decode (uses C::MAX_* / C::DECODE_TIMEOUT)
    participant Reader as DagCborDecodingReader
    participant Decoder as CBOR Decoder

    Peer->>Codec: deliver raw bytes (request/response)
    Codec->>Timed: invoke timed_decode(bytes)
    Timed->>Reader: wrap stream with size/timeout limits
    Reader->>Decoder: stream bytes into CBOR decoder
    Decoder-->>Reader: decoded message
    Reader-->>Timed: return decoded message
    Timed-->>Codec: Ok(decoded) or Err(io::ErrorKind::TimedOut / Io)
    Codec-->>Peer: return decoded message or error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

RPC

Suggested reviewers

  • akaladarshi
  • sudo-shashank
  • hanabi1224
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main purpose of the changeset, which is to harden the Hello and ChainExchange protocol handling by adding configurable limits and timeouts.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch harden-hello
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch harden-hello

Review rate limit: 4/5 reviews remaining, refill in 12 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

@LesnyRumcajs LesnyRumcajs force-pushed the harden-hello branch 2 times, most recently from b36fd6b to 74dfa72 Compare April 28, 2026 14:07
@LesnyRumcajs LesnyRumcajs marked this pull request as ready for review April 28, 2026 14:08
@LesnyRumcajs LesnyRumcajs requested a review from a team as a code owner April 28, 2026 14:08
@LesnyRumcajs LesnyRumcajs requested review from akaladarshi and sudo-shashank and removed request for a team April 28, 2026 14:08
@LesnyRumcajs LesnyRumcajs changed the title fix: harden Hello protocol handling fix: harden Hello & ChainExchange protocol handling Apr 28, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/libp2p/rpc/mod.rs`:
- Around line 161-163: The current shared MAX_BYTES_ALLOWED (2 MiB) passed into
timed_decode lets inbound Hello requests still consume large resources; make the
request cap protocol-specific by adding a second const generic (e.g.,
MAX_REQUEST_BYTES) to HelloCodec (and other protocol codec types) and use that
constant when decoding inbound requests instead of the global MAX_BYTES_ALLOWED;
update the call sites that construct HelloCodec and the invocation of
timed_decode for request paths to pass the new MAX_REQUEST_BYTES and keep the
existing const for response/read_response behavior unchanged.
- Around line 166-173: The hardcoded 30s in timed_decode (using
DagCborDecodingReader) is too short for large ChainExchange payloads; change
timed_decode to accept a timeout parameter or compute the timeout from max_bytes
(e.g., derive Duration from max_bytes and a bytes-per-second heuristic) and
update its callers so Hello uses a short fixed timeout while ChainExchange uses
the larger derived timeout or an explicitly larger value; adjust the
timed_decode signature and the invocations in Hello and ChainExchange
accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2f937b0a-83ff-4b92-8c60-ffefa12e5b28

📥 Commits

Reviewing files that changed from the base of the PR and between 04fac3b and 74dfa72.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • src/libp2p/chain_exchange/mod.rs
  • src/libp2p/hello/codec.rs
  • src/libp2p/rpc/mod.rs

Comment thread src/libp2p/rpc/mod.rs Outdated
Comment thread src/libp2p/rpc/mod.rs Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 28, 2026

Codecov Report

❌ Patch coverage is 36.36364% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.12%. Comparing base (c5625ab) to head (9ef2dc1).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/libp2p/rpc/mod.rs 36.36% 7 Missing ⚠️
Additional details and impacted files
Files with missing lines Coverage Δ
src/libp2p/rpc/mod.rs 16.66% <36.36%> (+0.75%) ⬆️

... and 7 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c5625ab...9ef2dc1. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

sudo-shashank
sudo-shashank previously approved these changes Apr 28, 2026
sudo-shashank
sudo-shashank previously approved these changes Apr 28, 2026
@LesnyRumcajs LesnyRumcajs enabled auto-merge April 28, 2026 14:34
@LesnyRumcajs LesnyRumcajs disabled auto-merge April 28, 2026 14:39
@LesnyRumcajs LesnyRumcajs marked this pull request as draft April 28, 2026 15:19
@LesnyRumcajs LesnyRumcajs marked this pull request as ready for review April 29, 2026 08:23
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/libp2p/rpc/mod.rs (1)

178-183: Include config context in the timeout log.

Once both Hello and ChainExchange go through this helper, timed out alone will be hard to action in production. Logging at least {max_bytes, timeout} here would make it obvious which guard fired.

💡 Possible refinement
-            tracing::debug!("{err}");
+            tracing::debug!(max_bytes, ?timeout, "{err}");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/libp2p/rpc/mod.rs` around lines 178 - 183, The timeout branch in the
match around tokio::time::timeout calling DagCborDecodingReader::new currently
logs only the error string; update the Err(_) arm to include the timeout
parameters (timeout and max_bytes) in the log message so callers
(Hello/ChainExchange) can see which guard fired; specifically, modify the
tracing::debug call in the Err branch to log a clear message like
"DagCborDecodingReader timed out" and include the timeout and max_bytes values,
and keep returning the io::Error as before.
src/libp2p/hello/codec.rs (1)

9-25: Please lock the 32-byte assumption down with a serialization test.

This cap is intentionally tight. A later change in HelloResponse encoding shape could still compile but start rejecting peers at runtime. A small test that serializes the largest plausible HelloResponse and asserts it stays within HelloCodecConfig::MAX_RESPONSE_BYTES would make that failure mode explicit.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/libp2p/hello/codec.rs` around lines 9 - 25, Add a unit test that
serializes the largest plausible HelloResponse and asserts its CBOR byte length
does not exceed HelloCodecConfig::MAX_RESPONSE_BYTES; create (for example) a
test named test_hello_response_size that constructs the maximal HelloResponse
(e.g., using u64::MAX or whatever the response fields’ max values are),
serialize it using the same CBOR serializer the codec uses, measure
serialized.len(), and assert serialized.len() <=
HelloCodecConfig::MAX_RESPONSE_BYTES so future changes to HelloResponse encoding
will fail the test if they exceed the 32-byte cap.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/libp2p/hello/codec.rs`:
- Around line 9-25: Add a unit test that serializes the largest plausible
HelloResponse and asserts its CBOR byte length does not exceed
HelloCodecConfig::MAX_RESPONSE_BYTES; create (for example) a test named
test_hello_response_size that constructs the maximal HelloResponse (e.g., using
u64::MAX or whatever the response fields’ max values are), serialize it using
the same CBOR serializer the codec uses, measure serialized.len(), and assert
serialized.len() <= HelloCodecConfig::MAX_RESPONSE_BYTES so future changes to
HelloResponse encoding will fail the test if they exceed the 32-byte cap.

In `@src/libp2p/rpc/mod.rs`:
- Around line 178-183: The timeout branch in the match around
tokio::time::timeout calling DagCborDecodingReader::new currently logs only the
error string; update the Err(_) arm to include the timeout parameters (timeout
and max_bytes) in the log message so callers (Hello/ChainExchange) can see which
guard fired; specifically, modify the tracing::debug call in the Err branch to
log a clear message like "DagCborDecodingReader timed out" and include the
timeout and max_bytes values, and keep returning the io::Error as before.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7ca5c768-4e94-4c73-a686-25174e880160

📥 Commits

Reviewing files that changed from the base of the PR and between 734eafb and 9ef2dc1.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • src/libp2p/chain_exchange/mod.rs
  • src/libp2p/hello/codec.rs
  • src/libp2p/rpc/mod.rs
✅ Files skipped from review due to trivial changes (1)
  • CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/libp2p/chain_exchange/mod.rs

@LesnyRumcajs LesnyRumcajs added this pull request to the merge queue Apr 29, 2026
Merged via the queue into main with commit cadfa2f Apr 29, 2026
43 checks passed
@LesnyRumcajs LesnyRumcajs deleted the harden-hello branch April 29, 2026 10:48
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