Skip to content

Make webrtc-specific multistream-select negotiation spec compliant#554

Open
haikoschol wants to merge 4 commits intoparitytech:masterfrom
ChainSafe:haiko-webrtc-multistream-nego-fix-3
Open

Make webrtc-specific multistream-select negotiation spec compliant#554
haikoschol wants to merge 4 commits intoparitytech:masterfrom
ChainSafe:haiko-webrtc-multistream-nego-fix-3

Conversation

@haikoschol
Copy link
Contributor

This PR brings the WebRTC-specific multistream-select implementation in line with the spec. Before this change, the header, the desired protocol and all fallback protocols were sent in a single multistream-select message. The spec mandates that only the desired protocol is to be sent instead. If the peer responds with a na, indicating it does not support this protocol, another multistream-select message should be sent, containing the first fallback protocol. This is to be repeated until the peer accepts a protocol or the dialer runs out of fallbacks.

This fix is required for interop with smoldot. Without this fix, the following happens:

  • The dialer proposes a protocol with fallbacks in a single message (e.g. /multistream/1.0.0\n/c7fd75141ca230c62e99af66d68f9d1f84b0821bcc1e17d2be92aaf5602d1c0e/block-announces/1\n/dot/block-announces/1\n).
  • Smoldot reads from its input buffer until it sees /c7fd75141ca230c62e99af66d68f9d1f84b0821bcc1e17d2be92aaf5602d1c0e/block-announces/1\n and sends back a confirmation.
  • The fallback protocol remains in the input buffer and is misinterpreted by Smoldot as the block announce handshake. Smoldot does not verify the handshake on inbound substreams.
  • The dialer sends the actual block announce handshake (70 byte payload).
  • Smoldot misinterprets this as the first block announce message and fails to decode it and logs this error to the browser console: DecodeBlockAnnounceError(Verify).

closes #75

@haikoschol haikoschol marked this pull request as draft March 3, 2026 06:30
@haikoschol
Copy link
Contributor Author

The last commit ended up being a big larger than expected. Originally I tried to get rid of drain_trailing_protocols because it was based on invalid assumptions and had a confusing name from its original usage.

But then I realized that the current multistream-select implementation still does not cover the valid scenario of receiving the header and the first proposed protocol in two separate webrtc protobuf messages. While implementing support for this I also made some changes that reduce the number of allocations when decoding multistream-select messages.

I think the result is overall better than before though. I've made sure the tests still make sense and tested it manually with smoldot.

Still, these changes are not necessary, more of a nice-to-have. If you prefer to keep the PR as small as possible, I can revert the commit.

@haikoschol haikoschol marked this pull request as ready for review March 3, 2026 09:23
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.

multistream-select implementation used by WebRTC doesn't conform to the spec

1 participant