1
1
import argparse
2
+ import logging
3
+ from typing import (
4
+ cast ,
5
+ )
2
6
3
7
import multiaddr
4
8
import trio
5
9
6
- from libp2p import (
7
- new_host ,
10
+ from libp2p .crypto .ed25519 import (
11
+ Ed25519PrivateKey ,
12
+ Ed25519PublicKey ,
13
+ KeyPair ,
8
14
)
9
15
from libp2p .custom_types import (
10
16
TProtocol ,
11
17
)
18
+ from libp2p .host .basic_host import (
19
+ BasicHost ,
20
+ )
12
21
from libp2p .network .stream .net_stream import (
13
22
INetStream ,
14
23
)
24
+ from libp2p .network .swarm import (
25
+ Swarm ,
26
+ )
27
+ from libp2p .peer .id import (
28
+ ID ,
29
+ )
15
30
from libp2p .peer .peerinfo import (
16
31
info_from_p2p_addr ,
17
32
)
33
+ from libp2p .peer .peerstore import (
34
+ PeerStore ,
35
+ )
36
+ from libp2p .security .noise .transport import (
37
+ PROTOCOL_ID ,
38
+ Transport ,
39
+ )
40
+ from libp2p .stream_muxer .yamux .yamux import (
41
+ Yamux ,
42
+ )
43
+ from libp2p .transport .tcp .tcp import (
44
+ TCP ,
45
+ )
46
+ from libp2p .transport .upgrader import (
47
+ TransportUpgrader ,
48
+ )
49
+
50
+ logging .basicConfig (level = logging .DEBUG )
18
51
19
52
PING_PROTOCOL_ID = TProtocol ("/ipfs/ping/1.0.0" )
20
53
PING_LENGTH = 32
@@ -28,10 +61,8 @@ async def handle_ping(stream: INetStream) -> None:
28
61
peer_id = stream .muxed_conn .peer_id
29
62
if payload is not None :
30
63
print (f"received ping from { peer_id } " )
31
-
32
64
await stream .write (payload )
33
65
print (f"responded with pong to { peer_id } " )
34
-
35
66
except Exception :
36
67
await stream .reset ()
37
68
break
@@ -41,45 +72,61 @@ async def send_ping(stream: INetStream) -> None:
41
72
try :
42
73
payload = b"\x01 " * PING_LENGTH
43
74
print (f"sending ping to { stream .muxed_conn .peer_id } " )
44
-
45
75
await stream .write (payload )
46
-
47
76
with trio .fail_after (RESP_TIMEOUT ):
48
77
response = await stream .read (PING_LENGTH )
49
-
50
78
if response == payload :
51
79
print (f"received pong from { stream .muxed_conn .peer_id } " )
52
-
53
80
except Exception as e :
54
81
print (f"error occurred : { e } " )
55
82
56
83
57
84
async def run (port : int , destination : str ) -> None :
58
85
localhost_ip = "127.0.0.1"
59
86
listen_addr = multiaddr .Multiaddr (f"/ip4/0.0.0.0/tcp/{ port } " )
60
- host = new_host ()
87
+
88
+ rust_privkey_bytes = bytes .fromhex (
89
+ "6866d018650288fef506b818f04e6aafeadd96d70752fb16ac4b7f0a5f88f18d"
90
+ )
91
+ rust_pubkey_bytes = bytes .fromhex (
92
+ "0d3fb3dc6cc19c6e58d6f61829fd56af9bbd28aa28d76ccb519f56a79bdace2a"
93
+ )
94
+ private_key = Ed25519PrivateKey .from_bytes (rust_privkey_bytes )
95
+ public_key = Ed25519PublicKey .from_bytes (rust_pubkey_bytes )
96
+ key_pair = KeyPair (private_key , public_key )
97
+ peer_id = ID .from_pubkey (key_pair .public_key )
98
+ logging .debug (f"Local Peer ID: { peer_id .pretty ()} " )
99
+ logging .debug (f"Public Key from Private: { key_pair .public_key .to_bytes ().hex ()} " )
100
+
101
+ noise_transport = Transport (key_pair , noise_privkey = key_pair .private_key )
102
+ tcp_transport = TCP ()
103
+ peerstore = PeerStore ()
104
+ upgrader = TransportUpgrader (
105
+ secure_transports_by_protocol = {PROTOCOL_ID : noise_transport },
106
+ muxer_transports_by_protocol = {cast (TProtocol , "/yamux/1.0.0" ): Yamux },
107
+ )
108
+ swarm = Swarm (
109
+ peer_id = peer_id , peerstore = peerstore , upgrader = upgrader , transport = tcp_transport
110
+ )
111
+ host = BasicHost (network = swarm )
61
112
62
113
async with host .run (listen_addrs = [listen_addr ]), trio .open_nursery () as nursery :
63
114
if not destination :
64
115
host .set_stream_handler (PING_PROTOCOL_ID , handle_ping )
65
-
66
- print (
67
- "Run this from the same folder in another console:\n \n "
116
+ cmd = (
117
+ f"Run this from the same folder in another console:\n \n "
68
118
f"ping-demo -p { int (port ) + 1 } "
69
119
f"-d /ip4/{ localhost_ip } /tcp/{ port } /p2p/{ host .get_id ().pretty ()} \n "
70
120
)
121
+ print (cmd )
71
122
print ("Waiting for incoming connection..." )
72
-
73
123
else :
74
124
maddr = multiaddr .Multiaddr (destination )
75
125
info = info_from_p2p_addr (maddr )
76
126
await host .connect (info )
77
127
stream = await host .new_stream (info .peer_id , [PING_PROTOCOL_ID ])
78
-
79
128
nursery .start_soon (send_ping , stream )
80
-
81
129
return
82
-
83
130
await trio .sleep_forever ()
84
131
85
132
@@ -90,13 +137,10 @@ def main() -> None:
90
137
Then, run another instance with 'python ping.py -p <ANOTHER_PORT> -d <DESTINATION>',
91
138
where <DESTINATION> is the multiaddress of the previous listener host.
92
139
"""
93
-
94
140
example_maddr = (
95
141
"/ip4/127.0.0.1/tcp/8000/p2p/QmQn4SwGkDZKkUEpBRBvTmheQycxAHJUNmVEnjA2v1qe8Q"
96
142
)
97
-
98
143
parser = argparse .ArgumentParser (description = description )
99
-
100
144
parser .add_argument (
101
145
"-p" , "--port" , default = 8000 , type = int , help = "source port number"
102
146
)
@@ -107,10 +151,8 @@ def main() -> None:
107
151
help = f"destination multiaddr string, e.g. { example_maddr } " ,
108
152
)
109
153
args = parser .parse_args ()
110
-
111
154
if not args .port :
112
155
raise RuntimeError ("failed to determine local port" )
113
-
114
156
try :
115
157
trio .run (run , * (args .port , args .destination ))
116
158
except KeyboardInterrupt :
0 commit comments