Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/addresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ def encodeBase58(num, alphabet=ALPHABET):
num: The number to encode
alphabet: The alphabet to use for encoding
"""
if num < 0:
return None
if num == 0:
return alphabet[0]
arr = []
Expand Down
12 changes: 6 additions & 6 deletions src/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ def isProofOfWorkSufficient(
# Packet creation


def CreatePacket(command, payload=''):
def CreatePacket(command, payload=b''):
"""Construct and return a packet"""
payload_length = len(payload)
checksum = hashlib.sha512(payload).digest()[0:4]
Expand All @@ -302,7 +302,7 @@ def assembleVersionMessage(
Construct the payload of a version message,
return the resulting bytes of running `CreatePacket` on it
"""
payload = ''
payload = b''
payload += pack('>L', 3) # protocol version.
# bitflags of the services I offer.
payload += pack(
Expand Down Expand Up @@ -337,7 +337,7 @@ def assembleVersionMessage(
)
# = 127.0.0.1. This will be ignored by the remote host.
# The actual remote connected IP will be used.
payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + pack(
payload += b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + pack(
'>L', 2130706433)
# we have a separate extPort and incoming over clearnet
# or outgoing through clearnet
Expand All @@ -359,7 +359,7 @@ def assembleVersionMessage(
payload += nodeid[0:8]
else:
payload += eightBytesOfRandomDataUsedToDetectConnectionsToSelf
userAgent = '/PyBitmessage:' + softwareVersion + '/'
userAgent = ('/PyBitmessage:%s/' % softwareVersion).encode('utf-8')
payload += encodeVarint(len(userAgent))
payload += userAgent

Expand All @@ -373,7 +373,7 @@ def assembleVersionMessage(
if count >= 160000:
break

return CreatePacket('version', payload)
return CreatePacket(b'version', payload)


def assembleErrorMessage(fatal=0, banTime=0, inventoryVector='', errorText=''):
Expand All @@ -387,7 +387,7 @@ def assembleErrorMessage(fatal=0, banTime=0, inventoryVector='', errorText=''):
payload += inventoryVector
payload += encodeVarint(len(errorText))
payload += errorText
return CreatePacket('error', payload)
return CreatePacket(b'error', payload)


# Packet decoding
Expand Down
6 changes: 6 additions & 0 deletions src/tests/samples.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from binascii import unhexlify


magic = 0xE9BEB4D9

# These keys are from addresses test script
sample_pubsigningkey = unhexlify(
'044a367f049ec16cb6b6118eb734a9962d10b8db59c890cd08f210c43ff08bdf09d'
Expand All @@ -14,6 +16,7 @@
b'93d0b61371a54b53df143b954035d612f8efa8a3ed1cf842c2186bfd8f876665'
sample_privencryptionkey = \
b'4b0b73a54e19b059dc274ab69df095fe699f43b17397bca26fdf40f4d7400a3a'

sample_ripe = b'003cd097eb7f35c87b5dc8b4538c22cb55312a9f'
# stream: 1, version: 2
sample_address = 'BM-onkVu1KKL2UaUss5Upg9vXmqd3esTmV79'
Expand All @@ -27,5 +30,8 @@

sample_seed = 'TIGER, tiger, burning bright. In the forests of the night'
# Deterministic addresses with stream 1 and versions 3, 4
sample_deterministic_ripe = b'00cfb69416ae76f68a81c459de4e13460c7d17eb'
sample_deterministic_addr3 = 'BM-2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN'
sample_deterministic_addr4 = 'BM-2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK'
sample_daddr3_512 = 18875720106589866286514488037355423395410802084648916523381
sample_daddr4_512 = 25152821841976547050350277460563089811513157529113201589004
34 changes: 30 additions & 4 deletions src/tests/test_addresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@

from pybitmessage import addresses

from .samples import sample_address, sample_ripe
from .samples import (
sample_address, sample_daddr3_512, sample_daddr4_512,
sample_deterministic_addr4, sample_deterministic_addr3,
sample_deterministic_ripe, sample_ripe)

sample_addr3 = sample_deterministic_addr3.split('-')[1]
sample_addr4 = sample_deterministic_addr4.split('-')[1]


class TestAddresses(unittest.TestCase):
Expand All @@ -17,19 +23,39 @@ def test_decode(self):
('success', 2, 1, unhexlify(sample_ripe)))

status, version, stream, ripe1 = addresses.decodeAddress(
'2cWzSnwjJ7yRP3nLEWUV5LisTZyREWSzUK')
sample_deterministic_addr4)
self.assertEqual(status, 'success')
self.assertEqual(stream, 1)
self.assertEqual(version, 4)
status, version, stream, ripe2 = addresses.decodeAddress(
'2DBPTgeSawWYZceFD69AbDT5q4iUWtj1ZN')
status, version, stream, ripe2 = addresses.decodeAddress(sample_addr3)
self.assertEqual(status, 'success')
self.assertEqual(stream, 1)
self.assertEqual(version, 3)
self.assertEqual(ripe1, ripe2)
self.assertEqual(ripe1, unhexlify(sample_deterministic_ripe))

def test_encode(self):
"""Encode sample ripe and compare the result to sample address"""
self.assertEqual(
sample_address,
addresses.encodeAddress(2, 1, unhexlify(sample_ripe)))
ripe = unhexlify(sample_deterministic_ripe)
self.assertEqual(
addresses.encodeAddress(3, 1, ripe),
'BM-%s' % addresses.encodeBase58(sample_daddr3_512))

def test_base58(self):
"""Check Base58 encoding and decoding"""
self.assertEqual(addresses.decodeBase58('1'), 0)
self.assertEqual(addresses.decodeBase58('!'), 0)
self.assertEqual(
addresses.decodeBase58(sample_addr4), sample_daddr4_512)
self.assertEqual(
addresses.decodeBase58(sample_addr3), sample_daddr3_512)

self.assertEqual(addresses.encodeBase58(0), '1')
self.assertEqual(addresses.encodeBase58(-1), None)
self.assertEqual(
sample_addr4, addresses.encodeBase58(sample_daddr4_512))
self.assertEqual(
sample_addr3, addresses.encodeBase58(sample_daddr3_512))
68 changes: 68 additions & 0 deletions src/tests/test_packets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@

import unittest
from binascii import unhexlify
from struct import pack

from pybitmessage import addresses, protocol

from .samples import magic


class TestSerialize(unittest.TestCase):
"""Test serializing and deserializing packet data"""

def test_varint(self):
"""Test varint encoding and decoding"""
data = addresses.encodeVarint(0)
self.assertEqual(data, b'\x00')
data = addresses.encodeVarint(42)
self.assertEqual(data, b'*')
data = addresses.encodeVarint(252)
self.assertEqual(data, unhexlify('fc'))
data = addresses.encodeVarint(253)
self.assertEqual(data, unhexlify('fd00fd'))
data = addresses.encodeVarint(100500)
self.assertEqual(data, unhexlify('fe00018894'))
data = addresses.encodeVarint(65535)
self.assertEqual(data, unhexlify('fdffff'))
data = addresses.encodeVarint(4294967295)
self.assertEqual(data, unhexlify('feffffffff'))
data = addresses.encodeVarint(4294967296)
self.assertEqual(data, unhexlify('ff0000000100000000'))
data = addresses.encodeVarint(18446744073709551615)
self.assertEqual(data, unhexlify('ffffffffffffffffff'))

with self.assertRaises(addresses.varintEncodeError):
addresses.encodeVarint(18446744073709551616)

value, length = addresses.decodeVarint(b'\xfeaddr')
self.assertEqual(value, protocol.OBJECT_ADDR)
self.assertEqual(length, 5)
value, length = addresses.decodeVarint(b'\xfe\x00tor')
self.assertEqual(value, protocol.OBJECT_ONIONPEER)
self.assertEqual(length, 5)

def test_packet(self):
"""Check the packet created by protocol.CreatePacket()"""
head = unhexlify(b'%x' % magic)
self.assertEqual(
protocol.CreatePacket(b'ping')[:len(head)], head)

def test_encodehost(self):
"""Check the result of protocol.encodeHost()"""
self.assertEqual(
protocol.encodeHost('127.0.0.1'),
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF'
+ pack('>L', 2130706433))
self.assertEqual(
protocol.encodeHost('191.168.1.1'),
unhexlify('00000000000000000000ffffbfa80101'))
self.assertEqual(
protocol.encodeHost('1.1.1.1'),
unhexlify('00000000000000000000ffff01010101'))
self.assertEqual(
protocol.encodeHost('0102:0304:0506:0708:090A:0B0C:0D0E:0F10'),
unhexlify('0102030405060708090a0b0c0d0e0f10'))
self.assertEqual(
protocol.encodeHost('quzwelsuziwqgpt2.onion'),
unhexlify('fd87d87eeb438533622e54ca2d033e7a'))