Skip to content

Commit 0d9d9ec

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/pg
2 parents f69098d + e2c3a83 commit 0d9d9ec

61 files changed

Lines changed: 3027 additions & 146 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.pre-commit-config.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,11 @@ repos:
4949
language: system
5050
always_run: true
5151
pass_filenames: false
52+
- repo: local
53+
hooks:
54+
- id: path-audit
55+
name: Cross-platform path handling audit (P0/P1)
56+
entry: python scripts/audit_paths.py --summary-only --fail-on-p1
57+
language: system
58+
always_run: true
59+
pass_filenames: false

docs/conf.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,26 @@
1212

1313
# If extensions (or modules to document with autodoc) are in another directory,
1414
# add these directories to sys.path here. If the directory is relative to the
15-
# documentation root, use os.path.abspath to make it absolute, like shown here.
15+
# documentation root, use pathlib to resolve it cross-platform.
1616

1717
import doctest
18-
import os
18+
from pathlib import Path
1919
import sys
20-
21-
sys.path.insert(0, os.path.abspath(".."))
2220
from unittest.mock import MagicMock
2321

22+
# Add project root to path (cross-platform)
23+
_docs_dir = Path(__file__).resolve().parent
24+
_project_root = _docs_dir.parent
25+
sys.path.insert(0, str(_project_root))
26+
2427
try:
2528
import tomllib
2629
except ModuleNotFoundError:
2730
# For Python < 3.11
2831
import tomli as tomllib # type: ignore (In case of >3.11 Pyrefly doesnt find tomli , which is right but a false flag)
2932

30-
# Path to pyproject.toml (assuming conf.py is in a 'docs' subdirectory)
31-
pyproject_path = os.path.join(os.path.dirname(__file__), "..", "pyproject.toml")
33+
# Path to pyproject.toml (conf.py is in 'docs', project root is parent)
34+
pyproject_path = _project_root / "pyproject.toml"
3235

3336
with open(pyproject_path, "rb") as f:
3437
pyproject_data = tomllib.load(f)

docs/contributing.rst

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,16 @@ This library uses type hints, which are enforced by the ``mypy`` tool (part of t
354354
``pre-commit`` checks). All new code is required to land with type hints, with the
355355
exception of code within the ``tests`` directory.
356356

357+
Path handling
358+
^^^^^^^^^^^^^
359+
360+
Use the cross-platform path utilities in ``libp2p.utils.paths`` instead of ``os.path``
361+
or hard-coded separators. Prefer ``join_paths()`` over ``os.path.join()``,
362+
``get_script_dir(__file__)`` over ``os.path.dirname(__file__)``, and ``create_temp_file()``
363+
or ``get_temp_dir()`` over hard-coded ``/tmp/`` or ``C:\\``. This keeps the codebase
364+
working on Windows, macOS, and Linux. Run ``python scripts/audit_paths.py`` to check
365+
for path issues; the same audit runs in ``pre-commit`` and fails on P0/P1 issues.
366+
357367
Documentation
358368
~~~~~~~~~~~~~
359369

@@ -393,14 +403,15 @@ To add a new example (e.g., identify):
393403
.. code:: sh
394404
395405
.....
396-
Activate with `source /tmp/tmpb9ybjgtg/package-smoke-test/bin/activate`
406+
Activate with ``source <temp-dir>/package-smoke-test/bin/activate``
407+
(The exact path is shown by the script; use that path.)
397408
Press enter when the test has completed. The directory will be deleted.
398409
399410
Then test the example:
400411

401412
.. code:: sh
402413
403-
source /tmp/tmpb9ybjgtg/package-smoke-test/bin/activate
414+
source <temp-dir>/package-smoke-test/bin/activate
404415
(package-smoke-test) $ identify-demo
405416
406417
Pull Requests

docs/examples.bitswap.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ Client Output
153153
======================================================================
154154
Size: 2.5 MB
155155
Filename: document.pdf (from metadata)
156-
✓ Saved to: /tmp/document.pdf
156+
✓ Saved to: <temp-dir>/document.pdf
157157
======================================================================
158158
159159
Features

docs/examples.perf.rst

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
Perf Protocol Demo
2+
==================
3+
4+
This example demonstrates how to use the libp2p ``perf`` protocol to measure
5+
transfer performance between two nodes.
6+
7+
The perf protocol sends and receives data to measure throughput, reporting
8+
both intermediary progress and final results.
9+
10+
Running the Example
11+
-------------------
12+
13+
First, start the server in one terminal:
14+
15+
.. code-block:: console
16+
17+
$ python examples/perf/perf_example.py -p 8000
18+
19+
Perf server ready, listening on:
20+
/ip4/127.0.0.1/tcp/8000/p2p/QmXfptdHU6hqG95JswxYVUH4bphcK8y18mhFcgUQFe6fCN
21+
22+
Protocol: /perf/1.0.0
23+
24+
Run client with:
25+
python perf_example.py -d /ip4/127.0.0.1/tcp/8000/p2p/QmXfptdHU6hqG95JswxYVUH4bphcK8y18mhFcgUQFe6fCN
26+
27+
Waiting for incoming perf requests...
28+
29+
Then, in another terminal, run the client with the multiaddr from the server:
30+
31+
.. code-block:: console
32+
33+
$ python examples/perf/perf_example.py -d /ip4/127.0.0.1/tcp/8000/p2p/QmXfptdHU6hqG95JswxYVUH4bphcK8y18mhFcgUQFe6fCN
34+
35+
Connecting to QmXfptdHU6hqG95JswxYVUH4bphcK8y18mhFcgUQFe6fCN...
36+
Connected!
37+
38+
Measuring performance:
39+
Upload: 2560 bytes
40+
Download: 2560 bytes
41+
42+
Uploading: 2560 bytes in 0.01s (256000 bytes/s)
43+
Downloading: 2560 bytes in 0.01s (256000 bytes/s)
44+
45+
==================================================
46+
Performance Results:
47+
Total time: 0.025 seconds
48+
Uploaded: 2560 bytes
49+
Downloaded: 2560 bytes
50+
Total data: 5120 bytes
51+
Throughput: 204800 bytes/s
52+
==================================================
53+
54+
Command Line Options
55+
--------------------
56+
57+
.. code-block:: text
58+
59+
-p, --port Listening port (default: random free port)
60+
-d, --destination Destination multiaddr (if not set, runs as server)
61+
-u, --upload Upload size in units of 256 bytes (default: 10)
62+
-D, --download Download size in units of 256 bytes (default: 10)
63+
64+
Source Code
65+
-----------
66+
67+
.. literalinclude:: ../examples/perf/perf_example.py
68+
:language: python
69+
:linenos:

docs/examples.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ Examples
2727
examples.websocket
2828
examples.tls
2929
examples.autotls
30+
examples.perf

docs/libp2p.perf.rst

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
libp2p.perf package
2+
===================
3+
4+
The perf module implements the libp2p performance measurement protocol,
5+
which allows measuring throughput between two libp2p nodes by sending
6+
and receiving configurable amounts of data.
7+
8+
Submodules
9+
----------
10+
11+
libp2p.perf.constants module
12+
----------------------------
13+
14+
.. automodule:: libp2p.perf.constants
15+
:members:
16+
:undoc-members:
17+
:show-inheritance:
18+
19+
libp2p.perf.types module
20+
------------------------
21+
22+
.. automodule:: libp2p.perf.types
23+
:members:
24+
:undoc-members:
25+
:show-inheritance:
26+
27+
libp2p.perf.perf\_service module
28+
--------------------------------
29+
30+
.. automodule:: libp2p.perf.perf_service
31+
:members:
32+
:undoc-members:
33+
:show-inheritance:
34+
35+
Module contents
36+
---------------
37+
38+
.. automodule:: libp2p.perf
39+
:members:
40+
:undoc-members:
41+
:show-inheritance:

docs/libp2p.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Subpackages
1616
libp2p.kad_dht
1717
libp2p.network
1818
libp2p.peer
19+
libp2p.perf
1920
libp2p.protocol_muxer
2021
libp2p.pubsub
2122
libp2p.rcmgr

examples/autotls/autotls.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,17 @@ async def run(port: int, destination: str, new: int, transport: str, tls: int) -
120120

121121
if transport == "tcp":
122122
listen_addrs = get_available_interfaces(port)
123-
if transport == "ws":
123+
elif transport == "ws":
124124
listen_addrs = [multiaddr.Multiaddr(f"/ip4/127.0.0.1/tcp/{port}/ws")]
125+
elif transport == "quic":
126+
# QUIC uses UDP addresses with /quic-v1 suffix
127+
quic_addrs = []
128+
for addr in get_available_interfaces(port):
129+
addr_str = str(addr).replace("/tcp/", "/udp/") + "/quic-v1"
130+
quic_addrs.append(multiaddr.Multiaddr(addr_str))
131+
listen_addrs = quic_addrs
132+
else:
133+
raise ValueError(f"Unknown transport: {transport}. Use tcp, ws, or quic.")
125134

126135
if new == 1:
127136
libp2p.utils.paths.ED25519_PATH = Path("libp2p-forge/peer2/ed25519.pem")
@@ -148,11 +157,15 @@ async def run(port: int, destination: str, new: int, transport: str, tls: int) -
148157
NOISE_PROTOCOL_ID: noise_transport,
149158
}
150159

160+
# Create host with QUIC support if transport is quic
161+
enable_quic = transport == "quic"
162+
151163
host = new_host(
152164
key_pair=key_pair,
153165
listen_addrs=listen_addrs,
154166
sec_opt=security_options,
155167
enable_autotls=enable_autotls,
168+
enable_quic=enable_quic,
156169
)
157170

158171
base_identify_handler = identify_handler_for(host, use_varint_format=False)
@@ -242,7 +255,7 @@ def main() -> None:
242255
"--transport",
243256
default="tcp",
244257
type=str,
245-
help="Choose the transport layer for ping TCP/WS",
258+
help="Choose the transport layer: tcp, ws, or quic",
246259
)
247260

248261
args = parser.parse_args()

0 commit comments

Comments
 (0)