Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Little endian #33

Merged
merged 2 commits into from
Jan 28, 2019
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
4 changes: 2 additions & 2 deletions ssz/sedes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def max_content_length(self) -> int:
return 2 ** (self.length_bytes * 8) - 1

def get_length_prefix(self, content: bytes) -> bytes:
return len(content).to_bytes(self.length_bytes, "big")
return len(content).to_bytes(self.length_bytes, "little")

def validate_content_length(self, content: bytes) -> None:
if len(content) >= self.max_content_length:
Expand All @@ -146,7 +146,7 @@ def serialize_content(self, value: TSerializable) -> bytes:
#
def deserialize_segment(self, data: bytes, start_index: int) -> Tuple[TDeserialized, int]:
prefix, content_start_index = self.consume_bytes(data, start_index, self.length_bytes)
length = int.from_bytes(prefix, "big")
length = int.from_bytes(prefix, "little")
content, continuation_index = self.consume_bytes(data, content_start_index, length)
return self.deserialize_content(content), continuation_index

Expand Down
4 changes: 2 additions & 2 deletions ssz/sedes/integer.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ def serialize_content(self, value: int) -> bytes:
)

try:
return value.to_bytes(self.length, 'big')
return value.to_bytes(self.length, "little")
except OverflowError:
raise SerializationError(
f"{value} is too large to be serialized in {self.length * 8} bits"
)

def deserialize_content(self, content: bytes) -> int:
return int.from_bytes(content, 'big')
return int.from_bytes(content, "little")


uint8 = UnsignedInteger(8)
Expand Down
2 changes: 1 addition & 1 deletion ssz/tree_hash/merkle_hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def merkle_hash(input_items: Sequence[Any]) -> Hash32:
"""

# Store length of list (to compensate for non-bijectiveness of padding)
data_length = len(input_items).to_bytes(32, 'big')
data_length = len(input_items).to_bytes(32, "little")

if len(input_items) == 0:
# Handle empty list case
Expand Down
30 changes: 11 additions & 19 deletions tests/core/sedes/test_byte_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,23 @@
'value,expected',
(
(b"", b'\x00\x00\x00\x00'),
(b"I", b'\x00\x00\x00\x01I'),
(b"foo", b'\x00\x00\x00\x03foo'),
(b"hello", b'\x00\x00\x00\x05hello'),

(bytearray(b""), b'\x00\x00\x00\x00'),
(bytearray(b"I"), b'\x00\x00\x00\x01I'),
(bytearray(b"foo"), b'\x00\x00\x00\x03foo'),
(bytearray(b"hello"), b'\x00\x00\x00\x05hello'),
(b"I", b'\x01\x00\x00\x00I'),
(b"foo", b'\x03\x00\x00\x00foo'),
(b"hello", b'\x05\x00\x00\x00hello'),
),
)
def test_bytes_serialize_values(value, expected):
assert bytes_sedes.serialize(value) == expected
assert bytes_sedes.serialize(bytearray(value)) == expected


@pytest.mark.parametrize(
'value,expected',
(
(b'\x00\x00\x00\x00', b""),
(b'\x00\x00\x00\x01I', b"I"),
(b'\x00\x00\x00\x03foo', b"foo"),
(b'\x00\x00\x00\x05hello', b"hello"),
(b'\x01\x00\x00\x00I', b"I"),
(b'\x03\x00\x00\x00foo', b"foo"),
(b'\x05\x00\x00\x00hello', b"hello"),
),
)
def test_bytes_deserialize_values(value, expected):
Expand All @@ -45,13 +41,13 @@ def test_bytes_deserialize_values(value, expected):
'value',
(
# Less than 4 bytes of serialized data
b'\x00\x00\x01',
b'\x01\x00\x00',

# Insufficient serialized object data as per found out byte object length
b'\x00\x00\x00\x04',
b'\x04\x00\x00\x00',

# Serialized data given is more than what is required
b'\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01' + b'\x00'
b'\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' + b'\x00'
),
)
def test_bytes_deserialization_bad_value(value):
Expand All @@ -66,15 +62,11 @@ def test_bytes_deserialization_bad_value(value):
(b"I", b'I'),
(b"foo", b'foo'),
(b"hello", b'hello'),

(bytearray(b""), b''),
(bytearray(b"I"), b'I'),
(bytearray(b"foo"), b'foo'),
(bytearray(b"hello"), b'hello'),
),
)
def test_bytes_round_trip(value, expected):
assert bytes_sedes.deserialize(bytes_sedes.serialize(value)) == expected
assert bytes_sedes.deserialize(bytes_sedes.serialize(bytearray(value))) == expected


@pytest.mark.parametrize(
Expand Down
23 changes: 12 additions & 11 deletions tests/core/sedes/test_integer_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@
(255, uint8, b'\xff'),

(0, uint16, b'\x00\x00'),
(5, uint16, b'\x00\x05'),
(127, uint16, b'\x00\x7f'),
(256, uint16, b'\x01\x00'),
(1024, uint16, b'\x04\x00'),
(5, uint16, b'\x05\x00'),
(127, uint16, b'\x7f\x00'),
(256, uint16, b'\x00\x01'),
(1024, uint16, b'\x00\x04'),
(65535, uint16, b'\xff\xff'),

(0, uint32, b'\x00\x00\x00\x00'),
(5, uint32, b'\x00\x00\x00\x05'),
(65536, uint32, b'\x00\x01\x00\x00'),
(5, uint32, b'\x05\x00\x00\x00'),
(65536, uint32, b'\x00\x00\x01\x00'),
(4294967295, uint32, b'\xff\xff\xff\xff'),

(0, uint64, b'\x00\x00\x00\x00\x00\x00\x00\x00'),
Expand Down Expand Up @@ -77,8 +77,8 @@ def test_ssz_encode_integer_serialize_bad_values(value):
'value,sedes,expected',
(
(b'\x05', uint8, 5),
(b'\x00\x05', uint16, 5),
(b'\x00\x00\x00\x05', uint32, 5),
(b'\x05\x00', uint16, 5),
(b'\x05\x00\x00\x00', uint32, 5),
(b'\x7f', uint8, 127),
(b'\xff', uint8, 255),
(b'\xff\xff', uint16, 65535),
Expand All @@ -94,14 +94,15 @@ def test_integer_deserialize_values(value, sedes, expected):
# Values too short
(b'\x05', uint16),
(b'\x7f', uint16),
(b'\x00\x05', uint32),
(b'\x00\x00\x00\x05', uint64),
(b'\x05\x00', uint32),
(b'\x05\x00\x00\x00', uint64),

# Values too long
(b'\x05\x00\x05', uint16),
(b'\x7f\x00\x7f', uint16),
(b'\x00\x05\x00\x05\x00\x05', uint32),
(b'\x05\x00\x05\x00\x05\x00', uint32),
(b'\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00\x05', uint64),
(b'\x05\x00\x00\x00\x05\x00\x00\x00\x05\x00\x00\x00', uint64),
),
)
def test_integer_deserialize_bad_values(value, sedes):
Expand Down
114 changes: 63 additions & 51 deletions tests/core/sedes/test_list_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,54 +38,59 @@
(
[0, 1, 2, 3, 4],
uint32_list,
b'\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x01'
b'\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04',
b'\x14\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00'
b'\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00',
),
(
(0, 1, 2, 3, 4),
uint32_list,
b'\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x01'
b'\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04',
b'\x14\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00'
b'\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00',
),
(
range(5),
uint32_list,
b'\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x01'
b'\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04',
b'\x14\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00'
b'\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00',
),

# Serialize bytes32 Iterables
([b'\x00' * 32], bytes32_list, b'\x00\x00\x00\x20' + (b'\x00' * 32)),
([b'\x00' * 32, b'\x00' * 32], bytes32_list, b'\x00\x00\x00\x40' + (b'\x00' * 64)),
((b'\x00' * 32, b'\x00' * 32), bytes32_list, b'\x00\x00\x00\x40' + (b'\x00' * 64)),
([b'\x00' * 32], bytes32_list, b'\x20\x00\x00\x00' + (b'\x00' * 32)),
([b'\x00' * 32, b'\x00' * 32], bytes32_list, b'\x40\x00\x00\x00' + (b'\x00' * 64)),
((b'\x00' * 32, b'\x00' * 32), bytes32_list, b'\x40\x00\x00\x00' + (b'\x00' * 64)),

# Serialize bytes48 Iterables
([b'\x00' * 48], bytes48_list, b'\x00\x00\x00\x30' + (b'\x00' * 48)),
([b'\x00' * 48, b'\x00' * 48], bytes48_list, b'\x00\x00\x00\x60' + (b'\x00' * 96)),
((b'\x00' * 48, b'\x00' * 48), bytes48_list, b'\x00\x00\x00\x60' + (b'\x00' * 96)),
([b'\x00' * 48], bytes48_list, b'\x30\x00\x00\x00' + (b'\x00' * 48)),
([b'\x00' * 48, b'\x00' * 48], bytes48_list, b'\x60\x00\x00\x00' + (b'\x00' * 96)),
((b'\x00' * 48, b'\x00' * 48), bytes48_list, b'\x60\x00\x00\x00' + (b'\x00' * 96)),

# Serialize bytes96 Iterables
([b'\x00' * 96], bytes96_list, b'\x00\x00\x00\x60' + (b'\x00' * 96)),
([b'\x00' * 96, b'\x00' * 96], bytes96_list, b'\x00\x00\x00\xc0' + (b'\x00' * 192)),
((b'\x00' * 96, b'\x00' * 96), bytes96_list, b'\x00\x00\x00\xc0' + (b'\x00' * 192)),
([b'\x00' * 96], bytes96_list, b'\x60\x00\x00\x00' + (b'\x00' * 96)),
([b'\x00' * 96, b'\x00' * 96], bytes96_list, b'\xc0\x00\x00\x00' + (b'\x00' * 192)),
((b'\x00' * 96, b'\x00' * 96), bytes96_list, b'\xc0\x00\x00\x00' + (b'\x00' * 192)),


# Serialize boolean Iterables
([True, True, True, True], boolean_list, b'\x00\x00\x00\x04' + b'\x01' * 4),
((True, True, True, True), boolean_list, b'\x00\x00\x00\x04' + b'\x01' * 4),
([False, False, False, False], boolean_list, b'\x00\x00\x00\x04' + b'\x00' * 4),
((False, False, False, False), boolean_list, b'\x00\x00\x00\x04' + b'\x00' * 4),
([True, False, True, False], boolean_list, b'\x00\x00\x00\x04\x01\x00\x01\x00'),
((True, False, True, False), boolean_list, b'\x00\x00\x00\x04\x01\x00\x01\x00'),
([True, True, True, True], boolean_list, b'\x04\x00\x00\x00' + b'\x01' * 4),
((True, True, True, True), boolean_list, b'\x04\x00\x00\x00' + b'\x01' * 4),
([False, False, False, False], boolean_list, b'\x04\x00\x00\x00' + b'\x00' * 4),
((False, False, False, False), boolean_list, b'\x04\x00\x00\x00' + b'\x00' * 4),
([True, False, True, False], boolean_list, b'\x04\x00\x00\x00\x01\x00\x01\x00'),
((True, False, True, False), boolean_list, b'\x04\x00\x00\x00\x01\x00\x01\x00'),

# Serialize bytes Iterables
([b'\x01'], bytes_list, b'\x00\x00\x00\x05\x00\x00\x00\x01\x01'),
([b'\x01', b'\x02'], bytes_list, b'\x00\x00\x00\n\x00\x00\x00\x01\x01\x00\x00\x00\x01\x02'),
([b'\x01'], bytes_list, b'\x05\x00\x00\x00\x01\x00\x00\x00\x01'),
(
[b'\x01', b'\x02'],
bytes_list,
b'\x0a\x00\x00\x00\x01\x00\x00\x00\x01\x01\x00\x00\x00\x02',
),
(
[b'\x01\x02', b'\x02\x03'],
bytes_list,
b'\x00\x00\x00\x0c\x00\x00\x00'
b'\x02\x01\x02\x00\x00\x00\x02\x02\x03',
b'\x0c\x00\x00\x00'
b'\x02\x00\x00\x00\x01\x02'
b'\x02\x00\x00\x00\x02\x03',
),
),
)
Expand Down Expand Up @@ -135,36 +140,43 @@ def test_list_serialize_bad_values(value, sedes):

# Deserialize uint32 Iterables
(
b'\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x01'
b'\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04',
b'\x14\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00'
b'\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00',
uint32_list,
(0, 1, 2, 3, 4),
),

# Deserialize bytes32 Iterables
(b'\x00\x00\x00\x20' + (b'\x00' * 32), bytes32_list, (b'\x00' * 32,)),
(b'\x00\x00\x00\x40' + (b'\x00' * 64), bytes32_list, (b'\x00' * 32, b'\x00' * 32)),
(b'\x20\x00\x00\x00' + (b'\x00' * 32), bytes32_list, (b'\x00' * 32,)),
(b'\x40\x00\x00\x00' + (b'\x00' * 64), bytes32_list, (b'\x00' * 32, b'\x00' * 32)),

# Deserialize bytes48 Iterables
(b'\x00\x00\x00\x30' + (b'\x00' * 48), bytes48_list, (b'\x00' * 48,)),
(b'\x00\x00\x00\x60' + (b'\x00' * 96), bytes48_list, (b'\x00' * 48, b'\x00' * 48)),
(b'\x30\x00\x00\x00' + (b'\x00' * 48), bytes48_list, (b'\x00' * 48,)),
(b'\x60\x00\x00\x00' + (b'\x00' * 96), bytes48_list, (b'\x00' * 48, b'\x00' * 48)),

# Deserialize bytes96 Iterables
(b'\x00\x00\x00\x60' + (b'\x00' * 96), bytes96_list, (b'\x00' * 96,)),
(b'\x00\x00\x00\xc0' + (b'\x00' * 192), bytes96_list, (b'\x00' * 96, b'\x00' * 96)),
(b'\x60\x00\x00\x00' + (b'\x00' * 96), bytes96_list, (b'\x00' * 96,)),
(b'\xc0\x00\x00\x00' + (b'\x00' * 192), bytes96_list, (b'\x00' * 96, b'\x00' * 96)),

# Deserialize boolean Iterables
(b'\x00\x00\x00\x04' + b'\x01' * 4, boolean_list, (True, True, True, True)),
(b'\x00\x00\x00\x04' + b'\x00' * 4, boolean_list, (False, False, False, False)),
(b'\x00\x00\x00\x04\x01\x00\x01\x00', boolean_list, (True, False, True, False)),
(b'\x04\x00\x00\x00' + b'\x01' * 4, boolean_list, (True, True, True, True)),
(b'\x04\x00\x00\x00' + b'\x00' * 4, boolean_list, (False, False, False, False)),
(b'\x04\x00\x00\x00\x01\x00\x01\x00', boolean_list, (True, False, True, False)),

# Deserialize bytes Iterables
# Serialize bytes Iterables
(b'\x00\x00\x00\x05\x00\x00\x00\x01\x01', bytes_list, (b'\x01',)),
(b'\x00\x00\x00\n\x00\x00\x00\x01\x01\x00\x00\x00\x01\x02', bytes_list, (b'\x01', b'\x02')),
(b'\x05\x00\x00\x00\x01\x00\x00\x00\x01', bytes_list, (b'\x01',)),
(
b'\x0a\x00\x00\x00'
b'\x01\x00\x00\x00\x01'
b'\x01\x00\x00\x00\x02',
bytes_list,
(b'\x01', b'\x02'),
),
(
b'\x00\x00\x00\x0c\x00\x00\x00'
b'\x02\x01\x02\x00\x00\x00\x02\x02\x03',
b'\x0c\x00\x00\x00'
b'\x02\x00\x00\x00\x01\x02'
b'\x02\x00\x00\x00\x02\x03',
bytes_list,
(b'\x01\x02', b'\x02\x03'),
),
Expand All @@ -185,21 +197,21 @@ def test_list_deserialize_values(value, sedes, expected):
(b'\x00\x00\x00', boolean_list),

# Insufficient serialized list data as per found out list length
(b'\x00\x00\x04', uint32_list),
(b'\x00\x00\x04', bytes32_list),
(b'\x00\x00\x04', bytes48_list),
(b'\x00\x00\x04', bytes96_list),
(b'\x00\x00\x04', boolean_list),
(b'\x04\x00\x00\x00\x00', uint32_list),
(b'\x04\x00\x00\x00\x00', bytes32_list),
(b'\x04\x00\x00\x00\x00', bytes48_list),
(b'\x04\x00\x00\x00\x00', bytes96_list),
(b'\x04\x00\x00\x00\x00', boolean_list),

# Serialized data given is more than what is required
(b'\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x01' + b'\x00', uint32_list),
(b'\x00\x00\x00 ' + (b'\x00' * 35), bytes32_list),
(b'\x00\x00\x00\x14' + (b'\x00' * 53), bytes48_list),
(b'\x00\x00\x00\x14' + (b'\x00' * 101), bytes96_list),
(b'\x00\x00\x00\x04' + b'\x01' * 5, boolean_list),
(b'\x08\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00' + b'\x00', uint32_list),
(b'\x20\x00\x00\x00' + (b'\x00' * 35), bytes32_list),
(b'\x14\x00\x00\x00' + (b'\x00' * 53), bytes48_list),
(b'\x14\x00\x00\x00' + (b'\x00' * 101), bytes96_list),
(b'\x04\x00\x00\x00' + b'\x01' * 5, boolean_list),

# Non-empty lists for empty sedes
(b'\x00\x00\x00\x01\x00', empty_list)
(b'\x01\x00\x00\x00\x00', empty_list)
),
)
def test_list_deserialize_bad_values(value, sedes):
Expand Down
Loading