Skip to content

spec: document optimistic multistream-select (issue #643)#721

Open
Devguru-codes wants to merge 3 commits into
libp2p:masterfrom
Devguru-codes:issue-643
Open

spec: document optimistic multistream-select (issue #643)#721
Devguru-codes wants to merge 3 commits into
libp2p:masterfrom
Devguru-codes:issue-643

Conversation

@Devguru-codes

Copy link
Copy Markdown

spec: Document optimistic multistream-select

Closes #643

Summary

This PR adds a new Working Draft specification documenting optimistic (lazy) multistream-select — the protocol negotiation optimization already implemented in go-libp2p and rust-libp2p but never formally specified.

What is optimistic multistream-select?

When a dialer knows (via identify) that a peer supports a given protocol, it can skip waiting for the multistream-select echo and send the header, protocol ID, and application data all at once — saving one round trip.

This is critical for latency-sensitive patterns like Kademlia DHT's "one stream per RPC" model.

Changes

New file

  • connections/optimistic-multistream.md — Full Working Draft specification covering:
    • Wire format diagrams (standard vs optimistic flow)
    • Prerequisites (identify-based prior knowledge)
    • Dialer requirements (ordering, handshake completion on close, prior knowledge)
    • Listener requirements (tolerating echo write failures, stream delivery, data boundaries)
    • Known limitations (protocol confusion on negotiation failure — go-multistream#20)
    • Security considerations
    • Interaction with inlined muxer negotiation

Modified file

  • connections/README.md — Added ToC entry, cross-reference subsection under Protocol Negotiation, and link definition

Implementation references

Reference Description
go-multistream#115 Fix: finish reading handshake on lazyConn close
go-multistream#87 Fix: ignore error if can't write back echoed protocol
go-multistream#20 Issue: lazy negotiation soundness problem (protocol confusion)
go-libp2p#3038 Bug: WebTransport StopSending caused by incomplete lazy handshake

Add new Working Draft specification for optimistic (lazy) multistream-select protocol negotiation, documenting the behavior already implemented in go-libp2p and rust-libp2p.

- New: connections/optimistic-multistream.md

- Modified: connections/README.md (ToC entry + cross-reference)

Refs: multiformats/go-multistream#115, multiformats/go-multistream#87, multiformats/go-multistream#20, libp2p/go-libp2p#3038
@Devguru-codes Devguru-codes marked this pull request as draft May 22, 2026 11:51
@Devguru-codes

Copy link
Copy Markdown
Author

Hello @MarcoPolo, I have created a draft pr so that you can review the work. I also had some doubts while I worked on this.
Three things I'd appreciate your input on:

  1. RTT count - The spec says standard stream-level negotiation costs "2 round trips" (header exchange → wait → protocol proposal → wait for echo). Is that accurate for the stream-level case, or do implementations pipeline the header + protocol proposal together (making it 1 RTT)?

  2. Interest Group - We need a 3rd member per the spec lifecycle. Currently listed: you and @marten-seemann. Could you suggest someone?

  3. General review - Does the spec accurately capture the behavior from go-multistream PRs typo. #115, gossipsub spec #87, and issue relay: add note about in-progress review and update #20?

After the review and my doubts cleared - I will do final fixes and make the pr. Thank you.

@Devguru-codes

Copy link
Copy Markdown
Author

hello @MarcoPolo , i am sorry to disturb you, please review my draft and help me with my doubts. Thank you.

@Devguru-codes

Copy link
Copy Markdown
Author

hello @MarcoPolo, just a ping to review my work. Thank you.

Comment thread connections/optimistic-multistream.md Outdated

In standard [multistream-select][mss] negotiation, the dialer (initiator) sends
its protocol proposal and **waits** for the listener (responder) to echo the
protocol ID back before sending any application data. This costs two full

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just one round trip:

A -> <multistream-header> <protocol> -> B
A <- <multistream-header> <protocol> <- B 
A -> Application data

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This was my main doubt. I have now updated it to 1 RTT count

Comment thread connections/optimistic-multistream.md Outdated
Comment on lines +79 to +82
[multistream-select][mss]. Messages are UTF-8 strings, newline-terminated, and
prefixed with their length as an [unsigned varint][uvarint]. The difference is
purely in the **sequencing** of messages.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
[multistream-select][mss]. Messages are UTF-8 strings, newline-terminated, and
prefixed with their length as an [unsigned varint][uvarint]. The difference is
purely in the **sequencing** of messages.
[multistream-select][mss].

Comment thread connections/optimistic-multistream.md Outdated
Comment on lines +56 to +60
Both [go-libp2p] and [rust-libp2p] use optimistic negotiation in production,
but it has not previously been documented in the libp2p specifications. This
document formalizes the optimization and documents the requirements
implementations must follow to use it correctly.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
Both [go-libp2p] and [rust-libp2p] use optimistic negotiation in production,
but it has not previously been documented in the libp2p specifications. This
document formalizes the optimization and documents the requirements
implementations must follow to use it correctly.

Comment thread connections/optimistic-multistream.md Outdated
Dialer Listener
| |
|--- /multistream/1.0.0 ---------------->|
|<-- /multistream/1.0.0 -----------------|

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Dialer does not have have to wait to hear back /multistream/1.0.0

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

updated it.

Comment thread connections/optimistic-multistream.md Outdated

## Prerequisites

Optimistic protocol negotiation is inherently **best-effort**. The dialer sends

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
Optimistic protocol negotiation is inherently **best-effort**. The dialer sends
Optimistic protocol negotiation is inherently optimistic. The dialer sends

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

updated this

Comment thread connections/optimistic-multistream.md Outdated
Comment on lines +144 to +145
Implementations SHOULD NOT use optimistic negotiation on the **first** stream
to a peer when no prior protocol knowledge is available.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
Implementations SHOULD NOT use optimistic negotiation on the **first** stream
to a peer when no prior protocol knowledge is available.
Implementations MAY skip optimistic negotiation when no prior protocol knowledge is available.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

updated this

Comment thread connections/optimistic-multistream.md Outdated
is a pure write/fire-and-forget pattern), the implementation MAY skip reading
the handshake response.

3. **Prior knowledge**: Implementations SHOULD NOT use optimistic negotiation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

SHOULD NOT is too strong I think. This can be OPTIONAL or MAY

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I updated it now

Comment thread connections/optimistic-multistream.md Outdated
applies within an already-authenticated peer relationship, where the remote peer
provides incorrect identify information.

## Interaction with Inlined Muxer Negotiation

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This section should simply say Inlined Muxer Negotiation is preferred.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done.

Comment thread connections/optimistic-multistream.md Outdated
- Implementations SHOULD log or track negotiation failures to detect potential
protocol confusion.

## Security Considerations

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This section doesn't add value. Consider cutting it.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I have also removed the security considerations section here. If you want me to keep - i will re-write it again. Thank you.

- Fix RTT count: standard negotiation is 1 RTT, not 2 (Comment 1, 4)

- Fix both diagrams to show header+protocol sent together

- Simplify wire format section (Comment 2)

- Remove meta 'not previously documented' paragraph (Comment 3)

- Change 'best-effort' to 'optimistic' (Comment 5)

- Soften SHOULD NOT to MAY for prior knowledge (Comment 6, 7)

- Remove obvious 'Data boundary' requirement (Comment 8)

- Simplify inlined muxer section (Comment 9)

- Remove Security Considerations section (Comment 10)
@Devguru-codes

Copy link
Copy Markdown
Author

@MarcoPolo hello, I have addressed and made the updates you suggested in latest commits - i would like you to just see whether the changes are in accordance with what you suggested. Thank you.

@Devguru-codes Devguru-codes marked this pull request as ready for review June 24, 2026 04:15
@Devguru-codes Devguru-codes requested a review from MarcoPolo June 24, 2026 04:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

Document optimistic multistream-select

2 participants