feat: implemented the perf protocol#1176
Conversation
|
cc: @lla-dane |
|
@ItshMoh : Hi Mohan. This is great progress — thanks a lot for pushing this forward. 👏 The implementation looks solid, the structure is clean, and the example + protocol summary make it very easy to understand and try out. This is a meaningful step toward better benchmarking and comparison across libp2p implementations. One small but important organizational point: could you please move this PR to the test-plans repository instead? The perf protocol implementation and examples fit much better there, especially since it’s focused on performance measurement, benchmarking, and experimentation rather than core protocol behavior. Link to the repository: https://github.com/libp2p/test-plans. Please also visit https://github.com/libp2p/test-plans/blob/master/docs/write-a-perf-test-app.md Once it’s in the test-plans repo, we can:
Everything you’ve done so far — including the module layout, example, and local testing — will carry over nicely. So this is more about placing it in the right home than changing the direction of the work. Really nice momentum here. Looking forward to the updated PR, and happy to review again once it’s up in test-plans. Thanks again for the effort and execution 🙌 |
|
Trying the example I can see this failure for big data (venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$ python perf_example.py
Perf server ready, listening on:
/ip4/127.0.0.1/tcp/55857/p2p/12D3KooWMFBZfDKd3pxKmRJCVsvHqp9hUo3WUb9mqTHgP1ejSA2J
Protocol: /perf/1.0.0
Run client with:
python perf_example.py -d /ip4/127.0.0.1/tcp/55857/p2p/12D3KooWMFBZfDKd3pxKmRJCVsvHqp9hUo3WUb9mqTHgP1ejSA2J
Waiting for incoming perf requests...
#################################
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$ python perf_example.py -d /ip4/127.0.0.1/tcp/53573/p2p/12D3KooWPcmQezXgRAB6wDCgDmj8d2J8RuFvXu39G8iKa6cP8QEy -u 100 -D 1000
Connecting to 12D3KooWPcmQezXgRAB6wDCgDmj8d2J8RuFvXu39G8iKa6cP8QEy...
Failed to open TCP stream: all attempts to connect to 127.0.0.1:53573 failed
Failed to open TCP stream: all attempts to connect to 127.0.0.1:53573 failed
Failed to open TCP stream: all attempts to connect to 127.0.0.1:53573 failed
Failed to open TCP stream: all attempts to connect to 127.0.0.1:53573 failed
+ Exception Group Traceback (most recent call last):
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf/perf_example.py", line 170, in <module>
| main()
| ~~~~^^
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf/perf_example.py", line 164, in main
| trio.run(run, args.port, args.destination, args.upload, args.download)
| ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/venv/lib/python3.13/site-packages/trio/_core/_run.py", line 2549, in run
| raise runner.main_task_outcome.error
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf/perf_example.py", line 119, in run
| async with host.run(listen_addrs=listen_addrs):
| ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/home/luca/.local/share/uv/python/cpython-3.13.11-linux-x86_64-gnu/lib/python3.13/contextlib.py", line 235, in __aexit__
| await self.gen.athrow(value)
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/libp2p/host/basic_host.py", line 357, in _run
| async with background_trio_service(network):
| ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
| File "/home/luca/.local/share/uv/python/cpython-3.13.11-linux-x86_64-gnu/lib/python3.13/contextlib.py", line 235, in __aexit__
| await self.gen.athrow(value)
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/libp2p/tools/async_service/trio_service.py", line 460, in background_trio_service
| async with trio.open_nursery() as nursery:
| ~~~~~~~~~~~~~~~~~^^
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/venv/lib/python3.13/site-packages/trio/_core/_run.py", line 1125, in __aexit__
| raise combined_error_from_nursery
| ExceptionGroup: Exceptions from Trio nursery (1 sub-exception)
+-+---------------- 1 ----------------
| libp2p.exceptions.MultiError: Error 1: fail to open connection to peer 12D3KooWPcmQezXgRAB6wDCgDmj8d2J8RuFvXu39G8iKa6cP8QEy
|
| The above exception was the direct cause of the following exception:
|
| Traceback (most recent call last):
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/libp2p/tools/async_service/trio_service.py", line 465, in background_trio_service
| yield manager
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/libp2p/host/basic_host.py", line 374, in _run
| yield
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf/perf_example.py", line 122, in run
| await run_client(
| ...<5 lines>...
| )
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf/perf_example.py", line 59, in run_client
| await host.connect(info)
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/libp2p/host/basic_host.py", line 675, in connect
| connections = await self._network.dial_peer(peer_info.peer_id)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/libp2p/network/swarm.py", line 275, in dial_peer
| raise SwarmException(
| ...<2 lines>...
| ) from MultiError(exceptions)
| libp2p.network.exceptions.SwarmException: unable to connect to 12D3KooWPcmQezXgRAB6wDCgDmj8d2J8RuFvXu39G8iKa6cP8QEy, no addresses established a successful connection (with exceptions)
+------------------------------------
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$
(venv) luca@r17:~/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf$ python perf_example.py -d /ip4/127.0.0.1/tcp/53573/p2p/12D3KooWPcmQezXgRAB6wDCgDmj8d2J8RuFvXu39G8iKa6cP8QEy -u 1000 -D 100
Connecting to 12D3KooWPcmQezXgRAB6wDCgDmj8d2J8RuFvXu39G8iKa6cP8QEy...
Failed to open TCP stream: all attempts to connect to 127.0.0.1:53573 failed
Failed to open TCP stream: all attempts to connect to 127.0.0.1:53573 failed
Failed to open TCP stream: all attempts to connect to 127.0.0.1:53573 failed
Failed to open TCP stream: all attempts to connect to 127.0.0.1:53573 failed
+ Exception Group Traceback (most recent call last):
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf/perf_example.py", line 170, in <module>
| main()
| ~~~~^^
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf/perf_example.py", line 164, in main
| trio.run(run, args.port, args.destination, args.upload, args.download)
| ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/venv/lib/python3.13/site-packages/trio/_core/_run.py", line 2549, in run
| raise runner.main_task_outcome.error
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf/perf_example.py", line 119, in run
| async with host.run(listen_addrs=listen_addrs):
| ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/home/luca/.local/share/uv/python/cpython-3.13.11-linux-x86_64-gnu/lib/python3.13/contextlib.py", line 235, in __aexit__
| await self.gen.athrow(value)
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/libp2p/host/basic_host.py", line 357, in _run
| async with background_trio_service(network):
| ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
| File "/home/luca/.local/share/uv/python/cpython-3.13.11-linux-x86_64-gnu/lib/python3.13/contextlib.py", line 235, in __aexit__
| await self.gen.athrow(value)
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/libp2p/tools/async_service/trio_service.py", line 460, in background_trio_service
| async with trio.open_nursery() as nursery:
| ~~~~~~~~~~~~~~~~~^^
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/venv/lib/python3.13/site-packages/trio/_core/_run.py", line 1125, in __aexit__
| raise combined_error_from_nursery
| ExceptionGroup: Exceptions from Trio nursery (1 sub-exception)
+-+---------------- 1 ----------------
| libp2p.exceptions.MultiError: Error 1: fail to open connection to peer 12D3KooWPcmQezXgRAB6wDCgDmj8d2J8RuFvXu39G8iKa6cP8QEy
|
| The above exception was the direct cause of the following exception:
|
| Traceback (most recent call last):
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/libp2p/tools/async_service/trio_service.py", line 465, in background_trio_service
| yield manager
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/libp2p/host/basic_host.py", line 374, in _run
| yield
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf/perf_example.py", line 122, in run
| await run_client(
| ...<5 lines>...
| )
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/examples/perf/perf_example.py", line 59, in run_client
| await host.connect(info)
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/libp2p/host/basic_host.py", line 675, in connect
| connections = await self._network.dial_peer(peer_info.peer_id)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| File "/home/luca/Informatica/Learning/PNL_Launchpad_Curriculum/Libp2p/py-libp2p/libp2p/network/swarm.py", line 275, in dial_peer
| raise SwarmException(
| ...<2 lines>...
| ) from MultiError(exceptions)
| libp2p.network.exceptions.SwarmException: unable to connect to 12D3KooWPcmQezXgRAB6wDCgDmj8d2J8RuFvXu39G8iKa6cP8QEy, no addresses established a successful connection (with exceptions)
+------------------------------------ |
|
hey @acul71 thanks for pointing it out . Now it is working , You can try. |
|
Update the Also include |
|
First version of python perf interop script in Summary of what’s in the report: Contents:
Failure categories:
|
|
@ItshMoh We could modify the example like transports: [quic-v1, tcp, ws]
secureChannels: [noise, tls]
muxers: [yamux, mplex]to see if they work, and also understand where we can optimize for throughput (yamux is awfully slow) |
|
Eventually I (we can) lint this PR and merge but opening a new issue for enhancing |
|
hey @acul71 thanks for the perf_test.py . |
Yeah we can merge this pr after i move the interface definitions in the abc.py file . We can eventually support the different transports and muxers in different issue. @acul71 Thanks again for the help. |
@lla-dane Done. |
@ItshMoh Thanks for you contribution. Before there are some issues to fix and decision to make like @seetadev perf module question about keeping it here in py-libp2p or make it an external lib (if possible) Read this review and then we go from there. AI Pull Request Review: #1176 — feat: implemented the perf protocolReview version: 1 1. Summary of ChangesThis PR implements the libp2p perf protocol ( What changed:
Protocol flow (aligned with spec):
Architecture: Fits alongside other protocol modules (identify, ping, etc.). No breaking changes or deprecations. The PR body references Issue #1169 but does not use "Fixes #1169" or "Closes #1169". 2. Branch Sync Status and Merge ConflictsBranch Sync Status
Merge Conflict Analysis
3. Strengths
4. Issues FoundCritical
Major
Minor (Lint — must fix for CI)
5. Security Review
6. Documentation and Examples
7. Newsfragment Requirement
8. Tests and ValidationLinting (
|
Ok leave it like that |
@acul71 I have replied to the @pacrob questions. it will not be a blocker if no review by him is done. |
|
@acul71 Should i file this issue for the system-wide implementation of |
|
@pacrob Fixed the changes as you have said. Thanks, for the review. |
|
Just noticed that some tests have gone in the top-level Looking at the I've noted a couple other small things. Once those are fixed and we determine where the interop tests should go (I'm not even sure why we have a top-level interop folder?), this should be good to go. |
This is a convention of unified-test (new test-plans), that the "material"
needed for building a Docker image with the configured python test script can live in a implementation repo directory . The unified-test, allow also this code to live (only) in unified-test repo itself. This is the current state of perf test (python x python) Result summary
Passing cases
Failing cases
Direct failure reason
So this is a genuine test-execution failure (timeouts + one QUIC runtime error), not an artifact upload/workflow issue. |
Use multiaddr items when rebuilding loopback-rewritten addresses in interop perf so protocol/value pairs are handled correctly, and align perf write block size default to 64KiB for js-libp2p parity. Co-authored-by: Cursor <cursoragent@cursor.com>
Issue #1169
Description
This PR implements the libp2p perf protocol as specified in the libp2p specs. The perf protocol enables measuring transfer performance (throughput) between libp2p nodes, which is useful for benchmarking and comparing implementations.
Protocol Summary
Usage
# Terminal 1 - Start server python3 examples/perf/perf_example.py -p 8000Tested locally with py-libp2p nodes communicating with each other. Example output:

Cute Animal Picture