Ejemplo n.º 1
0
def test_chaindb_get_score(chaindb, sample_beacon_block_params):
    genesis = BeaconBlock(**sample_beacon_block_params).copy(
        parent_root=GENESIS_PARENT_HASH,
        slot=0,
    )
    chaindb.persist_block(genesis, genesis.__class__)

    genesis_score_key = SchemaV1.make_block_root_to_score_lookup_key(
        genesis.root)
    genesis_score = ssz.decode(chaindb.db.get(genesis_score_key),
                               sedes=ssz.sedes.uint64)
    assert genesis_score == 0
    assert chaindb.get_score(genesis.root) == 0

    block1 = BeaconBlock(**sample_beacon_block_params).copy(
        parent_root=genesis.root,
        slot=1,
    )
    chaindb.persist_block(block1, block1.__class__)

    block1_score_key = SchemaV1.make_block_root_to_score_lookup_key(
        block1.root)
    block1_score = ssz.decode(chaindb.db.get(block1_score_key),
                              sedes=ssz.sedes.uint64)
    assert block1_score == 1
    assert chaindb.get_score(block1.root) == 1
Ejemplo n.º 2
0
def execute_invalid_ssz_test(test_case, sedes):
    if "value" in test_case and "ssz" in test_case:
        raise ValueError(
            "Test case for invalid inputs contains both value and ssz")

    if "value" in test_case:
        value = from_formatted_dict(test_case["value"], sedes, CustomCodec)
        try:
            ssz.encode(value, sedes)
        except SSZException:
            pass
        else:
            raise FailedTestCase(
                "Serializing invalid value did not yield an exception")

    elif "ssz" in test_case:
        serial = decode_hex(test_case["ssz"])
        try:
            ssz.decode(serial, sedes)
        except SSZException:
            pass
        else:
            raise FailedTestCase(
                "Deserializing invalid SSZ did not yield an exception")

    else:
        raise ValueError(
            "Test case for invalid inputs contains neither value nor ssz")
Ejemplo n.º 3
0
def main():
    logging.basicConfig(level=logging.DEBUG,
                        format='%(asctime)s %(levelname)s: %(message)s')
    override_lengths(MINIMAL_SERENITY_CONFIG)

    with open('state_15.ssz', 'rb') as f:
        pre_state_encoded = f.read()
    pre_state = ssz.decode(pre_state_encoded, sedes=BeaconState)

    with open('block_16.ssz', 'rb') as f:
        block_encoded = f.read()
    pre_block = ssz.decode(block_encoded, sedes=BeaconBlock)

    trinity_post = trinity_transition(pre_state, pre_block)
    pyspec_post = pyspec_transition(pre_state, pre_block)

    for index in range(len(pyspec_post.balances)):
        assert trinity_post.balances[index] == pyspec_post.balances[index]

        if trinity_post.balances[index] == pyspec_post.balances[index]:
            continue
        print(f"trinity balances[{index}]: \t"
              f"{trinity_post.balances[index].to_bytes(8, 'big').hex()}")
        print(f"pyspec balances[{index}]: \t"
              f"{pyspec_post.balances[index].to_bytes(8, 'big').hex()}")

    print(f"trinity: {trinity_post.current_crosslinks[7]}")
    print(f"pyspec: {pyspec_post.current_crosslinks[7]}")
Ejemplo n.º 4
0
def test_byte_vector_invalid_length(value, expected_length):
    byte_vector = ByteVector(expected_length)
    with pytest.raises(SerializationError):
        ssz.encode(value, byte_vector)

    properly_serialized_value = value
    with pytest.raises(DeserializationError):
        ssz.decode(properly_serialized_value, byte_vector)
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
 def _get_genesis_data(self) -> Tuple[Timestamp, Root]:
     key = SchemaV1.genesis_data()
     try:
         data = self.db[key]
     except KeyError:
         return default_timestamp, default_root
     genesis_time = ssz.decode(data[:8], ssz.sedes.uint64)
     genesis_validators_root = ssz.decode(data[8:], ssz.sedes.bytes32)
     return Timestamp(genesis_time), Root(genesis_validators_root)
Ejemplo n.º 7
0
def test_deserialization_for_custom_init_method():
    type_3 = SSZType3(2, 1, 3)
    assert type_3.field1 == 1
    assert type_3.field2 == 2
    assert type_3.field3 == 3

    result = decode(encode(type_3), sedes=SSZType3)
    assert result.field1 == 1
    assert result.field2 == 2
    assert result.field3 == 3

    result_sedes_encode = decode(encode(type_3, SSZType3), sedes=SSZType3)
    assert result_sedes_encode.field1 == 1
    assert result_sedes_encode.field2 == 2
    assert result_sedes_encode.field3 == 3
Ejemplo n.º 8
0
def test_tuple_of_static_sized_entries(value, serialized):
    sedes = Vector(uint8, len(value))
    assert encode_hex(ssz.encode(value, sedes)) == serialized
    decoded = ssz.decode(decode_hex(serialized), sedes)
    assert isinstance(decoded, HashableVector)
    assert tuple(decoded) == value
    assert decoded.sedes == sedes
Ejemplo n.º 9
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
Ejemplo n.º 10
0
    def beacon_aggregate_and_proof_validator(msg_forwarder: ID,
                                             msg: rpc_pb2.Message) -> bool:
        try:
            aggregate_and_proof = ssz.decode(msg.data, sedes=AggregateAndProof)
        except (TypeError, ssz.DeserializationError) as error:
            # Not correctly encoded
            logger.debug(
                bold_red(
                    "Failed to deserialize AggregateAndProof from %s, error=%s"
                ),
                encode_hex(msg.data),
                str(error),
            )
            return False

        state = chain.get_head_state()
        state_machine = chain.get_state_machine()
        attestation = aggregate_and_proof.aggregate

        try:
            validate_voting_beacon_block(chain, attestation)
            run_validate_aggregate_and_proof(
                state,
                aggregate_and_proof,
                state_machine.config,
            )
        except InvalidGossipMessage as error:
            logger.debug("%s", str(error))
            return False

        return True
Ejemplo n.º 11
0
async def test_get_canonical_block_range_by_root(request, event_loop):
    chain_db = get_chain_db()

    genesis = create_test_block(slot=0)
    base_branch = create_branch(3, root=genesis)
    non_canonical_branch = create_branch(3,
                                         root=base_branch[-1],
                                         state_root=b"\x00" * 32)
    canonical_branch = create_branch(4,
                                     root=base_branch[-1],
                                     state_root=b"\x11" * 32)

    for branch in [[genesis], base_branch, non_canonical_branch,
                   canonical_branch]:
        chain_db.persist_block_chain(branch, BeaconBlock)

    alice, response_buffer = await get_request_server_setup(
        request, event_loop, chain_db)

    alice.sub_proto.send_get_blocks(base_branch[1].root, 4, request_id=5)
    response = await response_buffer.msg_queue.get()

    assert isinstance(response.command, BeaconBlocks)
    assert response.payload["request_id"] == 5
    blocks = tuple(
        ssz.decode(block, BeaconBlock)
        for block in response.payload["encoded_blocks"])
    assert len(blocks) == 4
    assert [block.slot for block in blocks] == [2, 3, 4, 5]
    assert blocks == base_branch[1:] + canonical_branch[:2]
Ejemplo n.º 12
0
    def committee_index_beacon_attestation_validator(
            msg_forwarder: ID, msg: rpc_pb2.Message) -> bool:
        try:
            attestation = ssz.decode(msg.data, sedes=Attestation)
        except (TypeError, ssz.DeserializationError) as error:
            # Not correctly encoded
            logger.debug(
                bold_red("Failed to validate attestation=%s, error=%s"),
                encode_hex(msg.data),
                str(error),
            )
            return False

        state_machine = chain.get_state_machine()
        state = chain.get_head_state()

        try:
            validate_subnet_id(attestation, subnet_id)
            validate_is_unaggregated(attestation)
            validate_voting_beacon_block(chain, attestation)
            validate_attestation_propagation_slot_range(
                state,
                attestation,
                ATTESTATION_PROPAGATION_SLOT_RANGE,
            )
            validate_attestation_signature(
                state,
                attestation,
                CommitteeConfig(state_machine.config),
            )
        except InvalidGossipMessage as error:
            logger.debug("%s", str(error))
            return False
        else:
            return True
Ejemplo n.º 13
0
 def _get_score(db: BaseDB, block_root: Hash32) -> int:
     try:
         encoded_score = db[SchemaV1.make_block_root_to_score_lookup_key(block_root)]
     except KeyError:
         raise BlockNotFound("No block with hash {0} found".format(
             encode_hex(block_root)))
     return ssz.decode(encoded_score, sedes=ssz.sedes.uint64)
Ejemplo n.º 14
0
 def from_wire_bytes(cls: Type["MessagePacket"], data: bytes) -> "MessagePacket":
     tag, auth_tag, encrypted_message = ssz.decode(data, MESSAGE_PACKET_SEDES)
     return cls(
         tag=tag,
         auth_tag=auth_tag,
         encrypted_message=encrypted_message,
     )
Ejemplo n.º 15
0
def _decrypt_payload(key: AES128Key,
                     auth_tag: Nonce,
                     encrypted_message: bytes,
                     authenticated_data: bytes,
                     message_registry: RegistryAPI,
                     ) -> ssz.Serializable:
    plain_text = aesgcm_decrypt(
        key=key,
        nonce=auth_tag,
        cipher_text=encrypted_message,
        authenticated_data=authenticated_data,
    )

    try:
        message_id = plain_text[0]
    except IndexError:
        raise ValidationError("Decrypted message is empty")

    try:
        sedes = message_registry.get_sedes(message_id)
    except KeyError:
        raise ValidationError(f"Unknown message type {message_id}")

    try:
        message = ssz.decode(plain_text[1:], sedes)
    except ssz.DeserializationError as error:
        raise ValidationError("Encrypted message does not contain valid RLP") from error

    return message
Ejemplo n.º 16
0
 def from_wire_bytes(cls: Type["CompleteHandshakePacket"],
                     data: bytes) -> "CompleteHandshakePacket":
     tag, header_as_tuple, encrypted_message = ssz.decode(data, COMPLETE_HANDSHAKE_PACKET_SEDES)
     (
         auth_tag,
         id_nonce,
         auth_scheme_name,
         ephemeral_public_key_bytes,
         public_key_bytes,
         encrypted_auth_response,
     ) = header_as_tuple
     ephemeral_public_key = keys.PublicKey.from_compressed_bytes(ephemeral_public_key_bytes)
     public_key = keys.PublicKey.from_compressed_bytes(public_key_bytes)
     header = AuthHeader(
         auth_tag,
         id_nonce,
         auth_scheme_name,
         ephemeral_public_key,
         public_key=public_key,
         encrypted_auth_response=encrypted_auth_response,
     )
     return cls(
         tag=tag,
         header=header,
         encrypted_message=encrypted_message,
     )
Ejemplo n.º 17
0
async def test_bcc_receive_server_handle_attestations_checks(
        request, event_loop, event_bus, monkeypatch):
    async with get_peer_and_receive_server(
            request,
            event_loop,
            event_bus,
    ) as (alice, _, bob_recv_server, bob_msg_queue):

        attestation = Attestation()

        def _validate_attestations(attestations):
            return tuple(attestations)

        monkeypatch.setattr(
            bob_recv_server,
            '_validate_attestations',
            _validate_attestations,
        )

        alice.sub_proto.send_attestation_records([attestation])
        msg = await bob_msg_queue.get()
        assert len(msg['encoded_attestations']) == 1
        decoded_attestation = ssz.decode(msg['encoded_attestations'][0],
                                         Attestation)
        assert decoded_attestation == attestation
Ejemplo n.º 18
0
    def _read_state_eth1_data_votes(self,
                                    state_root: Root) -> Iterable[Eth1Data]:
        key = SchemaV1.state_root_to_eth1_data_votes(state_root)
        roots = _bytes_to_roots(self.db[key])

        for root in roots:
            yield ssz.decode(self.db[bytes(root)], Eth1Data)
Ejemplo n.º 19
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
Ejemplo n.º 20
0
    def mark_finalized_head(self, block: BaseBeaconBlock) -> None:
        """
        Marks the given ``block`` as finalized and stores each newly finalized state and block at
        their corresponding slot.
        """
        if block.slot > 0:
            newly_finalized_states = self.get_state_parents(
                block.state_root,
                block.slot - self.get_finalized_head(BeaconBlock).slot) + (
                    block.state_root, )
        else:
            newly_finalized_states = (block.state_root, )

        for state_root in newly_finalized_states:
            slot = ssz.decode(self.db[SchemaV1.state_root_to_slot(state_root)],
                              ssz.uint64)
            self.db[SchemaV1.slot_to_state_root(slot)] = state_root

            latest_block_header = self._read_state_block_header(state_root)
            slot_to_block_root = SchemaV1.slot_to_block_root(
                latest_block_header.slot)
            self.db[slot_to_block_root] = latest_block_header.hash_tree_root

        self.db[SchemaV1.slot_to_block_root(block.slot)] = block.hash_tree_root
        self.db[SchemaV1.finalized_head_root()] = block.hash_tree_root
Ejemplo n.º 21
0
 def decode_payload(self, data: bytes) -> sedes.Serializable:
     message_id = data[0]
     try:
         sedes = self._payload_sedes[message_id]
     except KeyError:
         raise ValueError(f"Unknown message type: {message_id}")
     return ssz.decode(data[1:], sedes)
Ejemplo n.º 22
0
    async def _handle_attestations(self, peer: BCCPeer, msg: AttestationsMessage) -> None:
        if not peer.is_operational:
            return
        encoded_attestations = msg["encoded_attestations"]
        attestations = tuple(
            ssz.decode(encoded_attestation, Attestation)
            for encoded_attestation in encoded_attestations
        )
        self.logger.debug("Received attestations=%s", attestations)

        # Validate attestations
        valid_attestations = self._validate_attestations(attestations)
        if len(valid_attestations) == 0:
            return

        # Check if attestations has been seen already.
        # Filter out those seen already.
        valid_new_attestations = tuple(
            filter(
                self._is_attestation_new,
                valid_attestations,
            )
        )
        if len(valid_new_attestations) == 0:
            return
        # Add the valid and new attestations to attestation pool.
        self.attestation_pool.batch_add(valid_new_attestations)
        # Broadcast the valid and new attestations.
        self._broadcast_attestations(valid_new_attestations, peer)
Ejemplo n.º 23
0
async def test_get_incomplete_canonical_block_range(request, event_loop,
                                                    event_bus):
    chain_db = await get_chain_db()

    genesis = create_test_block()
    base_branch = create_branch(3, root=genesis)
    non_canonical_branch = create_branch(3,
                                         root=base_branch[-1],
                                         state_root=b"\x00" * 32)
    canonical_branch = create_branch(4,
                                     root=base_branch[-1],
                                     state_root=b"\x11" * 32)

    for branch in [[genesis], base_branch, non_canonical_branch,
                   canonical_branch]:
        scorings = (higher_slot_scoring for block in branch)
        await chain_db.coro_persist_block_chain(branch, BeaconBlock, scorings)

    async with get_request_server_setup(request, event_loop, event_bus,
                                        chain_db) as (alice, response_buffer):

        alice.sub_proto.send_get_blocks(genesis.slot + 3, 10, request_id=5)
        response = await response_buffer.msg_queue.get()

        assert isinstance(response.command, BeaconBlocks)
        assert response.payload["request_id"] == 5
        blocks = tuple(
            ssz.decode(block, BeaconBlock)
            for block in response.payload["encoded_blocks"])
        assert len(blocks) == 5
        assert [block.slot for block in blocks
                ] == [genesis.slot + s for s in [3, 4, 5, 6, 7]]
        assert blocks == base_branch[-1:] + canonical_branch
Ejemplo n.º 24
0
    def _read_state_current_epoch_attestations(
            self, state_root: Root) -> Iterable[PendingAttestation]:
        key = SchemaV1.state_root_to_current_epoch_attestations(state_root)
        roots = _bytes_to_roots(self.db[key])

        for root in roots:
            yield ssz.decode(self.db[bytes(root)], PendingAttestation)
Ejemplo n.º 25
0
    def beacon_block_validator(msg_forwarder: ID,
                               msg: rpc_pb2.Message) -> bool:
        try:
            block = ssz.decode(msg.data, BeaconBlock)
        except (TypeError, ssz.DeserializationError) as error:
            logger.debug(
                bold_red("Failed to validate block=%s, error=%s"),
                encode_hex(block.signing_root),
                str(error),
            )
            return False

        state_machine = chain.get_state_machine(block.slot - 1)
        state_transition = state_machine.state_transition
        state = chain.get_head_state()
        # Fast forward to state in future slot in order to pass
        # block.slot validity check
        state = state_transition.apply_state_transition(
            state,
            future_slot=block.slot,
        )
        try:
            validate_proposer_signature(state, block,
                                        CommitteeConfig(state_machine.config))
        except ValidationError as error:
            logger.debug(
                bold_red("Failed to validate block=%s, error=%s"),
                encode_hex(block.signing_root),
                str(error),
            )
            return False
        else:
            return True
Ejemplo n.º 26
0
def test_byte_vector(value):
    byte_vector = ByteVector(len(value))
    serialized_value = ssz.encode(value, byte_vector)
    assert serialized_value == ssz.encode(
        tuple(bytes([byte_value]) for byte_value in value),
        Vector(byte, len(value)))
    assert ssz.decode(serialized_value, byte_vector) == value
Ejemplo n.º 27
0
    def beacon_attestation_validator(msg_forwarder: ID,
                                     msg: rpc_pb2.Message) -> bool:
        try:
            attestation = ssz.decode(msg.data, sedes=Attestation)
        except (TypeError, ssz.DeserializationError) as error:
            # Not correctly encoded
            logger.debug(
                bold_red(
                    "Failed to deserialize Attestation from %s, error=%s"),
                encode_hex(msg.data),
                str(error),
            )
            return False

        state = chain.get_head_state()
        state_machine = chain.get_state_machine()

        try:
            validate_voting_beacon_block(chain, attestation)
            validate_attestation_signature(
                state,
                attestation,
                CommitteeConfig(state_machine.config),
            )
        except InvalidGossipMessage as error:
            logger.debug("%s", str(error))
            return False
        else:
            return True
Ejemplo n.º 28
0
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
Ejemplo n.º 29
0
async def test_get_non_canonical_branch(request, event_loop):
    chain_db = await get_chain_db()

    genesis = create_test_block()
    base_branch = create_branch(3, root=genesis)
    non_canonical_branch = create_branch(3,
                                         root=base_branch[-1],
                                         state_root=b"\x00" * 32)
    canonical_branch = create_branch(4,
                                     root=base_branch[-1],
                                     state_root=b"\x11" * 32)

    for branch in [[genesis], base_branch, non_canonical_branch,
                   canonical_branch]:
        await chain_db.coro_persist_block_chain(branch, BeaconBlock)

    alice, response_buffer = await get_request_server_setup(
        request, event_loop, chain_db)

    alice.sub_proto.send_get_blocks(non_canonical_branch[1].signing_root,
                                    3,
                                    request_id=5)
    response = await response_buffer.msg_queue.get()

    assert isinstance(response.command, BeaconBlocks)
    assert response.payload["request_id"] == 5
    blocks = tuple(
        ssz.decode(block, BeaconBlock)
        for block in response.payload["encoded_blocks"])
    assert len(blocks) == 1
    assert blocks[0].slot == genesis.slot + 5
    assert blocks[0] == non_canonical_branch[1]
Ejemplo n.º 30
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