Skip to content

Implement relay-side HOP responder and STOP initiator #69

Description

@deepso7

Parent

Part of #61.

Canonical specification

Implement PR 1 of docs/plans/circuit-relay-v2-relay-server.md. That document and the resolved decisions in #62#68 are authoritative. Do not reopen product design or substitute rust-libp2p behavior where the specification declares a minip2p deviation.

What to build

Deliver the complete relay-side wire boundary for a Circuit Relay v2 server. Existing relay clients must retain their public behavior while server-side code can accept inbound HOP streams, initiate outbound STOP streams, make explicit accept/deny decisions, and preserve payload pipelined with either handshake.

Keep this layer limited to one HOP or STOP stream: protobuf messages, protocol identifiers, status encoding, the 8 KiB frame boundary, and per-stream machines belong here. Reservation tables, clocks, admission policy, forwarding policy, and whole-service lifecycle state do not.

Acceptance criteria

  • Split the relay implementation into message, client, and server responsibilities without changing existing client exports or behavior.
  • Add and publicly export the HopResponder and StopInitiator sans-I/O machines plus the status helpers required by the canonical specification.
  • Both machines implement the existing sans-I/O protocol contract and preserve application payload pipelined with the final handshake frame for later circuit forwarding.
  • HOP handling distinguishes RESERVE and CONNECT and exposes decisions in the order required by the service; STOP initiation maps responses without losing exact wire status.
  • A well-framed message with a wrong kind or a missing required field receives the specified malformed or unexpected status and then closes its write side.
  • Invalid framing, oversized declarations, and inputs for which no valid status can be encoded reset the stream.
  • Decoding preserves field presence: absent and invalid message types, absent and invalid CONNECT peer IDs, and unknown enum values remain distinguishable instead of becoming proto3 defaults.
  • Every relay control frame uses minip2p's existing 8 KiB maximum. The deliberate difference from rust-libp2p's 4 KiB limit is documented.
  • Remote close/reset behavior and partial or fragmented input leave each state machine in a deterministic terminal state.

Tests and fuzzing

  • Unit tests cover fragmented frames, exact-limit frames, oversized frames, wrong message kinds, missing required fields, invalid peer IDs, unknown enum values, decision ordering, remote closes/resets, and payload pipelined in both directions.
  • Existing relay client tests continue to pass unchanged except for mechanical module-path migration where necessary.
  • The wire_inputs fuzz target feeds arbitrary input to both new server-side machines.
  • just fuzz 30 completes successfully and its result is recorded in the PR.

Documentation and compatibility

  • Update crate-level rustdoc and the relay crate README for the new roles, ownership boundary, malformed-input contract, pipelined-data behavior, and 8 KiB frame limit.
  • Preserve the pinned Circuit Relay v2 wire contract and existing minip2p client exports.
  • Document deterministic status/reset handling as a deliberate minip2p extension rather than claiming rust-libp2p parity.
  • Do not add reservation policy, service configuration, clocks, admission, or forwarding state to the wire crate.
  • Reservation vouchers remain out of scope and voucher remains None.

Completion checks

  • Every new public item has rustdoc with actionable failure and terminal-state semantics.
  • just fmt passes.
  • just test passes.
  • just clippy passes with warnings denied.
  • just check-nostd passes.
  • just fuzz 30 passes.
  • No behavior assigned to later PRs is pulled into this issue, and no behavior in this issue is left to inference beyond the canonical specification.

Blocked by

None — can start immediately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, ready for an AFK agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions