libp2p / libp2p/unified-testing
nim-v1.14 / python-v0.x WebSocket protocol negotiation failure
Nobody has claimed this yet.
- Dominant language
- Shell
- Stars
- 7
- Forks
- 19
- PR merge metrics
- No merged PRs in 30d
Description
Repos:
- status-im/nim-libp2p (commit
0309685cd27d4bf763c8b3be86a76c33bcfe67ea) - libp2p/py-libp2p (commit
22ea173ac0359a386275bdf6b846bc52a0082e91)
Transport: ws, Secure: noise
Summary
nim-v1.14 and python-v0.x fail WebSocket interop in both directions. When nim is the dialer, the protocol upgrade fails with "Incorrect message received!" during multistream-select. When python is the dialer, the connection succeeds and ping stream is created, but the muxed stream closes prematurely during the ping response read, causing a MuxedStreamEOF.
Failing tests (4)
nim-v1.14 x python-v0.x (ws, noise, mplex)nim-v1.14 x python-v0.x (ws, noise, yamux)python-v0.x x nim-v1.14 (ws, noise, mplex)python-v0.x x nim-v1.14 (ws, noise, yamux)
Error output (nim as dialer)
ERR Unexpected error description="Failed to finish outgoing upgrade in internalConnect:
Incorrect message received!"
Error output (python as dialer)
The connection and stream creation succeed, but the ping response read fails with a stream EOF:
Connected successfully
Creating ping stream
Ping stream created successfully
Performing ping test
sending ping to 12D3KooW...
error occurred:
Dialer error: Exceptions from Trio nursery (1 sub-exception)
...
| libp2p.stream_muxer.exceptions.MuxedStreamEOF: Stream closed
|
| The above exception was the direct cause of the following exception:
|
| File "/app/ping_test.py", line 520, in send_ping
| response = await stream.read(PING_LENGTH)
| libp2p.network.stream.exceptions.StreamEOF
The nim listener appears to close the muxed stream after receiving the ping data but before the python dialer reads the response.
Notes
- When nim is the dialer, the failure is in multistream-select framing: the two implementations disagree on protocol negotiation framing over WebSocket (e.g., length-prefixed vs raw framing).
- When python is the dialer, the TCP/noise/muxer negotiation succeeds but the ping protocol fails. The stream is closed by the nim side prematurely, suggesting nim's ping handler may not properly hold the stream open for the response.
- Both implementations work with other peers (go, rust, js) over ws, so the issue is specific to nim-python interop.
- Both mplex and yamux muxers are affected in both directions, confirming the issue is not muxer-specific.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the four listed WebSocket/noise interop tests and compare multistream-select framing when Nim dials with the ping stream lifecycle when Python dials. Inspect the Nim and Python implementations around protocol negotiation and ping handling; done means all four combinations pass for both mplex and yamux.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- distributed-systems, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100