Skip to content

Commit 33e211d

Browse files
committed
test: implement ser/unser of I2P addresses in functional tests
1 parent 8674281 commit 33e211d

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

test/functional/test_framework/messages.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
Classes use __slots__ to ensure extraneous attributes aren't accidentally added
1919
by tests, compromising their intended effect.
2020
"""
21+
from base64 import b32decode, b32encode
2122
from codecs import encode
2223
import copy
2324
import hashlib
@@ -207,15 +208,20 @@ class CAddress:
207208

208209
# see https://github.com/bitcoin/bips/blob/master/bip-0155.mediawiki
209210
NET_IPV4 = 1
211+
NET_I2P = 5
210212

211213
ADDRV2_NET_NAME = {
212-
NET_IPV4: "IPv4"
214+
NET_IPV4: "IPv4",
215+
NET_I2P: "I2P"
213216
}
214217

215218
ADDRV2_ADDRESS_LENGTH = {
216-
NET_IPV4: 4
219+
NET_IPV4: 4,
220+
NET_I2P: 32
217221
}
218222

223+
I2P_PAD = "===="
224+
219225
def __init__(self):
220226
self.time = 0
221227
self.nServices = 1
@@ -255,24 +261,33 @@ def deserialize_v2(self, f):
255261
self.nServices = deser_compact_size(f)
256262

257263
self.net = struct.unpack("B", f.read(1))[0]
258-
assert self.net == self.NET_IPV4
264+
assert self.net in (self.NET_IPV4, self.NET_I2P)
259265

260266
address_length = deser_compact_size(f)
261267
assert address_length == self.ADDRV2_ADDRESS_LENGTH[self.net]
262268

263-
self.ip = socket.inet_ntoa(f.read(4))
269+
addr_bytes = f.read(address_length)
270+
if self.net == self.NET_IPV4:
271+
self.ip = socket.inet_ntoa(addr_bytes)
272+
else:
273+
self.ip = b32encode(addr_bytes)[0:-len(self.I2P_PAD)].decode("ascii").lower() + ".b32.i2p"
264274

265275
self.port = struct.unpack(">H", f.read(2))[0]
266276

267277
def serialize_v2(self):
268278
"""Serialize in addrv2 format (BIP155)"""
269-
assert self.net == self.NET_IPV4
279+
assert self.net in (self.NET_IPV4, self.NET_I2P)
270280
r = b""
271281
r += struct.pack("<I", self.time)
272282
r += ser_compact_size(self.nServices)
273283
r += struct.pack("B", self.net)
274284
r += ser_compact_size(self.ADDRV2_ADDRESS_LENGTH[self.net])
275-
r += socket.inet_aton(self.ip)
285+
if self.net == self.NET_IPV4:
286+
r += socket.inet_aton(self.ip)
287+
else:
288+
sfx = ".b32.i2p"
289+
assert self.ip.endswith(sfx)
290+
r += b32decode(self.ip[0:-len(sfx)] + self.I2P_PAD, True)
276291
r += struct.pack(">H", self.port)
277292
return r
278293

0 commit comments

Comments
 (0)