Exemplo n.º 1
0
class HistoricalBatch(ssz.Serializable):

    fields = [
        # Block roots
        ('block_roots', List(bytes32)),
        # State roots
        ('state_roots', List(bytes32)),
    ]

    def __init__(self, *, block_roots: Sequence[Hash32],
                 state_roots: Sequence[Hash32],
                 slots_per_historical_root: int) -> None:
        assert len(block_roots) == slots_per_historical_root
        assert len(state_roots) == slots_per_historical_root

        super().__init__(
            block_roots=block_roots,
            state_roots=state_roots,
        )

    _hash_tree_root = None

    @property
    def hash_tree_root(self) -> Hash32:
        if self._hash_tree_root is None:
            self._hash_tree_root = ssz.hash_tree_root(self)
        return self._hash_tree_root
Exemplo n.º 2
0
class IndexedAttestation(ssz.Serializable):

    fields = [
        # Validator indices
        ("custody_bit_0_indices", List(uint64, 1)),
        ("custody_bit_1_indices", List(uint64, 1)),
        # Attestation data
        ("data", AttestationData),
        # Aggregate signature
        ("signature", bytes96),
    ]

    def __init__(
        self,
        custody_bit_0_indices: Sequence[ValidatorIndex] = default_tuple,
        custody_bit_1_indices: Sequence[ValidatorIndex] = default_tuple,
        data: AttestationData = default_attestation_data,
        signature: BLSSignature = EMPTY_SIGNATURE,
    ) -> None:
        super().__init__(custody_bit_0_indices, custody_bit_1_indices, data,
                         signature)

    def __str__(self) -> str:
        return (f"custody_bit_0_indices={self.custody_bit_0_indices},"
                f" custody_bit_1_indices={self.custody_bit_1_indices},"
                f" data=({self.data}),"
                f" signature={humanize_hash(self.signature)}")
Exemplo n.º 3
0
class IndexedAttestation(ssz.Serializable):

    fields = [
        # Validator indices
        ('custody_bit_0_indices', List(uint64, 1)),
        ('custody_bit_1_indices', List(uint64, 1)),
        # Attestation data
        ('data', AttestationData),
        # Aggregate signature
        ('signature', bytes96),
    ]

    def __init__(
            self,
            custody_bit_0_indices: Sequence[ValidatorIndex] = default_tuple,
            custody_bit_1_indices: Sequence[ValidatorIndex] = default_tuple,
            data: AttestationData = default_attestation_data,
            signature: BLSSignature = EMPTY_SIGNATURE) -> None:
        super().__init__(
            custody_bit_0_indices,
            custody_bit_1_indices,
            data,
            signature,
        )

    def __repr__(self) -> str:
        return f"<IndexedAttestation {self.data}>"
Exemplo n.º 4
0
def test_not_serializable():
    octopi = (octopus, octopus, octopus)
    sedes = List(Animal, 2**32)
    output = to_formatted_dict(octopi, sedes)

    hashable_octopi = HashableList.from_iterable(octopi, sedes)
    assert hashable_octopi == from_formatted_dict(output, List(Animal, 2**32))
Exemplo n.º 5
0
class State(Serializable):
    fields = [
        ("validators", List(Validator, VALIDATOR_REGISTRY_LIMIT)),
        ("balances", List(uint64, VALIDATOR_REGISTRY_LIMIT)),
        ("randao_mixes", Vector(bytes32, EPOCHS_PER_HISTORICAL_VECTOR)),
        ("latest_block_header", BeaconBlockHeader),
        ("eth1_data", Eth1Data),
    ]
Exemplo n.º 6
0
def test_invalid_serialized_list():
    # ensure that an improperly read offset (not enough bytes) does not
    # incorrectly register as an empty list due to mis-interpreting the failed
    # stream read as the stream having been empty.
    data = decode_hex("0x0001")
    sedes = List(List(uint8, 2**32), 2**32)
    with pytest.raises(DeserializationError):
        ssz.decode(data, sedes=sedes)
Exemplo n.º 7
0
class BeaconBlockBody(HashableContainer):

    fields = [
        ("randao_reveal", bytes96),
        ("eth1_data", Eth1Data),
        ("graffiti", bytes32),
        ("proposer_slashings", List(ProposerSlashing, 16)),
        ("attester_slashings", List(AttesterSlashing, 2)),
        ("attestations", List(Attestation, 128)),
        ("deposits", List(Deposit, 16)),
        ("voluntary_exits", List(SignedVoluntaryExit, 16)),
    ]

    @classmethod
    def create(
        cls: Type[TBeaconBlockBody],
        *,
        randao_reveal: BLSSignature = EMPTY_SIGNATURE,
        eth1_data: Eth1Data = default_eth1_data,
        graffiti: Hash32 = ZERO_HASH32,
        proposer_slashings: Sequence[ProposerSlashing] = default_tuple,
        attester_slashings: Sequence[AttesterSlashing] = default_tuple,
        attestations: Sequence[Attestation] = default_tuple,
        deposits: Sequence[Deposit] = default_tuple,
        voluntary_exits: Sequence[SignedVoluntaryExit] = default_tuple,
    ) -> TBeaconBlockBody:
        return super().create(
            randao_reveal=randao_reveal,
            eth1_data=eth1_data,
            graffiti=graffiti,
            proposer_slashings=proposer_slashings,
            attester_slashings=attester_slashings,
            attestations=attestations,
            deposits=deposits,
            voluntary_exits=voluntary_exits,
        )

    @property
    def is_empty(self) -> bool:
        return self == BeaconBlockBody.create()

    def __str__(self) -> str:
        return (
            f"randao_reveal={humanize_hash(self.randao_reveal)},"
            f" eth1_data=({self.eth1_data}),"
            f" graffiti={humanize_hash(self.graffiti)},"
            f" proposer_slashings={tuple(slashing for slashing in self.proposer_slashings)},"
            f" attester_slashings={tuple(slashing for slashing in self.attester_slashings)},"
            f" attestations={tuple(attestation for attestation in self.attestations)},"
            f" deposits={tuple(deposit for deposit in self.deposits)},"
            f" voluntary_exits={tuple(exit for exit in self.voluntary_exits)},"
        )

    def __repr__(self) -> str:
        return f"<{self.__class__.__name__}: {str(self)}>"
Exemplo n.º 8
0
class BeaconBlockBody(ssz.Serializable):

    fields = [
        ('proposer_slashings', List(ProposerSlashing)),
        ('attester_slashings', List(AttesterSlashing)),
        ('attestations', List(Attestation)),
        ('deposits', List(Deposit)),
        ('exits', List(Exit)),
    ]

    def __init__(self,
                 proposer_slashings: Sequence[ProposerSlashing],
                 attester_slashings: Sequence[AttesterSlashing],
                 attestations: Sequence[Attestation],
                 deposits: Sequence[Deposit],
                 exits: Sequence[Exit])-> None:
        super().__init__(
            proposer_slashings=proposer_slashings,
            attester_slashings=attester_slashings,
            attestations=attestations,
            deposits=deposits,
            exits=exits,
        )

    @classmethod
    def create_empty_body(cls) -> 'BeaconBlockBody':
        return cls(
            proposer_slashings=(),
            attester_slashings=(),
            attestations=(),
            deposits=(),
            exits=(),
        )

    @property
    def is_empty(self) -> bool:
        return (
            self.proposer_slashings == () and
            self.attester_slashings == () and
            self.attestations == () and
            self.deposits == () and
            self.exits == ()
        )

    @classmethod
    def cast_block_body(cls,
                        body: 'BeaconBlockBody') -> 'BeaconBlockBody':
        return cls(
            proposer_slashings=body.proposer_slashings,
            attester_slashings=body.attester_slashings,
            attestations=body.attestations,
            deposits=body.deposits,
            exits=body.exits,
        )
Exemplo n.º 9
0
class CompactCommittee(ssz.Serializable):

    fields = [("pubkeys", List(bytes48, 1)),
              ("compact_validators", List(uint64, 1))]

    def __init__(
        self,
        pubkeys: Sequence[BLSPubkey] = default_tuple,
        compact_validators: Sequence[int] = default_tuple,
    ) -> None:
        super().__init__(pubkeys=pubkeys,
                         compact_validators=compact_validators)
Exemplo n.º 10
0
class BeaconBlockBody(ssz.Serializable):

    fields = [
        ("randao_reveal", bytes96),
        ("eth1_data", Eth1Data),
        ("graffiti", bytes32),
        ("proposer_slashings", List(ProposerSlashing, 1)),
        ("attester_slashings", List(AttesterSlashing, 1)),
        ("attestations", List(Attestation, 1)),
        ("deposits", List(Deposit, 1)),
        ("voluntary_exits", List(VoluntaryExit, 1)),
    ]

    def __init__(
        self,
        *,
        randao_reveal: bytes96 = EMPTY_SIGNATURE,
        eth1_data: Eth1Data = default_eth1_data,
        graffiti: Hash32 = ZERO_HASH32,
        proposer_slashings: Sequence[ProposerSlashing] = default_tuple,
        attester_slashings: Sequence[AttesterSlashing] = default_tuple,
        attestations: Sequence[Attestation] = default_tuple,
        deposits: Sequence[Deposit] = default_tuple,
        voluntary_exits: Sequence[VoluntaryExit] = default_tuple,
    ) -> None:
        super().__init__(
            randao_reveal=randao_reveal,
            eth1_data=eth1_data,
            graffiti=graffiti,
            proposer_slashings=proposer_slashings,
            attester_slashings=attester_slashings,
            attestations=attestations,
            deposits=deposits,
            voluntary_exits=voluntary_exits,
        )

    @property
    def is_empty(self) -> bool:
        return self == BeaconBlockBody()

    def __str__(self) -> str:
        return (f"randao_reveal={humanize_hash(self.randao_reveal)},"
                f" graffiti={humanize_hash(self.graffiti)},"
                f" proposer_slashings={self.proposer_slashings},"
                f" attester_slashings={self.attester_slashings},"
                f" attestations={self.attestations},"
                f" deposits={self.deposits},"
                f" voluntary_exits={self.voluntary_exits},")

    def __repr__(self) -> str:
        return f"<{self.__class__.__name__}: {str(self)}>"
Exemplo n.º 11
0
class RecentBeaconBlocksRequest(ssz.Serializable):
    fields = [
        ('block_roots', List(bytes32, 1)),
    ]

    def __init__(self, block_roots: Sequence[HashTreeRoot]) -> None:
        super().__init__(block_roots)
Exemplo n.º 12
0
class BeaconBlocksResponse(ssz.Serializable):
    fields = [
        ('blocks', List(BeaconBlock, 1)),
    ]

    def __init__(self, blocks: Sequence[BeaconBlock]) -> None:
        super().__init__(blocks)
Exemplo n.º 13
0
def test_byte_list(value):
    serialized_value = ssz.encode(value, byte_list)
    assert serialized_value == ssz.encode(
        tuple(bytes([byte_value]) for byte_value in value),
        List(byte),
    )
    assert ssz.decode(serialized_value, byte_list) == value
Exemplo n.º 14
0
class Animal(Serializable):
    fields = [
        ('id_hash', bytes32),
        ('public_key', bytes48),
        ('clock_in_records', List(ClockInRecords)),
        ('vaccinated', boolean),
    ]
Exemplo n.º 15
0
class BeaconBlocksByRootRequest(ssz.Serializable):
    fields = [
        ('block_roots', List(bytes32, 1)),
    ]

    def __init__(self, block_roots: Sequence[SigningRoot]) -> None:
        super().__init__(block_roots)
Exemplo n.º 16
0
class IndexedAttestation(HashableContainer):

    fields = [
        # Validator indices
        ("attesting_indices", List(uint64, 1)),
        # Attestation data
        ("data", AttestationData),
        # Aggregate signature
        ("signature", bytes96),
    ]

    @classmethod
    def create(
        cls: Type[TIndexedAttestation],
        attesting_indices: Sequence[ValidatorIndex] = default_tuple,
        data: AttestationData = default_attestation_data,
        signature: BLSSignature = EMPTY_SIGNATURE,
    ) -> TIndexedAttestation:
        return super().create(
            attesting_indices=attesting_indices, data=data, signature=signature
        )

    def __str__(self) -> str:
        return (
            f"attesting_indices={self.attesting_indices},"
            f" data=({self.data}),"
            f" signature={humanize_hash(self.signature)}"
        )
Exemplo n.º 17
0
class Animal(HashableContainer):
    fields = [
        ("id_hash", bytes32),
        ("public_key", bytes48),
        ("clock_in_records", List(ClockInRecords, 2**32)),
        ("vaccinated", boolean),
    ]
Exemplo n.º 18
0
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)
Exemplo n.º 19
0
class Deposit(ssz.Serializable):
    """
    A :class:`~eth2.beacon.types.deposits.Deposit` contains the data represented by an instance
    of :class:`~eth2.beacon.types.deposit_data.DepositData`, along with a Merkle proof (``branch``
    and ``index``) that can be used to verify inclusion in the canonical deposit tree.
    """

    fields = [
        # Merkle branch in the deposit tree
        ('branch', List(bytes32)),
        # Index in the deposit tree
        ('index', uint64),
        # Deposit data
        ('deposit_data', DepositData),
    ]

    def __init__(self,
                 branch: Sequence[Hash32],
                 index: int,
                 deposit_data: DepositData)-> None:
        super().__init__(
            branch,
            index,
            deposit_data,
        )
Exemplo n.º 20
0
def test_list(value, serialized):
    sedes = List(uint8, 2**32)
    assert encode_hex(ssz.encode(value, sedes)) == serialized
    decoded = ssz.decode(decode_hex(serialized), sedes)
    assert isinstance(decoded, HashableList)
    assert tuple(decoded) == value
    assert decoded.sedes == sedes
Exemplo n.º 21
0
def test_list_of_dynamic_sized_entries(value, serialized):
    sedes = Vector(List(uint8, 2**32), len(value))
    assert encode_hex(ssz.encode(value, sedes)) == serialized
    decoded = ssz.decode(decode_hex(serialized), sedes)
    assert isinstance(decoded, HashableVector)
    assert tuple(tuple(element) for element in decoded) == value
    assert decoded.sedes == sedes
Exemplo n.º 22
0
class BeaconBlocksByRootRequest(HashableContainer):
    fields = [
        ('block_roots', List(bytes32, 64)),
    ]

    @classmethod
    def create(cls, block_roots: Sequence[Root]) -> "BeaconBlocksByRootRequest":
        return super().create(block_roots=block_roots)
Exemplo n.º 23
0
def genesis_validators(validator_count, pubkeys, config):
    """
    Returns ``validator_count`` number of activated validators.
    """
    return HashableList.from_iterable(
        (create_mock_validator(pubkey=pubkey, config=config)
         for pubkey in pubkeys[:validator_count]),
        List(Validator, config.VALIDATOR_REGISTRY_LIMIT),
    )
Exemplo n.º 24
0
class SlashableAttestation(ssz.Serializable):

    fields = [
        # Validator indices
        ('validator_indices', List(uint64)),
        # Attestation data
        ('data', AttestationData),
        # Custody bitfield
        ('custody_bitfield', byte_list),
        # Aggregate signature
        ('aggregate_signature', bytes96),
    ]

    def __init__(self,
                 validator_indices: Sequence[ValidatorIndex],
                 data: AttestationData,
                 custody_bitfield: bytes,
                 aggregate_signature: BLSSignature = EMPTY_SIGNATURE) -> None:
        super().__init__(
            validator_indices,
            data,
            custody_bitfield,
            aggregate_signature,
        )

    @property
    def are_validator_indices_ascending(self) -> bool:
        for i in range(len(self.validator_indices) - 1):
            if self.validator_indices[i] >= self.validator_indices[i + 1]:
                return False
        return True

    @property
    def custody_bit_indices(self) -> Tuple[Tuple[ValidatorIndex, ...], Tuple[ValidatorIndex, ...]]:
        custody_bit_0_indices = ()  # type: Tuple[ValidatorIndex, ...]
        custody_bit_1_indices = ()  # type: Tuple[ValidatorIndex, ...]
        for i, validator_index in enumerate(self.validator_indices):
            if not has_voted(self.custody_bitfield, i):
                custody_bit_0_indices += (validator_index,)
            else:
                custody_bit_1_indices += (validator_index,)

        return (custody_bit_0_indices, custody_bit_1_indices)

    @property
    def message_hashes(self) -> Tuple[Hash32, Hash32]:
        """
        Build the message_hashes that validators are expected to sign for an
        ``AttesterSlashing`` operation.
        """
        return (
            AttestationDataAndCustodyBit(data=self.data, custody_bit=False).root,
            AttestationDataAndCustodyBit(data=self.data, custody_bit=True).root,
        )
Exemplo n.º 25
0
def test_bytes_n_list_randomized(data, length, sequence_type):
    sedes = List(BytesN(length))
    items = data.draw(
        st.lists(
            st.binary(
                min_size=length,
                max_size=length,
            )
        )
    )
    value = sequence_type(items)
    assert len(hash_tree_root(value, sedes)) == 32
Exemplo n.º 26
0
def general_list_sedes_and_values_st(draw,
                                     element_sedes_and_elements,
                                     size=None):
    element_sedes, elements = element_sedes_and_elements

    if size is None:
        size = draw(st.integers(min_value=1, max_value=10))
    max_size = draw(st.integers(min_value=size, max_value=1024))

    sedes = List(element_sedes, max_length=max_size)
    values = st.lists(elements, min_size=size, max_size=size)
    return sedes, values
Exemplo n.º 27
0
def infer_list_sedes(obj):
    try:
        first_element, iterator = peek(obj)
    except StopIteration:
        # For empty lists we use any empty_list sedes.
        return empty_list
    else:
        try:
            element_sedes = infer_sedes(first_element)
        except TypeError:
            raise TypeError("Could not infer sedes for list elements", obj)
        else:
            return List(element_sedes)
Exemplo n.º 28
0
class BeaconBlockBody(ssz.Serializable):

    fields = [
        ("randao_reveal", bytes96),
        ("eth1_data", Eth1Data),
        ("graffiti", bytes32),
        ("proposer_slashings", List(ProposerSlashing, 1)),
        ("attester_slashings", List(AttesterSlashing, 1)),
        ("attestations", List(Attestation, 1)),
        ("deposits", List(Deposit, 1)),
        ("voluntary_exits", List(VoluntaryExit, 1)),
        ("transfers", List(Transfer, 1)),
    ]

    def __init__(
        self,
        *,
        randao_reveal: bytes96 = EMPTY_SIGNATURE,
        eth1_data: Eth1Data = default_eth1_data,
        graffiti: Hash32 = ZERO_HASH32,
        proposer_slashings: Sequence[ProposerSlashing] = default_tuple,
        attester_slashings: Sequence[AttesterSlashing] = default_tuple,
        attestations: Sequence[Attestation] = default_tuple,
        deposits: Sequence[Deposit] = default_tuple,
        voluntary_exits: Sequence[VoluntaryExit] = default_tuple,
        transfers: Sequence[Transfer] = default_tuple,
    ) -> None:
        super().__init__(
            randao_reveal=randao_reveal,
            eth1_data=eth1_data,
            graffiti=graffiti,
            proposer_slashings=proposer_slashings,
            attester_slashings=attester_slashings,
            attestations=attestations,
            deposits=deposits,
            voluntary_exits=voluntary_exits,
            transfers=transfers,
        )

    @property
    def is_empty(self) -> bool:
        return self == BeaconBlockBody()
Exemplo n.º 29
0
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))
Exemplo n.º 30
0
class BeaconBlockBody(ssz.Serializable):

    fields = [
        ('randao_reveal', bytes96),
        ('eth1_data', Eth1Data),
        ('proposer_slashings', List('ProposerSlashing')),
        ('attester_slashings', List(AttesterSlashing)),
        ('attestations', List(Attestation)),
        ('deposits', List(Deposit)),
        ('voluntary_exits', List(VoluntaryExit)),
        ('transfers', List(Transfer)),
    ]

    def __init__(self,
                 *,
                 randao_reveal: bytes96,
                 eth1_data: Eth1Data,
                 proposer_slashings: Sequence['ProposerSlashing'],
                 attester_slashings: Sequence[AttesterSlashing],
                 attestations: Sequence[Attestation],
                 deposits: Sequence[Deposit],
                 voluntary_exits: Sequence[VoluntaryExit],
                 transfers: Sequence[Transfer])-> None:
        super().__init__(
            randao_reveal=randao_reveal,
            eth1_data=eth1_data,
            proposer_slashings=proposer_slashings,
            attester_slashings=attester_slashings,
            attestations=attestations,
            deposits=deposits,
            voluntary_exits=voluntary_exits,
            transfers=transfers,
        )

    @classmethod
    def create_empty_body(cls) -> 'BeaconBlockBody':
        return cls(
            randao_reveal=EMPTY_SIGNATURE,
            eth1_data=Eth1Data.create_empty_data(),
            proposer_slashings=(),
            attester_slashings=(),
            attestations=(),
            deposits=(),
            voluntary_exits=(),
            transfers=(),
        )

    @property
    def is_empty(self) -> bool:
        return (
            self.randao_reveal == EMPTY_SIGNATURE and
            self.eth1_data == Eth1Data.create_empty_data() and
            self.proposer_slashings == () and
            self.attester_slashings == () and
            self.attestations == () and
            self.deposits == () and
            self.voluntary_exits == () and
            self.transfers == ()
        )

    @classmethod
    def cast_block_body(cls,
                        body: 'BeaconBlockBody') -> 'BeaconBlockBody':
        return cls(
            randao_reveal=body.randao_reveal,
            eth1_data=body.eth1_data,
            proposer_slashings=body.proposer_slashings,
            attester_slashings=body.attester_slashings,
            attestations=body.attestations,
            deposits=body.deposits,
            voluntary_exits=body.voluntary_exits,
            transfers=body.transfers,
        )

    _hash_tree_root = None

    @property
    def hash_tree_root(self) -> Hash32:
        if self._hash_tree_root is None:
            self._hash_tree_root = ssz.hash_tree_root(self)
        return self._hash_tree_root