Skip to content

Commit 4941ad9

Browse files
committed
Merge branch 'fix/gossipsub-identify-aware-publish' of https://github.com/imApoorva36/py-libp2p into fix/gossipsub-identify-aware-publish
2 parents b5f6c43 + 69c5cbf commit 4941ad9

File tree

91 files changed

+4436
-451
lines changed

Some content is hidden

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

91 files changed

+4436
-451
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ fabric.properties
138138

139139
# Django stuff:
140140
*.log
141+
*.pem
142+
*.key
141143
local_settings.py
142144
db.sqlite3
143145

@@ -190,3 +192,5 @@ tests/interop/js_libp2p/js_node/src/package-lock.json
190192

191193
# Sphinx documentation build
192194
_build/
195+
196+
libp2p-forge

docs/examples.autotls.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
examples.autotls package
2+
========================
3+
4+
Submodules
5+
----------
6+
7+
examples.autotls.autotls module
8+
-------------------------------
9+
10+
.. automodule:: examples.autotls.autotls
11+
:members:
12+
:show-inheritance:
13+
:undoc-members:
14+
15+
Module contents
16+
---------------
17+
18+
.. automodule:: examples.autotls
19+
:members:
20+
:show-inheritance:
21+
:undoc-members:

docs/examples.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ Examples
2222
examples.random_walk
2323
examples.multiple_connections
2424
examples.websocket
25+
examples.tls
26+
examples.autotls

docs/examples.tls.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
TLS Examples package
2+
====================
3+
4+
Submodules
5+
----------
6+
7+
examples.tls.example\_tls\_client module
8+
----------------------------------------
9+
10+
.. automodule:: examples.tls.example_tls_client
11+
:members:
12+
:show-inheritance:
13+
:undoc-members:
14+
15+
examples.tls.example\_tls\_server module
16+
----------------------------------------
17+
18+
.. automodule:: examples.tls.example_tls_server
19+
:members:
20+
:show-inheritance:
21+
:undoc-members:
22+
23+
Module contents
24+
---------------
25+
26+
.. automodule:: examples.tls
27+
:members:
28+
:show-inheritance:
29+
:undoc-members:

docs/getting_started.rst

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,36 @@ Now that you have configured a **Transport**, **Crypto** and **Stream Multiplexe
7979
.. literalinclude:: ../examples/doc-examples/example_running.py
8080
:language: python
8181

82+
Bind address and IPv6
83+
^^^^^^^^^^^^^^^^^^^^^
84+
85+
Default listen addresses are controlled by environment variables. Use ``LIBP2P_BIND`` for IPv4 (default ``127.0.0.1``) and ``LIBP2P_BIND_V6`` for IPv6 (default ``::1``). Invalid values fall back to these secure defaults.
86+
87+
**IPv4 (LIBP2P_BIND):**
88+
89+
.. code-block:: bash
90+
91+
# Listen on all IPv4 interfaces (e.g. for tests)
92+
export LIBP2P_BIND=0.0.0.0
93+
python your_script.py
94+
95+
**IPv6 (LIBP2P_BIND_V6):**
96+
97+
.. code-block:: bash
98+
99+
# Use default IPv6 loopback (::1)
100+
python your_script.py
101+
102+
# Listen on all IPv6 interfaces (e.g. for tests or dual-stack)
103+
export LIBP2P_BIND_V6=::
104+
python your_script.py
105+
106+
# Custom IPv6 address
107+
export LIBP2P_BIND_V6=fd00::1
108+
python your_script.py
109+
110+
Multiaddr formats for IPv6 include ``/ip6/::1/tcp/PORT`` and ``/ip6/::1/tcp/PORT/ws`` for WebSocket.
111+
82112
Resource Management
83113
^^^^^^^^^^^^^^^^^^^
84114

docs/release_notes.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ Internal Changes - for py-libp2p Contributors
391391
- Implement ``get_available_interfaces()``, ``get_optimal_binding_address()``, and ``expand_wildcard_address()``
392392
- Update echo example to use dynamic address discovery instead of hardcoded wildcard
393393
- Add safe fallbacks for environments lacking Thin Waist support
394-
- Temporarily disable IPv6 support due to libp2p handshake issues (TODO: re-enable when resolved) (`#811 <https://github.com/libp2p/py-libp2p/issues/811>`__)
394+
- Temporarily disable IPv6 support due to libp2p handshake issues (re-enabled later; use ``LIBP2P_BIND_V6`` to configure IPv6 bind address) (`#811 <https://github.com/libp2p/py-libp2p/issues/811>`__)
395395
- The TODO IK patterns in Noise has been deprecated in specs: https://github.com/libp2p/specs/tree/master/noise#handshake-pattern (`#816 <https://github.com/libp2p/py-libp2p/issues/816>`__)
396396
- Remove the already completed TODO tasks in Peerstore:
397397
TODO: Set up an async task for periodic peer-store cleanup for expired addresses and records.

examples/autotls/__init__.py

Whitespace-only changes.

examples/autotls/autotls.py

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
import argparse
2+
import logging
3+
from pathlib import Path
4+
5+
import multiaddr
6+
import trio
7+
8+
import libp2p
9+
from libp2p import (
10+
generate_new_ed25519_identity,
11+
load_keypair,
12+
new_host,
13+
save_keypair,
14+
)
15+
from libp2p.abc import INetStream
16+
from libp2p.crypto.x25519 import create_new_key_pair as create_new_x25519_key_pair
17+
from libp2p.custom_types import (
18+
TProtocol,
19+
)
20+
from libp2p.identity.identify.identify import (
21+
ID as IDENTIFY_PROTOCOL_ID,
22+
identify_handler_for,
23+
)
24+
from libp2p.peer.peerinfo import (
25+
info_from_p2p_addr,
26+
)
27+
from libp2p.security.noise.transport import (
28+
PROTOCOL_ID as NOISE_PROTOCOL_ID,
29+
Transport as NoiseTransport,
30+
)
31+
from libp2p.security.tls.transport import (
32+
PROTOCOL_ID as TLS_PROTOCOL_ID,
33+
TLSTransport,
34+
)
35+
import libp2p.utils
36+
import libp2p.utils.paths
37+
38+
# Configure logging to show debug logs
39+
root = logging.getLogger()
40+
root.handlers.clear()
41+
root.setLevel(logging.WARNING)
42+
43+
handler = logging.StreamHandler()
44+
handler.setLevel(logging.DEBUG)
45+
handler.setFormatter(logging.Formatter("[%(levelname)s] %(name)s: %(message)s"))
46+
47+
for name in [
48+
"root",
49+
"libp2p.network.basic_host",
50+
"libp2p.security.tls",
51+
"libp2p.autotls.acme",
52+
"libp2p.autotls.broker",
53+
]:
54+
logger = logging.getLogger(name)
55+
logger.setLevel(logging.INFO)
56+
logger.addHandler(handler)
57+
logger.propagate = False
58+
59+
60+
PING_PROTOCOL_ID = TProtocol("/ipfs/ping/1.0.0")
61+
PING_LENGTH = 32
62+
RESP_TIMEOUT = 60
63+
PSK = "dffb7e3135399a8b1612b2aaca1c36a3a8ac2cd0cca51ceeb2ced87d308cac6d"
64+
DIRECTORY = {}
65+
ACME_DIRECTORY_URL = "https://acme-staging-v02.api.letsencrypt.org/directory"
66+
PEER_ID_AUTH_SCHEME = "libp2p-PeerID="
67+
68+
69+
async def handle_ping(stream: INetStream) -> None:
70+
while True:
71+
try:
72+
payload = await stream.read(PING_LENGTH)
73+
peer_id = stream.muxed_conn.peer_id
74+
if payload is not None:
75+
print(f"received ping from {peer_id}")
76+
77+
await stream.write(payload)
78+
print(f"responded with pong to {peer_id}")
79+
80+
except Exception:
81+
await stream.reset()
82+
break
83+
84+
85+
async def send_ping(stream: INetStream) -> None:
86+
try:
87+
payload = b"\x01" * PING_LENGTH
88+
print(f"sending ping to {stream.muxed_conn.peer_id}")
89+
90+
await stream.write(payload)
91+
92+
with trio.fail_after(RESP_TIMEOUT):
93+
response = await stream.read(PING_LENGTH)
94+
95+
if response == payload:
96+
print(f"received pong from {stream.muxed_conn.peer_id}")
97+
98+
except Exception as e:
99+
print(f"error occurred : {e}")
100+
101+
102+
async def run(port: int, destination: str, new: int, transport: str, tls: int) -> None:
103+
from libp2p.utils.address_validation import (
104+
find_free_port,
105+
get_available_interfaces,
106+
)
107+
108+
# Create a libp2p-forge directory for persisting keys and certificates
109+
# Currently the config is for 2 peers exchanging ping/pong
110+
base = Path("libp2p-forge")
111+
(base / "peer1").mkdir(parents=True, exist_ok=True)
112+
(base / "peer2").mkdir(parents=True, exist_ok=True)
113+
114+
enable_autotls = True
115+
if tls == 1:
116+
enable_autotls = False
117+
118+
if port <= 0:
119+
port = find_free_port()
120+
121+
if transport == "tcp":
122+
listen_addrs = get_available_interfaces(port)
123+
if transport == "ws":
124+
listen_addrs = [multiaddr.Multiaddr(f"/ip4/127.0.0.1/tcp/{port}/ws")]
125+
126+
if new == 1:
127+
libp2p.utils.paths.ED25519_PATH = Path("libp2p-forge/peer2/ed25519.pem")
128+
libp2p.utils.paths.AUTOTLS_CERT_PATH = Path(
129+
"libp2p-forge/peer2/autotls-cert.pem"
130+
)
131+
libp2p.utils.paths.AUTOTLS_KEY_PATH = Path("libp2p-forge/peer2/autotls-key.pem")
132+
133+
key_pair = load_keypair()
134+
135+
if key_pair:
136+
logging.info("Loaded existing key-pair")
137+
else:
138+
logging.info("Generated new key-pair...")
139+
key_pair = generate_new_ed25519_identity()
140+
save_keypair(key_pair)
141+
142+
noise_key_pair = create_new_x25519_key_pair()
143+
noise_transport = NoiseTransport(key_pair, noise_privkey=noise_key_pair.private_key)
144+
tls_transport = TLSTransport(key_pair, enable_autotls=enable_autotls)
145+
146+
security_options = {
147+
TLS_PROTOCOL_ID: tls_transport,
148+
NOISE_PROTOCOL_ID: noise_transport,
149+
}
150+
151+
host = new_host(
152+
key_pair=key_pair,
153+
listen_addrs=listen_addrs,
154+
sec_opt=security_options,
155+
enable_autotls=enable_autotls,
156+
)
157+
158+
base_identify_handler = identify_handler_for(host, use_varint_format=False)
159+
async with host.run(listen_addrs=listen_addrs), trio.open_nursery() as nursery:
160+
# Start the peer-store cleanup task
161+
nursery.start_soon(host.get_peerstore().start_cleanup_task, 60)
162+
163+
if not destination:
164+
host.set_stream_handler(IDENTIFY_PROTOCOL_ID, base_identify_handler)
165+
host.set_stream_handler(PING_PROTOCOL_ID, handle_ping)
166+
167+
# Replace/remove this hardcoded IP when running on you own servers
168+
# Check this function to more info: `inititate_autotls_procedure`
169+
if enable_autotls:
170+
await host.initiate_autotls_procedure(public_ip="13.126.88.127")
171+
172+
all_addrs = host.get_addrs()
173+
print("Listener ready, listening on:\n")
174+
for addr in all_addrs:
175+
print(f"{addr}")
176+
177+
all_addrs = host.get_addrs()
178+
if all_addrs:
179+
print(
180+
f"\nRun this from the same folder in another console:\n\n"
181+
f"autotls-demo -d {all_addrs[0]} -new 1 -t {transport} -tls {tls}\n"
182+
)
183+
else:
184+
print("\nWarning: No listening addresses available")
185+
print("Waiting for incoming connection...")
186+
187+
else:
188+
all_addrs = host.get_addrs()
189+
print("Listener ready, listening on:\n")
190+
for addr in all_addrs:
191+
print(f"{addr}")
192+
print("\n\n")
193+
194+
host.set_stream_handler(IDENTIFY_PROTOCOL_ID, base_identify_handler)
195+
196+
# Replace/remove this hardcoded IP when running on you own servers
197+
# Check this function to more info: `inititate_autotls_procedure`
198+
if enable_autotls:
199+
await host.initiate_autotls_procedure(public_ip="13.126.88.127")
200+
201+
maddr = multiaddr.Multiaddr(destination)
202+
info = info_from_p2p_addr(maddr)
203+
await host.connect(info)
204+
stream = await host.new_stream(info.peer_id, [PING_PROTOCOL_ID])
205+
206+
nursery.start_soon(send_ping, stream)
207+
return
208+
209+
await trio.sleep_forever()
210+
211+
212+
def main() -> None:
213+
description = """
214+
This program demonstrates a simple p2p ping application using libp2p.
215+
To use it, first run 'python ping.py -p <PORT>', where <PORT> is the port number.
216+
Then, run another instance with 'python ping.py -p <ANOTHER_PORT> -d <DESTINATION>',
217+
where <DESTINATION> is the multiaddress of the previous listener host.
218+
"""
219+
220+
example_maddr = (
221+
"/ip4/[HOST_IP]/tcp/8000/p2p/QmQn4SwGkDZKkUEpBRBvTmheQycxAHJUNmVEnjA2v1qe8Q"
222+
)
223+
224+
parser = argparse.ArgumentParser(description=description)
225+
parser.add_argument("-p", "--port", default=0, type=int, help="source port number")
226+
227+
parser.add_argument(
228+
"-d",
229+
"--destination",
230+
type=str,
231+
help=f"destination multiaddr string, e.g. {example_maddr}",
232+
)
233+
234+
parser.add_argument("-new", "--new", default=0, type=int, help="Run client")
235+
236+
parser.add_argument(
237+
"-tls", "--tls", default=0, type=int, help="Run with self-signed TLS handshake"
238+
)
239+
240+
parser.add_argument(
241+
"-t",
242+
"--transport",
243+
default="tcp",
244+
type=str,
245+
help="Choose the transport layer for ping TCP/WS",
246+
)
247+
248+
args = parser.parse_args()
249+
250+
try:
251+
trio.run(
252+
run, *(args.port, args.destination, args.new, args.transport, args.tls)
253+
)
254+
except KeyboardInterrupt:
255+
pass
256+
257+
258+
if __name__ == "__main__":
259+
main()

examples/bitswap/bitswap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
# Silence verbose loggers
3131
logging.getLogger("multiaddr.transforms").setLevel(logging.WARNING)
3232
logging.getLogger("multiaddr.codecs.cid").setLevel(logging.WARNING)
33-
logging.getLogger("async_service.Manager").setLevel(logging.WARNING)
33+
logging.getLogger("libp2p.tools.async_service.base").setLevel(logging.WARNING)
3434

3535
logger = logging.getLogger(__name__)
3636

0 commit comments

Comments
 (0)