Skip to content

i2p, test: steady SAM creation deadline, test framework fixes - #246

Merged
djh58 merged 1 commit into
feature/pq-transportfrom
djh58/pq233-tests-i2p
Oct 23, 2026
Merged

djh58 merged 1 commit into
feature/pq-transportfrom
djh58/pq233-tests-i2p

Conversation

@djh58

@djh58 djh58 commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Three fixes from review of #233.

  • I2P session creation keeps its 3-minute limit when the clock moves. The limit was measured on the steady clock, but Sock::SendComplete() and Sock::RecvUntilTerminator() measure their timeouts on the mockable wall clock. A clock step back while the router stalled extended creation, and that holds Session::m_mutex, which also blocks outbound I2P connects. A frozen setmocktime left only an interrupt to end it. Each SAM request now goes through a socket view whose waits end at the steady deadline. Sock is unchanged for other callers. A new unit test freezes the mockable clock, and steps it back, while the router stalls.
  • The Python v2 peer delivers its handshake bytes before disconnecting. When authentication failed, it queued its key confirmation and then raised from the asyncio callback. That closed the transport before the write ran, so the node saw EOF (closed_after_switch) instead of a failed confirmation. Sends now go through an ordered per-connection queue, which the failure path flushes before a graceful close. p2p_v2_pq_misbehaving.py gains a case where such a responder makes the node record first_packet_failed.
  • V2TransportTester owns its PQKemOps. It passed a caller's reference straight to V2Transport, getting around the deleted rvalue overload, so a temporary could dangle. This was latent, since every caller passes a static.

Tests run:

  • test_qbit --run_test=net_tests,i2p_tests
  • these functional tests: p2p_v2_pq_misbehaving, p2p_v2_pq, p2p_v2_misbehaving, feature_framework_unit_tests, p2p_i2p_ports, p2p_i2p_sessions and feature_proxy, plus p2p_v2_encrypted, p2p_v2_transport, p2p_v2_pq_fallback, rpc_pqtransport, p2p_invalid_messages, p2p_ping, p2p_segwit and p2p_compactblocks

All passed. Since #245, pull requests into feature/pq-transport don't run CI. #233's full CI covers this change once it merges.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

Found in review of #233.

- i2p: the single SAM session creation deadline is on the steady clock,
  but Sock::SendComplete() and Sock::RecvUntilTerminator() re-base the
  time left on the mockable wall clock. A clock step back while the
  router stalls extended creation (holding Session::m_mutex, which also
  blocks outbound I2P connects), and a frozen setmocktime left only the
  interrupt to end it. Each request now goes through a socket view whose
  waits end by the steady deadline, so the 3-minute bound holds without
  changing Sock for other callers. A unit test freezes and steps back
  the mockable clock while the router stalls on SESSION CREATE.

- test: when its handshake authentication failed, the Python v2 peer
  queued its pending bytes (a key confirmation) and then raised from the
  asyncio callback, which closed the transport before the queued write
  ran and printed a fatal error on stderr. A hybrid responder whose keys
  don't match the node's therefore made the node see EOF
  (closed_after_switch) instead of failing the confirmation. Sends now
  go through an ordered per-connection queue that the failure path
  flushes before a graceful close. p2p_v2_pq_misbehaving.py gets a case
  where such a responder fails the node's confirmation too, and the node
  records first_packet_failed.

- test: V2TransportTester passed a caller's PQKemOps reference straight
  to V2Transport, getting around its deleted rvalue overload, so a
  temporary could dangle. The tester now owns a copy that outlives its
  transport.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@djh58

djh58 commented Oct 23, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-23T17:32:52.221312Z 55d8f7f Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 55d8f7ff04

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@djh58
djh58 merged commit 19e45c8 into feature/pq-transport Oct 23, 2026
djh58 added a commit that referenced this pull request Oct 26, 2026
When the Python v2 peer fails the node's key confirmation, it writes out
what it has sent and closes the connection, so that the node sees the
peer's own confirmation fail (#246). But a close with the node's later
bytes still unread on the peer's socket resets the connection, and on
Windows the reset discards what the node has not read yet: the node then
records closed_after_switch (reset) instead of first_packet_failed, and
p2p_v2_pq_misbehaving.py fails. The node sends its version packet right
after its confirmation, so this depends on timing.

End the peer's stream with write_eof() instead and let the node close the
connection, discarding what the node still sends until then. Sends after
that are dropped, since a write after write_eof() raises.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@djh58 djh58 mentioned this pull request Oct 26, 2026
6 of 15 tasks
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