Skip to content

[W5.4] libp2p/mux: the Muxer values #17

Closed

Description

@leolara

Unit W5.4 of docs/PLAN.md.

The Muxer values: Mux.yamux over the session of net/yamux under /yamux/1.0.0, and the fixed-key test value. mplex is P2 (§8) and can follow any time after this unit: go-compatible (id, initiator) identity and half-close.

Where the spec lives

  • The unit row: root docs/PLAN.md — the deliverable, the dependencies, the priority.
  • The frozen interfaces: root docs/ARCHITECTURE.md, §3 (the mechanisms) and §4.9 (this package).
  • The package's own docs: packages/libp2p/mux/docs/ARCHITECTURE.md and its PLAN.md — read them first; they refine the root docs and never contradict them.
  • The reference: the spike branch, Conn/Mux.lean (the yamux value), Conn/Mplex.lean (mplex, P2) (ARCHITECTURE §7). Read it before you implement. Port its tests, keep the wire bytes; the code shape follows §3, not the spike's internals (§7 preamble, §9).

Your freedom, and its cost

The docs govern, and they are yours to change. Where a better design exists, change it — and change the documents in the same pull request. A contract change starts at the root docs/ARCHITECTURE.md; the package docs follow it in the same change. Code that disagrees with the docs, or package docs that disagree with the root, does not merge.

Definition of done

  • The public surface follows ARCHITECTURE §4; the owned contracts hold.
  • The muxer values over the sim transport end to end through the host seams, and the half-close contract (§5.3): a response after our FIN still arrives.
  • The carried vector and property tests pass through the Tests suite.
  • lake build, lake test, and lake test -- +RTS -N1 -RTS are green; scripts/lint-imports.sh is green.
  • No sorry, no build warnings (CLAUDE.md, "Strict checking").
  • First submodule under your leaf? Widen the lib's globs in lakefile.toml in the same commit.

Depends on

Every issue is claimable from day one; you build ahead of open dependencies against mocks of their frozen interfaces (RULES.md, "Working ahead of the tree").

Ground rules

  • Comment claim to take the issue; an organiser assigns it. One issue at a time.
  • A pull request within 8 hours of the assignment; drafts count. Link the issue (Closes #N). Miss the window, lose the claim.
  • Target the hackathon26 branch.
  • The license-acceptance line of the PR description stays ticked; commits carry no AI co-author trailers. Two guards fail the PR otherwise.
  • Prose register everywhere: CLAUDE.md, "Writing Style".
  • A contract question the docs do not settle: ask on this issue before you code past it.

Activity

  1. Mouzayan commented on Nov 4, 2026

    @Mouzayan
    Contributor

    claim

  2. IvanAnishchuk commented on Nov 4, 2026

    @IvanAnishchuk
    Contributor

    W1.1 (#27) changed frozen signatures this unit builds on. RULES.md ("Working ahead of the tree") asks for a comment on every dependent issue, and this one is late: it belonged here before the merge. The change is approved on the PR: #27 (comment)

    Everything that can park now runs in Conc.Async. The reason is threads: 5000 receivers parked in Async cost 12 OS threads, and 5005 with a blocking IO.wait (scripts/park-threads.lean).

    For the muxer values:

    • Mux.yamux carries open : Role → Connection → ByteArray → ExceptT Core.Error Async MuxSession (root ARCHITECTURE §4.9).
    • The MuxSession it returns has accept : Async (Option Stream) and openStream through ExceptT Core.Error Async. close : IO Unit stays in IO, since a close never parks.
    • The mplex loop imports Async with Chan, TaskSet and OnceRef from base/conc, as the package ARCHITECTURE lists.

    #27 is merged, so the package builds on Conc directly.

  3. Mouzayan commented on Nov 4, 2026

    @Mouzayan
    Contributor

    W1.1 (#27) changed frozen signatures this unit builds on. RULES.md ("Working ahead of the tree") asks for a comment on every dependent issue, and this one is late: it belonged here before the merge. The change is approved on the PR: #27 (comment)

    Everything that can park now runs in Conc.Async. The reason is threads: 5000 receivers parked in Async cost 12 OS threads, and 5005 with a blocking IO.wait (scripts/park-threads.lean).

    For the muxer values:

    • Mux.yamux carries open : Role → Connection → ByteArray → ExceptT Core.Error Async MuxSession (root ARCHITECTURE §4.9).
    • The MuxSession it returns has accept : Async (Option Stream) and openStream through ExceptT Core.Error Async. close : IO Unit stays in IO, since a close never parks.
    • The mplex loop imports Async with Chan, TaskSet and OnceRef from base/conc, as the package ARCHITECTURE lists.

    #27 is merged, so the package builds on Conc directly.

    Thanks.
    I'll build directly on Conc.Async and keep close in IO as specified.

  4. IvanAnishchuk commented on Nov 4, 2026

    @IvanAnishchuk
    Contributor

    The W4.2 pull request (#47) changes the TCP close discipline of root ARCHITECTURE §4.7, which the Connection of net/streams carries to every layer above it.

    • close sends a FIN when no write is in flight, and an RST when one is. On v4.34, a write to a peer that stops reading never completes. libuv's shutdown waits behind it, and the write request holds the socket and its descriptor. A C shim in net/streams ends such a connection, and the peer gets an RST. A failed write follows the same rule.
    • A read that meets the peer's RST answers none, the end-of-stream channel of §3.5. go-libp2p closes every TCP connection with an RST (linger 0, vendor/go-libp2p/p2p/transport/tcp/tcp.go, lines 278 to 281), so a session with a go node ends this way.

    The Connection type and its fields stay the same. The net/streams ARCHITECTURE, "Decisions", records both rules with their sources.

  5. IvanAnishchuk commented on Nov 5, 2026

    @IvanAnishchuk
    Contributor

    #61 (W5.6) touches the docs of two packages this unit builds on, through the chain of root PLAN.

    • packages/libp2p/core/docs/ARCHITECTURE.md fixes the policy shapes, which the core surface left to the host: the gater's allowDial, allowInbound, and allowSecured; ResourceManager.openConnection with its ConnectionScope; and AddressRanker.rank over go-libp2p's AddrDelay schedule. No seam of SecurityProtocol, Muxer, MuxSession, or StreamHandler changes.
    • packages/libp2p/negotiate/docs/ARCHITECTURE.md gains upgradeWith, the upgrade with a checkpoint after the handshake, and negotiateStream, multistream-select over one muxed stream. upgrade keeps its signature.

    The host surface also has newStream (#60 posted it). A unit that holds a Host opens its streams through it, and one that serves streams registers a StreamHandler, unchanged.

  6. IvanAnishchuk commented on Nov 5, 2026

    @IvanAnishchuk
    Contributor

    #62 (W4.3, yamux) touches docs this unit builds on. No existing signature changes.

    • Root ARCHITECTURE §3.3: "The loop blocks on one channel" now reads "The loop blocks only on channels its shutdown closes".
    • base/bytes gains Bytes.take? (with sliceAt?), which moves out of Streams.Framing, and Bytes.Blob, the wrapper that gives core data a Repr for its bytes.
    • net/streams gains Streams.readLoop, the reader task of a session: a credit from the loop before each read, a post per chunk, and a post for the end of the connection.
    • net/yamux lands its session: Session.new role conn leftover clock keepalive, openStream, acceptStream, close, and join, serving the Stream seam.
  7. Mouzayan commented on Nov 5, 2026

    @Mouzayan
    Contributor

    Thanks, noted.

    W4.2’s TCP close behavior from #47 is already in this branch’s upstream baseline. The test session treats a peer RST as connection end and keeps it distinct from a mux stream reset. The W5.6 changes in #61 do not alter the mux-facing seams.

    W5.4 is completing the independent test-mux lifecycle coverage. After #62 merges, I’ll rebase and connect Mux.yamux to Yamux.Session.new.
    During that integration, I’ll check whether Streams.readLoop and the new byte helpers should replace any package-local machinery without changing the test-mux contract.

  8. IvanAnishchuk commented on Nov 5, 2026

    @IvanAnishchuk
    Contributor

    #63 (W5.1) lands libp2p/identity and touches docs and types this unit builds on. No existing signature changes.

    • Libp2p.Identity exports KeyType, PubKey, PrivKey, PeerId, and Identity.Error. The entry points are PubKey.unmarshal?, PrivKey.unmarshal?, PubKey.marshal, PubKey.verify, PrivKey.sign : ByteArray → ExceptT Error IO ByteArray, PrivKey.toPublic, PeerId.ofPubKey, PeerId.ofBytes?, PeerId.toBytes, and PeerId.ofString?.
    • PeerId derives BEq, DecidableEq, Hashable, Ord, and Repr, as root §3.2 asks. ToString prints the parsed text form. The derived == also compares that form, so code that asks "same peer?" compares a.hash == b.hash.
    • To make those classes derivable, Multiformats.Multihash now derives Hashable and Ord, and the generated multiformats enums (HashCode, ContentCodec, Protocol, Multibase.Base) derive Ord.
    • The peer shape rule stays Multiformats.Multiaddr.validPeerHash; PeerId carries its proof.
  9. Mouzayan commented on Nov 5, 2026

    @Mouzayan
    Contributor

    Progress update:
    The independent, repo-only Mux.test implementation is complete in PR #49, including its bounded framing/session machinery and lifecycle, concurrency, resource-boundary, and hostile-input coverage.

    The PR is now paused at the dependency boundary.
    Once W5.2 (#15 / PR #64) and W4.3 (#14 / PR #62) land, I’ll rebase and replace the temporary Core seam and connect the thin Mux.yamux adapter.

  10. leolara commented on Nov 7, 2026

    @leolara
    ContributorAuthor

    Unit 1b stays open: PR #49 merged with Mux.yamux moved to a seam issue, per the organiser ruling of today. The muxer seam values and the test value landed; the production yamux value over the W4.3 session closes this issue.

  11. reopened this on Nov 7, 2026
  12. Mouzayan commented on Nov 9, 2026

    @Mouzayan
    Contributor

    PR #84 is ready for review with the production Mux.yamux value over the landed net/yamux session. Mux.test remains the independent repository test muxer, and the adapter’s role mapping, leftover forwarding, error boundary, and public session behavior are covered. Mplex remains deferred P2 work.

  13. leolara commented on Nov 9, 2026

    @leolara
    ContributorAuthor

    Unit 1b landed through PR #84: Mux.yamux fills the real core seam over the net/yamux session, with the adapter suite over the sim pair. The issue closes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions