Skip to content

WIP: Add interoperability test for py-libp2p and js-libp2p #662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

paschal533
Copy link
Contributor

What was wrong?

I'm working on an interoperability test between py-libp2p and js-libp2p to verify the ping protocol (/ipfs/ping/1.0.0) using Yamux (/yamux/1.0.0) and Noise (/noise) for stream multiplexing and encryption. The test setup includes a Python server (py-libp2p) and a JavaScript client (js-libp2p). The client successfully connects to the server, but the ping sequence fails, and the server encounters a RawConnError without invoking the ping handler.

How was it fixed?

I'm still working on it.

To-Do

  • Clean up commit history
  • Add or update documentation related to these changes
  • Add entry to the release notes

Cute Animal Picture

put a cute animal picture link inside the **parentheses**

@paschal533
Copy link
Contributor Author

Hi @Nkovaturient, and @acul71 we can continue working on the Js-libp2p/Py-libp2p interop ping test here. I have created the test structure and a Readme on how to run the test.

@seetadev
Copy link
Contributor

seetadev commented Jun 9, 2025

Hi @Nkovaturient, and @acul71 we can continue working on the Js-libp2p/Py-libp2p interop ping test here. I have created the test structure and a Readme on how to run the test.

@acul71, @paschal533 and @Nkovaturient: Neat effort on JS-libp2p interop.

5 CI/CD tests are failing. Wish if you could collaborate and resolve it.

@Nkovaturient
Copy link

great work @paschal533 , thanks for the clear, stepwise guide.
Wil test it out and look into it with @acul71

@acul71
Copy link
Contributor

acul71 commented Jun 11, 2025

I've tried to run the py-libp2p ping demo and the js-libp2p ping demo

python as dialer - javascript as host

  • The python ping demo can ping the javascript host, even if the javascript host crash with this error:
  libp2p:connection-manager onDisconnect remove all connections for peer QmP71L8NDLcAdWhVC1RbsKi7GKV3AQa1LSjWBsPb3ANuCA +14s
file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-queue/dist/src/recipient.js:7
        this.deferred = Promise.withResolvers();

Javascript host

node --version
v21.7.3

DEBUG="libp2p:*" node src/index.js 
  libp2p:transports adding transport @libp2p/tcp +0ms
  libp2p:connection-manager started +0ms
  libp2p:transports creating listener for @libp2p/tcp on /ip4/127.0.0.1/tcp/0 +5ms
  libp2p:tcp:listener listening on { address: '127.0.0.1', family: 'IPv4', port: 35385 } +0ms
libp2p has started
listening on addresses:
/ip4/127.0.0.1/tcp/35385/p2p/12D3KooWNbs93x5dJ4cTEcsT7qhRmPcXmd196ua5FbmBRLAHM4Tc
no remote peer address given, skipping ping
  libp2p:tcp:listener new inbound connection /ip4/127.0.0.1/tcp/55226 +14s
  libp2p:tcp:socket encrypting inbound connection to /ip4/127.0.0.1/tcp/55226 using /noise +0ms
  libp2p:tcp:socket inbound handling muxers [ '/yamux/1.0.0' ] +11ms
  libp2p:tcp:socket successfully upgraded inbound connection +1ms
  libp2p:connection-manager:connection-pruner checking max connections limit 1/300 +0ms
  libp2p:tcp:listener inbound connection upgraded /ip4/127.0.0.1/tcp/55226 +15ms
  libp2p:connection:inbound:30ey8s1749681693998 incoming stream opened on /ipfs/ping/1.0.0 +0ms
  libp2p:ping incoming ping from QmP71L8NDLcAdWhVC1RbsKi7GKV3AQa1LSjWBsPb3ANuCA +0ms
  libp2p:tcp:socket inbound 127.0.0.1:55226 socket end +11ms
  libp2p:ping incoming ping from QmP71L8NDLcAdWhVC1RbsKi7GKV3AQa1LSjWBsPb3ANuCA complete in 9ms +9ms
  libp2p:yamux sending GoAway reason=NormalTermination +0ms
  libp2p:tcp:socket inbound 127.0.0.1:55226 socket close +2ms
  libp2p:connection:inbound:30ey8s1749681693998 closing connection to /ip4/127.0.0.1/tcp/55226/p2p/QmP71L8NDLcAdWhVC1RbsKi7GKV3AQa1LSjWBsPb3ANuCA +10ms
  libp2p:tcp:socket the inbound 127.0.0.1:55226 socket is already closed +0ms
  libp2p:connection-manager onDisconnect remove all connections for peer QmP71L8NDLcAdWhVC1RbsKi7GKV3AQa1LSjWBsPb3ANuCA +14s
file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-queue/dist/src/recipient.js:7
        this.deferred = Promise.withResolvers();
                                ^

TypeError: Promise.withResolvers is not a function
    at new JobRecipient (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-queue/dist/src/recipient.js:7:33)
    at Job.join (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-queue/dist/src/job.js:46:27)
    at Queue.add (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-queue/dist/src/index.js:161:20)
    at Object.readLock (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/mortice/dist/src/mortice.js:149:30)
    at PersistentStore.getReadLock (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/peer-store/dist/src/store.js:79:45)
    at PersistentPeerStore.get (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/peer-store/dist/src/index.js:54:42)
    at ReconnectQueue.maybeReconnect (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/connection-manager/reconnect-queue.js:44:43)
    at TypedEventEmitter.<anonymous> (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/connection-manager/reconnect-queue.js:34:18)
    at [nodejs.internal.kHybridDispatch] (node:internal/event_target:822:20)
    at TypedEventEmitter.dispatchEvent (node:internal/event_target:757:26)

Node.js v21.7.3

Python dialer

LIBP2P_DEBUG=DEBUG python ping.py -d /ip4/127.0.0.1/tcp/35385/p2p/12D3KooWNbs93x5dJ4cTEcsT7qhRmPcXmd196ua5FbmBRLAHM4Tc
Logging to: /tmp/py-libp2p_20250612_004133_897282_a21ae9b0.log
2025-06-12 00:41:33,981 - libp2p.transport.tcp - DEBUG - serve_tcp 0.0.0.0 0
2025-06-12 00:41:33,983 - libp2p.network.swarm - DEBUG - attempting to dial peer 12D3KooWNbs93x5dJ4cTEcsT7qhRmPcXmd196ua5FbmBRLAHM4Tc
2025-06-12 00:41:33,983 - libp2p.network.swarm - DEBUG - dialed peer 12D3KooWNbs93x5dJ4cTEcsT7qhRmPcXmd196ua5FbmBRLAHM4Tc over base transport
2025-06-12 00:41:33,994 - libp2p.network.swarm - DEBUG - upgraded security for peer 12D3KooWNbs93x5dJ4cTEcsT7qhRmPcXmd196ua5FbmBRLAHM4Tc
2025-06-12 00:41:33,998 - libp2p.network.swarm - DEBUG - upgraded mux for peer 12D3KooWNbs93x5dJ4cTEcsT7qhRmPcXmd196ua5FbmBRLAHM4Tc
2025-06-12 00:41:33,998 - libp2p.network.swarm - DEBUG - successfully dialed peer 12D3KooWNbs93x5dJ4cTEcsT7qhRmPcXmd196ua5FbmBRLAHM4Tc
2025-06-12 00:41:33,998 - libp2p.network.swarm - DEBUG - attempting to open a stream to peer 12D3KooWNbs93x5dJ4cTEcsT7qhRmPcXmd196ua5FbmBRLAHM4Tc
2025-06-12 00:41:33,998 - libp2p.network.swarm - DEBUG - successfully opened a stream to peer 12D3KooWNbs93x5dJ4cTEcsT7qhRmPcXmd196ua5FbmBRLAHM4Tc
sending ping to 12D3KooWNbs93x5dJ4cTEcsT7qhRmPcXmd196ua5FbmBRLAHM4Tc
received pong from 12D3KooWNbs93x5dJ4cTEcsT7qhRmPcXmd196ua5FbmBRLAHM4Tc

javascript as dialer - python as host

  • the Javascript dialer crash with error
libp2p:connection-manager:dial-queue dial to /ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 succeeded +15ms
  libp2p:connection-manager:dial-queue:error could not update last dial failure key for QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 TypeError: Promise.withResolvers is not a function
    at new JobRecipient (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-queue/dist/src/recipient.js:7:33)
    at Job.join (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-queue/dist/src/job.js:46:27)
    at Queue.add (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-queue/dist/src/index.js:161:20)
    at createReleasable (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/mortice/dist/src/mortice.js:102:11)
    at Object.writeLock (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/mortice/dist/src/mortice.js:170:20)
    at PersistentStore.getWriteLock (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/peer-store/dist/src/store.js:93:45)
    at PersistentPeerStore.merge (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/peer-store/dist/src/index.js:92:42)
    at DialQueue.dialPeer (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/connection-manager/dial-queue.js:218:57)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async queue.add.peerId.peerId [as fn] (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/connection-manager/dial-queue.js:148:24) +0ms
  libp2p:connection:outbound:aznwno1749683271493:error could not create new outbound stream on connection to /ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 for protocols [ '/ipfs/ping/1.0.0' ] - AbortError: The operation was aborted

Python host

LIBP2P_DEBUG=DEBUG python ping.py 
Logging to: /tmp/py-libp2p_20250612_010713_628624_f8ee2218.log
2025-06-12 01:07:14,198 - libp2p.transport.tcp - DEBUG - serve_tcp 0.0.0.0 0
Run this from the same folder in another console:

ping-demo -d /ip4/0.0.0.0/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7

Waiting for incoming connection...
2025-06-12 01:07:51,492 - libp2p.network.swarm - DEBUG - upgraded mux for peer 12D3KooWLVo5xNUBR2DzXNRV1LmcK5AK2cNFJWjC7ekhmvPdXeKJ
2025-06-12 01:07:51,492 - libp2p.network.swarm - DEBUG - successfully opened connection to peer 12D3KooWLVo5xNUBR2DzXNRV1LmcK5AK2cNFJWjC7ekhmvPdXeKJ

Javascript dialer

DEBUG="libp2p:*" node src/index.js /ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7
  libp2p:transports adding transport @libp2p/tcp +0ms
  libp2p:connection-manager started +0ms
  libp2p:transports creating listener for @libp2p/tcp on /ip4/127.0.0.1/tcp/0 +4ms
  libp2p:tcp:listener listening on { address: '127.0.0.1', family: 'IPv4', port: 35639 } +0ms
libp2p has started
listening on addresses:
/ip4/127.0.0.1/tcp/35639/p2p/12D3KooWLVo5xNUBR2DzXNRV1LmcK5AK2cNFJWjC7ekhmvPdXeKJ
pinging remote peer at /ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7
  libp2p:ping pinging /ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 +0ms
  libp2p:connection-manager dial QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 +9ms
  libp2p:connection-manager:dial-queue creating dial target for QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 [
  '/ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7'
] +0ms
  libp2p:connection-manager:dial-queue starting dial to QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 +0ms
  libp2p:connection-manager:dial-queue calculating addrs to dial QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 from [
  '/ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7'
] +0ms
  libp2p:connection-manager:dial-queue starting dial to QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 with [
  '/ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7'
] +1ms
  libp2p:tcp dialing /ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 +0ms
  libp2p:tcp connection opened /ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 +1ms
  libp2p:tcp new outbound connection /ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 +1ms
  libp2p:tcp:socket encrypting outbound connection to /ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 using /noise +0ms
  libp2p:tcp:socket outbound selecting muxer [ '/yamux/1.0.0' ] +9ms
  libp2p:tcp:socket selected /yamux/1.0.0 as muxer protocol +1ms
  libp2p:tcp:socket successfully upgraded outbound connection +0ms
  libp2p:connection-manager:connection-pruner checking max connections limit 1/300 +0ms
  libp2p:connection-manager:dial-queue dial to /ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 succeeded +15ms
  libp2p:connection-manager:dial-queue:error could not update last dial failure key for QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 TypeError: Promise.withResolvers is not a function
    at new JobRecipient (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-queue/dist/src/recipient.js:7:33)
    at Job.join (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-queue/dist/src/job.js:46:27)
    at Queue.add (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-queue/dist/src/index.js:161:20)
    at createReleasable (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/mortice/dist/src/mortice.js:102:11)
    at Object.writeLock (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/mortice/dist/src/mortice.js:170:20)
    at PersistentStore.getWriteLock (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/peer-store/dist/src/store.js:93:45)
    at PersistentPeerStore.merge (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/peer-store/dist/src/index.js:92:42)
    at DialQueue.dialPeer (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/connection-manager/dial-queue.js:218:57)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async queue.add.peerId.peerId [as fn] (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/connection-manager/dial-queue.js:148:24) +0ms
  libp2p:connection:outbound:aznwno1749683271493:error could not create new outbound stream on connection to /ip4/127.0.0.1/tcp/33879/p2p/QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 for protocols [ '/ipfs/ping/1.0.0' ] - AbortError: The operation was aborted
  libp2p:connection:outbound:aznwno1749683271493:error     at raceSignal (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/race-signal/dist/src/index.js:29:19)
  libp2p:connection:outbound:aznwno1749683271493:error     at Object.read (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-byte-stream/dist/src/index.js:58:47)
  libp2p:connection:outbound:aznwno1749683271493:error     at Object.read (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-length-prefixed-stream/dist/src/index.js:45:49)
  libp2p:connection:outbound:aznwno1749683271493:error     at read (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/multistream-select/dist/src/multistream.js:21:30)
  libp2p:connection:outbound:aznwno1749683271493:error     at Module.readString (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/multistream-select/dist/src/multistream.js:32:23)
  libp2p:connection:outbound:aznwno1749683271493:error     at Module.select (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/multistream-select/dist/src/select.js:72:38)
  libp2p:connection:outbound:aznwno1749683271493:error     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
  libp2p:connection:outbound:aznwno1749683271493:error     at async ConnectionImpl.newStream [as _newStream] (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/upgrader.js:353:50)
  libp2p:connection:outbound:aznwno1749683271493:error     at async ConnectionImpl.newStream (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/connection/index.js:95:24)
  libp2p:connection:outbound:aznwno1749683271493:error     at async Ping.ping (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/ping/dist/src/ping.js:112:22) +0ms
  libp2p:yamux:outbound:1 abort with error AbortError: The operation was aborted
    at raceSignal (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/race-signal/dist/src/index.js:29:19)
    at Object.read (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-byte-stream/dist/src/index.js:58:47)
    at Object.read (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-length-prefixed-stream/dist/src/index.js:45:49)
    at read (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/multistream-select/dist/src/multistream.js:21:30)
    at Module.readString (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/multistream-select/dist/src/multistream.js:32:23)
    at Module.select (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/multistream-select/dist/src/select.js:72:38)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ConnectionImpl.newStream [as _newStream] (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/upgrader.js:353:50)
    at async ConnectionImpl.newStream (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/connection/index.js:95:24)
    at async Ping.ping (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/ping/dist/src/ping.js:112:22) {
  type: 'aborted',
  code: 'ABORT_ERR'
} +0ms
  libp2p:yamux:outbound:1 try to send reset to remote +0ms
  libp2p:ping:error error while pinging QmZ8PzMWNEev59x3aoKBN2B9uSwkVVqvVgy17SBUcbJtk7 AbortError: The operation was aborted
    at raceSignal (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/race-signal/dist/src/index.js:29:19)
    at Object.read (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-byte-stream/dist/src/index.js:58:47)
    at Object.read (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-length-prefixed-stream/dist/src/index.js:45:49)
    at read (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/multistream-select/dist/src/multistream.js:21:30)
    at Module.readString (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/multistream-select/dist/src/multistream.js:32:23)
    at Module.select (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/multistream-select/dist/src/select.js:72:38)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ConnectionImpl.newStream [as _newStream] (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/upgrader.js:353:50)
    at async ConnectionImpl.newStream (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/connection/index.js:95:24)
    at async Ping.ping (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/ping/dist/src/ping.js:112:22) {
  type: 'aborted',
  code: 'ABORT_ERR'
} +0ms
node:internal/process/esm_loader:34
      internalBinding('errors').triggerUncaughtException(
                                ^

AbortError: The operation was aborted
    at raceSignal (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/race-signal/dist/src/index.js:29:19)
    at Object.read (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-byte-stream/dist/src/index.js:58:47)
    at Object.read (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/it-length-prefixed-stream/dist/src/index.js:45:49)
    at read (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/multistream-select/dist/src/multistream.js:21:30)
    at Module.readString (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/multistream-select/dist/src/multistream.js:32:23)
    at Module.select (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/multistream-select/dist/src/select.js:72:38)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async ConnectionImpl.newStream [as _newStream] (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/upgrader.js:353:50)
    at async ConnectionImpl.newStream (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/libp2p/dist/src/connection/index.js:95:24)
    at async Ping.ping (file:///home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/js-libp2p-ping/node_modules/@libp2p/ping/dist/src/ping.js:112:22) {
  type: 'aborted',
  code: 'ABORT_ERR'
}

Node.js v21.7.3

@acul71
Copy link
Contributor

acul71 commented Jun 12, 2025

JavaScript to Python libp2p Ping Failure Analysis

Overview

This document analyzes why the JavaScript libp2p client fails to ping the Python libp2p server, while the Python client can successfully ping the JavaScript server.

Connection Sequence

The JavaScript client successfully:

  1. Starts up
  2. Establishes a TCP connection
  3. Upgrades the connection with Noise encryption
  4. Negotiates Yamux as the stream multiplexer

Failure Point

The failure occurs during the protocol negotiation phase with the error:

libp2p:connection:outbound:86qm9n1749689214122:error could not create new outbound stream on connection to /ip4/127.0.0.1/tcp/8000/p2p/QmR2XWcWrbMaNcYD2KmFqyrsdKUqkvdEzjRZ3hY7VMso4b for protocols [ '/ipfs/ping/1.0.0' ] - AbortError: The operation was aborted

Root Cause Analysis

The issue appears to be a timing problem in the protocol negotiation:

  1. The JavaScript client attempts to negotiate the /ipfs/ping/1.0.0 protocol
  2. The Python server receives the connection and starts the Yamux session
  3. The protocol negotiation times out before completion, triggering an AbortError

This is likely happening because:

  • The Python server is taking too long to respond to the protocol negotiation request
  • The JavaScript client has a timeout that's being triggered before the Python server can complete the negotiation

Technical Details

The error occurs in the multistream-select protocol negotiation phase, which is used to negotiate which protocol to use for the stream. The JavaScript client is aborting the operation before the Python server can complete the negotiation.

Potential Solutions

To resolve this issue, you could try:

  1. Increasing the timeout in the JavaScript client
  2. Making the protocol negotiation in the Python server more responsive
  3. Ensuring both implementations are using compatible versions of the multistream-select protocol

Conclusion

The fact that the Python client can ping the JavaScript server but not vice versa suggests there might be an asymmetry in how the two implementations handle protocol negotiation timing. This needs to be addressed to ensure proper bidirectional interoperability between the implementations.

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.

4 participants