Skip to content

Commit f9b34cc

Browse files
authored
Merge pull request #26 from zaibon/master
Fix used by py-libp2p
2 parents 33a58bb + 7cbe53f commit f9b34cc

File tree

7 files changed

+121
-58
lines changed

7 files changed

+121
-58
lines changed

multiaddr/codec.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ def address_bytes_to_string(proto, buf):
163163
buf = buf[num_bytes_read:]
164164
if len(buf) != size:
165165
raise ValueError("inconsistent lengths")
166-
return base58.b58encode(buf)
166+
return base58.b58encode(buf).decode()
167167
raise ValueError("unknown protocol")
168168

169169

multiaddr/multiaddr.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from .codec import size_for_addr
66
from .codec import string_to_bytes
77
from .codec import bytes_to_string
8+
from .codec import protocol_with_name
89
from .protocols import protocol_with_code
910
from .protocols import read_varint_code
1011

@@ -29,19 +30,18 @@ class Multiaddr(object):
2930
Multiaddr objects are immutable, so `encapsulate` and `decapsulate`
3031
return new objects rather than modify internal state.
3132
"""
32-
def __init__(self, string_addr=None, bytes_addr=None):
33+
34+
def __init__(self, addr):
3335
"""Instantiate a new Multiaddr.
3436
3537
Args:
36-
string_addr (optional): A string-encoded Multiaddr
37-
bytes_addr (optional): A byte-encoded Multiaddr
38+
addr : A string-encoded or a byte-encoded Multiaddr
3839
39-
Only one of string_addr or bytes_addr may be set
4040
"""
41-
if string_addr is not None and bytes_addr is None:
42-
self._bytes = string_to_bytes(string_addr)
43-
elif bytes_addr is not None and string_addr is None:
44-
self._bytes = bytes_addr
41+
if isinstance(addr, str):
42+
self._bytes = string_to_bytes(addr)
43+
elif isinstance(addr, bytes):
44+
self._bytes = addr
4545
else:
4646
raise ValueError("Invalid address type, must be bytes or str")
4747

@@ -91,7 +91,7 @@ def encapsulate(self, other):
9191
"""
9292
mb = self.to_bytes()
9393
ob = other.to_bytes()
94-
return Multiaddr(bytes_addr=b''.join([mb, ob]))
94+
return Multiaddr(b''.join([mb, ob]))
9595

9696
def decapsulate(self, other):
9797
"""Remove a Multiaddr wrapping.
@@ -116,6 +116,11 @@ def decapsulate(self, other):
116116
def value_for_protocol(self, code):
117117
"""Return the value (if any) following the specified protocol."""
118118
from .util import split
119+
120+
if isinstance(code, str):
121+
protocol = protocol_with_name(code)
122+
code = protocol.code
123+
119124
for sub_addr in split(self):
120125
if sub_addr.protocols()[0].code == code:
121126
addr_parts = str(sub_addr).split("/")

multiaddr/protocols.csv

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
1-
code size name
2-
4 32 ip4
3-
6 16 tcp
4-
17 16 udp
5-
33 16 dccp
6-
41 128 ip6
7-
132 16 sctp
8-
301 0 udt
9-
302 0 utp
10-
421 V ipfs
11-
480 0 http
12-
443 0 https
13-
444 10 onion
1+
code, size, name, comment
2+
4, 32, ip4,
3+
6, 16, tcp,
4+
17, 16, udp,
5+
33, 16, dccp,
6+
41, 128, ip6,
7+
42, V, ip6zone, rfc4007 IPv6 zone
8+
53, V, dns, reserved
9+
54, V, dns4,
10+
55, V, dns6,
11+
56, V, dnsaddr,
12+
132, 16, sctp,
13+
301, 0, udt,
14+
302, 0, utp,
15+
400, V, unix,
16+
421, V, p2p, preferred over /ipfs
17+
421, V, ipfs, backwards compatibility; equivalent to /p2p
18+
444, 96, onion,
19+
460, 0, quic,
20+
480, 0, http,
21+
443, 0, https,
22+
477, 0, ws,
23+
478, 0, wss,
24+
479, 0, p2p-websocket-star,
25+
275, 0, p2p-webrtc-star,
26+
276, 0, p2p-webrtc-direct,
27+
290, 0, p2p-circuit,

multiaddr/protocols.py

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,55 @@
1212
P_UDP = 17
1313
P_DCCP = 33
1414
P_IP6 = 41
15+
P_IP6ZONE = 42 # rfc4007 IPv6 zone
16+
P_DNS = 53 # reserved
17+
P_DNS4 = 54
18+
P_DNS6 = 55
19+
P_DNSADDR = 56
1520
P_SCTP = 132
16-
P_UTP = 301
17-
P_UDT = 302
18-
P_IPFS = 421
21+
P_UDT = 301
22+
P_UTP = 302
23+
P_UNIX = 400
24+
P_P2P = 421 # preferred over /ipfs
25+
P_IPFS = 421 # backwards compatibility; equivalent to /p2p
26+
P_ONION = 444
27+
P_QUIC = 460
1928
P_HTTP = 480
2029
P_HTTPS = 443
21-
P_ONION = 444
30+
P_WS = 477
31+
P_WSS = 478
32+
P_P2P_WEBSOCKET_STAR = 479
33+
P_P2P_WEBRTC_STAR = 275
34+
P_P2P_WEBRTC_DIRECT = 276
35+
P_P2P_CIRCUIT = 290
2236

2337
_CODES = [
2438
P_IP4,
2539
P_TCP,
2640
P_UDP,
2741
P_DCCP,
2842
P_IP6,
43+
P_IP6ZONE,
44+
P_DNS,
45+
P_DNS4,
46+
P_DNS6,
47+
P_DNSADDR,
2948
P_SCTP,
30-
P_UTP,
3149
P_UDT,
50+
P_UTP,
51+
P_UNIX,
52+
P_P2P,
3253
P_IPFS,
54+
P_ONION,
55+
P_QUIC,
3356
P_HTTP,
3457
P_HTTPS,
35-
P_ONION,
58+
P_WS,
59+
P_WSS,
60+
P_P2P_WEBSOCKET_STAR,
61+
P_P2P_WEBRTC_STAR,
62+
P_P2P_WEBRTC_DIRECT,
63+
P_P2P_CIRCUIT,
3664
]
3765

3866

@@ -70,18 +98,18 @@ def __init__(self, code, size, name, vcode):
7098

7199
def __eq__(self, other):
72100
return all((self.code == other.code,
73-
self.size == other.size,
74-
self.name == other.name,
75-
self.vcode == other.vcode))
101+
self.size == other.size,
102+
self.name == other.name,
103+
self.vcode == other.vcode))
76104

77105
def __ne__(self, other):
78106
return not (self == other)
79107

80108
def __repr__(self):
81109
return "Protocol(code={code}, name='{name}', size={size})".format(
82-
code=self.code,
83-
size=self.size,
84-
name=self.name)
110+
code=self.code,
111+
size=self.size,
112+
name=self.name)
85113

86114

87115
def code_to_varint(num):
@@ -118,21 +146,32 @@ def read_varint_code(buf):
118146

119147
# Protocols is the list of multiaddr protocols supported by this module.
120148
PROTOCOLS = [
121-
Protocol(P_IP4, 32, "ip4", code_to_varint(P_IP4)),
122-
Protocol(P_TCP, 16, "tcp", code_to_varint(P_TCP)),
123-
Protocol(P_UDP, 16, "udp", code_to_varint(P_UDP)),
124-
Protocol(P_DCCP, 16, "dccp", code_to_varint(P_DCCP)),
125-
Protocol(P_IP6, 128, "ip6", code_to_varint(P_IP6)),
126-
# these require varint:
127-
Protocol(P_SCTP, 16, "sctp", code_to_varint(P_SCTP)),
128-
# Bug in spec? Onion addresses actually need to be 96 bits to account for
129-
# the port number.
130-
Protocol(P_ONION, 96, "onion", code_to_varint(P_ONION)),
131-
Protocol(P_UTP, 0, "utp", code_to_varint(P_UTP)),
132-
Protocol(P_UDT, 0, "udt", code_to_varint(P_UDT)),
133-
Protocol(P_HTTP, 0, "http", code_to_varint(P_HTTP)),
134-
Protocol(P_HTTPS, 0, "https", code_to_varint(P_HTTPS)),
135-
Protocol(P_IPFS, LENGTH_PREFIXED_VAR_SIZE, "ipfs", code_to_varint(P_IPFS)),
149+
Protocol(P_IP4, 32, 'ip4', code_to_varint(P_IP4)),
150+
Protocol(P_TCP, 16, 'tcp', code_to_varint(P_TCP)),
151+
Protocol(P_UDP, 16, 'udp', code_to_varint(P_UDP)),
152+
Protocol(P_DCCP, 16, 'dccp', code_to_varint(P_DCCP)),
153+
Protocol(P_IP6, 128, 'ip6', code_to_varint(P_IP6)),
154+
Protocol(P_IP6ZONE, LENGTH_PREFIXED_VAR_SIZE, 'ip6zone', code_to_varint(P_IP6ZONE)),
155+
Protocol(P_DNS, LENGTH_PREFIXED_VAR_SIZE, 'dns', code_to_varint(P_DNS)),
156+
Protocol(P_DNS4, LENGTH_PREFIXED_VAR_SIZE, 'dns4', code_to_varint(P_DNS4)),
157+
Protocol(P_DNS6, LENGTH_PREFIXED_VAR_SIZE, 'dns6', code_to_varint(P_DNS6)),
158+
Protocol(P_DNSADDR, LENGTH_PREFIXED_VAR_SIZE, 'dnsaddr', code_to_varint(P_DNSADDR)),
159+
Protocol(P_SCTP, 16, 'sctp', code_to_varint(P_SCTP)),
160+
Protocol(P_UDT, 0, 'udt', code_to_varint(P_UDT)),
161+
Protocol(P_UTP, 0, 'utp', code_to_varint(P_UTP)),
162+
Protocol(P_UNIX, LENGTH_PREFIXED_VAR_SIZE, 'unix', code_to_varint(P_UNIX)),
163+
Protocol(P_P2P, LENGTH_PREFIXED_VAR_SIZE, 'p2p', code_to_varint(P_P2P)),
164+
Protocol(P_IPFS, LENGTH_PREFIXED_VAR_SIZE, 'ipfs', code_to_varint(P_IPFS)),
165+
Protocol(P_ONION, 96, 'onion', code_to_varint(P_ONION)),
166+
Protocol(P_QUIC, 0, 'quic', code_to_varint(P_QUIC)),
167+
Protocol(P_HTTP, 0, 'http', code_to_varint(P_HTTP)),
168+
Protocol(P_HTTPS, 0, 'https', code_to_varint(P_HTTPS)),
169+
Protocol(P_WS, 0, 'ws', code_to_varint(P_WS)),
170+
Protocol(P_WSS, 0, 'wss', code_to_varint(P_WSS)),
171+
Protocol(P_P2P_WEBSOCKET_STAR, 0, 'p2p-websocket-star', code_to_varint(P_P2P_WEBSOCKET_STAR)),
172+
Protocol(P_P2P_WEBRTC_STAR, 0, 'p2p-webrtc-star', code_to_varint(P_P2P_WEBRTC_STAR)),
173+
Protocol(P_P2P_WEBRTC_DIRECT, 0, 'p2p-webrtc-direct', code_to_varint(P_P2P_WEBRTC_DIRECT)),
174+
Protocol(P_P2P_CIRCUIT, 0, 'p2p-circuit', code_to_varint(P_P2P_CIRCUIT)),
136175
]
137176

138177
_names_to_protocols = dict((proto.name, proto) for proto in PROTOCOLS)

multiaddr/util.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ def split(ma):
1111
addrs = []
1212
bb = bytes_split(ma.to_bytes())
1313
for addr in bb:
14-
addrs.append(Multiaddr(bytes_addr=binascii.hexlify(addr)))
14+
addrs.append(Multiaddr(binascii.hexlify(addr)))
1515
return addrs
1616

1717

1818
def join(multiaddrs):
1919
bs = []
2020
for ma in multiaddrs:
2121
bs.append(ma.to_bytes())
22-
return Multiaddr(bytes_addr=b''.join(bs))
22+
return Multiaddr(b''.join(bs))
2323

2424

2525
def int_to_hex(i, size):

tests/test_multiaddr.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,15 +209,20 @@ def test_get_value():
209209

210210

211211
def test_bad_initialization_no_params():
212-
with pytest.raises(ValueError):
212+
with pytest.raises(TypeError):
213213
Multiaddr()
214214

215215

216216
def test_bad_initialization_too_many_params():
217-
with pytest.raises(ValueError):
217+
with pytest.raises(TypeError):
218218
Multiaddr("/ip4/0.0.0.0", "")
219219

220220

221+
def test_bad_initialization_wrong_type():
222+
with pytest.raises(ValueError):
223+
Multiaddr(42)
224+
225+
221226
def test_get_value_too_many_fields_protocol(monkeypatch):
222227
"""
223228
This test patches the Multiaddr's string representation to return

tests/test_protocols.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ def patch_protocols(monkeypatch):
127127
monkeypatch.setattr(protocols, '_codes_to_protocols', {})
128128

129129

130-
def test_add_protocol(patch_protocols):
131-
proto = protocols.Protocol(**valid_params())
130+
def test_add_protocol(patch_protocols, valid_params):
131+
proto = protocols.Protocol(**valid_params)
132132
protocols.add_protocol(proto)
133133
assert protocols.PROTOCOLS == [proto]
134134
assert proto.name in protocols._names_to_protocols
@@ -137,8 +137,8 @@ def test_add_protocol(patch_protocols):
137137
protocols.P_TCP, 16, "tcp", protocols.code_to_varint(protocols.P_TCP))
138138

139139

140-
def test_add_protocol_twice(patch_protocols):
141-
proto = protocols.Protocol(**valid_params())
140+
def test_add_protocol_twice(patch_protocols, valid_params):
141+
proto = protocols.Protocol(**valid_params)
142142
protocols.add_protocol(proto)
143143
with pytest.raises(ValueError):
144144
protocols.add_protocol(proto)

0 commit comments

Comments
 (0)