def parse_type_definition(type_definition): error_message = f"Could not parse type definition {type_definition}" if isinstance(type_definition, str): try: sedes = sedes_by_name[type_definition] except KeyError: raise ValueError(error_message) else: return sedes elif isinstance(type_definition, Sequence): if len(type_definition) == 1: return List(parse_type_definition(type_definition[0])) elif len(type_definition) == 2: element_type = parse_type_definition(type_definition[0]) try: length = int(type_definition[1]) except ValueError: raise ValueError(error_message) return Vector(element_type, length) else: raise ValueError(error_message) elif isinstance(type_definition, Mapping): return Container(tuple( (field_name, parse_type_definition(field_type)) for field_name, field_type in type_definition.items() )) else: raise ValueError(error_message)
def test_container_of_static_sized_fields(value, serialized): field_names = tuple(str(index) for index in range(len(value))) sedes = Container(tuple((field_name, uint8) for field_name in field_names)) value_dict = {field_name: field_value for field_name, field_value in zip(field_names, value)} assert encode_hex(ssz.encode(value_dict, sedes)) == serialized assert ssz.decode(decode_hex(serialized), sedes) == value_dict
def test_container_of_dynamic_sized_fields(fields, value, serialized): sedes = Container(fields) assert encode_hex(ssz.encode(value, sedes)) == serialized decoded = ssz.decode(decode_hex(serialized), sedes) pure_decoded = tuple( tuple(element) if isinstance(element, HashableList) else element for element in decoded) assert pure_decoded == value
def test_container(bytes16_fields, result): field_names = tuple(f"field{index}" for index in range(len(bytes16_fields))) sedes = Container( tuple((field_name, bytes16) for field_name in field_names)) value = { field_name: field_value for field_name, field_value in zip(field_names, bytes16_fields) } assert ssz.hash_tree_root(value, sedes) == result
from ssz.sedes import Container, List, uint8, uint16, uint32, uint256 class ByteList(List): # type: ignore def __init__(self, max_length: int) -> None: super().__init__(element_sedes=uint8, max_length=max_length) def serialize(self, value: bytes) -> bytes: return value def deserialize(self, value: bytes) -> bytes: return value byte_list = ByteList(max_length=2048) PingSedes = Container(field_sedes=(uint32, uint256)) PongSedes = Container(field_sedes=(uint32, uint256)) FindNodesSedes = Container(field_sedes=(List(uint16, max_length=256),)) FoundNodesSedes = Container(field_sedes=(uint8, List(byte_list, max_length=32))) FindContentSedes = Container(field_sedes=(byte_list,)) FoundContentSedes = Container(field_sedes=(List(byte_list, max_length=32), byte_list))
def test_container(bytes16_fields, result): sedes = Container(tuple(itertools.repeat(bytes16, len(bytes16_fields)))) assert ssz.get_hash_tree_root(bytes16_fields, sedes) == result
bytes48, bytes96, uint8, uint256, ) @pytest.mark.parametrize( ("sedes", "size"), ( (boolean, 1), (uint8, 1), (uint256, 32), (Vector(uint8, 0), 0), (Vector(uint8, 2), 2), (Container((uint8, Vector(uint8, 4))), 5), (Vector(List(uint8), 0), 0), (Vector(Container((uint8, Vector(uint8, 4))), 4), 20), (byte, 1), (ByteVector(0), 0), (bytes32, 32), (bytes48, 48), (bytes96, 96), ), ) def test_fixed_size(sedes, size): assert sedes.is_fixed_sized assert sedes.get_fixed_size() == size @pytest.mark.parametrize(
def test_container_of_static_sized_fields(value, serialized): sedes = Container(tuple(itertools.repeat(uint8, len(value)))) assert encode_hex(ssz.encode(value, sedes)) == serialized assert ssz.decode(decode_hex(serialized), sedes) == value
sedes = Container(fields) assert encode_hex(ssz.encode(value, sedes)) == serialized decoded = ssz.decode(decode_hex(serialized), sedes) pure_decoded = tuple( tuple(element) if isinstance(element, HashableList) else element for element in decoded) assert pure_decoded == value @pytest.mark.parametrize( ("sedes", "id"), ( (List(uint8, 2), "List(UInt8,2)"), (Vector(uint8, 2), "Vector(UInt8,2)"), (Container((uint8, bytes32)), "UInt8,ByteVector32"), (Container((uint8, List(uint8, 2))), "UInt8,List(UInt8,2)"), ( Vector(Container((uint8, List(uint8, 2))), 2), "Vector(UInt8,List(UInt8,2),2)", ), ), ) def test_get_sedes_id(sedes, id): assert sedes.get_sedes_id() == id @pytest.mark.parametrize( ("sedes1", "sedes2"), ( (List(uint8, 2), List(uint8, 2)),
bytes48, bytes96, uint8, uint256, ) @pytest.mark.parametrize( ("sedes", "size"), ( (boolean, 1), (uint8, 1), (uint256, 32), (Vector(uint8, 0), 0), (Vector(uint8, 2), 2), (Container((("a", uint8), ("b", Vector(uint8, 4)))), 5), (Vector(List(uint8), 0), 0), (Vector(Container((("a", uint8), ("b", Vector(uint8, 4)))), 4), 20), (byte, 1), (ByteVector(0), 0), (bytes32, 32), (bytes48, 48), (bytes96, 96), ), ) def test_static_size(sedes, size): assert sedes.is_static_sized assert sedes.get_static_size() == size @pytest.mark.parametrize(
def test_container_of_dynamic_sized_fields(fields, value, serialized): sedes = Container(fields) assert encode_hex(ssz.encode(value, sedes)) == serialized assert ssz.decode(decode_hex(serialized), sedes) == value
def __init__(self, max_length: int) -> None: super().__init__(element_sedes=uint8, max_length=max_length) def serialize(self, value: bytes) -> bytes: return value def deserialize(self, value: bytes) -> bytes: return value byte_list = ByteList(max_length=2048) uint40 = UInt(40) content_key_sedes = ByteList(max_length=256) PingSedes = Container(field_sedes=(uint32, uint256)) PongSedes = Container(field_sedes=(uint32, uint256)) FindNodesSedes = Container(field_sedes=(List(uint16, max_length=256),)) FoundNodesSedes = Container(field_sedes=(uint8, List(byte_list, max_length=32))) GetContentSedes = Container(field_sedes=(byte_list, uint32, uint16)) ContentSedes = Container(field_sedes=(boolean, byte_list,)) AdvertisementSedes = Container( field_sedes=(byte_list, bytes32, uint40, uint8, uint256, uint256) ) AdvertiseSedes = List(AdvertisementSedes, max_length=32) AckSedes = Container(field_sedes=(uint256, List(boolean, max_length=32))) LocateSedes = Container(field_sedes=(content_key_sedes,))
def general_container_sedes_and_values_st(draw, element_sedes_and_elements_sequence): element_sedes, elements = zip(*element_sedes_and_elements_sequence) sedes = Container(element_sedes) values = st.tuples(*elements) return sedes, values