Ejemplo n.º 1
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.º 2
0
def run_validate_block_proposer_signature(
        state: BeaconState, state_machine: BaseBeaconStateMachine,
        block: BaseBeaconBlock) -> None:
    # Fast forward to state in future slot in order to pass
    # block.slot validity check
    try:
        future_state = state_machine.state_transition.apply_state_transition(
            state,
            future_slot=block.slot,
        )
    except ValidationError as error:
        raise InvalidGossipMessage(
            "Failed to fast forward to state at slot=%d, error=%s",
            block.slot,
            str(error),
        )

    try:
        validate_proposer_signature(future_state, block,
                                    CommitteeConfig(state_machine.config))
    except ValidationError as error:
        logger.debug(
            "Failed to validate block=%s, error=%s",
            encode_hex(block.signing_root),
            str(error),
        )
Ejemplo n.º 3
0
def test_validate_proposer_signature(
        slots_per_epoch,
        shard_count,
        proposer_privkey,
        proposer_pubkey,
        is_valid_signature,
        sample_beacon_block_params,
        sample_beacon_state_params,
        target_committee_size,
        max_effective_balance,
        config):

    state = BeaconState(**sample_beacon_state_params).copy(
        validators=tuple(
            create_mock_validator(proposer_pubkey, config)
            for _ in range(10)
        ),
        balances=(max_effective_balance,) * 10,
    )

    block = BeaconBlock(**sample_beacon_block_params)
    header = block.header

    proposed_block = block.copy(
        signature=bls.sign(
            message_hash=header.signing_root,
            privkey=proposer_privkey,
            domain=get_domain(
                state,
                SignatureDomain.DOMAIN_BEACON_PROPOSER,
                slots_per_epoch,
            ),
        ),
    )

    if is_valid_signature:
        validate_proposer_signature(
            state,
            proposed_block,
            CommitteeConfig(config),
        )
    else:
        with pytest.raises(ValidationError):
            validate_proposer_signature(
                state,
                proposed_block,
                CommitteeConfig(config),
            )
def test_validate_proposer_signature(
        epoch_length, shard_count, proposer_privkey, proposer_pubkey,
        is_valid_signature, sample_beacon_block_params,
        sample_beacon_state_params, beacon_chain_shard_number, genesis_epoch,
        target_committee_size, max_deposit_amount):

    state = BeaconState(**sample_beacon_state_params).copy(
        validator_registry=tuple(
            mock_validator_record(proposer_pubkey) for _ in range(10)),
        validator_balances=(max_deposit_amount, ) * 10,
    )

    default_block = BeaconBlock(**sample_beacon_block_params)
    empty_signature_block_root = default_block.block_without_signature_root

    proposal_root = ProposalSignedData(
        state.slot,
        beacon_chain_shard_number,
        empty_signature_block_root,
    ).root

    proposed_block = BeaconBlock(**sample_beacon_block_params).copy(
        signature=bls.sign(
            message=proposal_root,
            privkey=proposer_privkey,
            domain=SignatureDomain.DOMAIN_PROPOSAL,
        ), )

    if is_valid_signature:
        validate_proposer_signature(
            state,
            proposed_block,
            beacon_chain_shard_number,
            genesis_epoch,
            epoch_length,
            target_committee_size,
            shard_count,
        )
    else:
        with pytest.raises(ValidationError):
            validate_proposer_signature(state, proposed_block,
                                        beacon_chain_shard_number,
                                        genesis_epoch, epoch_length,
                                        target_committee_size, shard_count)
def test_validate_proposer_signature(
        slots_per_epoch, shard_count, proposer_privkey, proposer_pubkey,
        is_valid_signature, sample_beacon_block_params,
        sample_beacon_state_params, target_committee_size, max_deposit_amount,
        config):

    state = BeaconState(**sample_beacon_state_params).copy(
        validator_registry=tuple(
            mock_validator(proposer_pubkey, config) for _ in range(10)),
        validator_balances=(max_deposit_amount, ) * 10,
    )

    block = BeaconBlock(**sample_beacon_block_params)
    header = block.header

    proposed_block = block.copy(signature=bls.sign(
        message_hash=header.signing_root,
        privkey=proposer_privkey,
        domain=get_domain(
            Fork(
                config.GENESIS_FORK_VERSION.to_bytes(4, 'little'),
                config.GENESIS_FORK_VERSION.to_bytes(4, 'little'),
                config.GENESIS_EPOCH,
            ),
            slot_to_epoch(state.slot, slots_per_epoch),
            SignatureDomain.DOMAIN_BEACON_BLOCK,
        ),
    ), )

    if is_valid_signature:
        validate_proposer_signature(
            state,
            proposed_block,
            CommitteeConfig(config),
        )
    else:
        with pytest.raises(ValidationError):
            validate_proposer_signature(
                state,
                proposed_block,
                CommitteeConfig(config),
            )
Ejemplo n.º 6
0
def test_validate_proposer_signature(
    slots_per_epoch,
    max_committees_per_slot,
    proposer_privkey,
    proposer_pubkey,
    is_valid_signature,
    sample_beacon_block_params,
    sample_beacon_state_params,
    target_committee_size,
    max_effective_balance,
    config,
):

    state = BeaconState.create(**sample_beacon_state_params).mset(
        "validators",
        tuple(
            create_mock_validator(proposer_pubkey, config) for _ in range(10)),
        "balances",
        (max_effective_balance, ) * 10,
    )

    block = BeaconBlock.create(**sample_beacon_block_params)

    proposed_block = SignedBeaconBlock.create(
        message=block,
        signature=bls.sign(
            message_hash=block.hash_tree_root,
            privkey=proposer_privkey,
            domain=get_domain(state, SignatureDomain.DOMAIN_BEACON_PROPOSER,
                              slots_per_epoch),
        ),
    )

    if is_valid_signature:
        validate_proposer_signature(state, proposed_block,
                                    CommitteeConfig(config))
    else:
        with pytest.raises(ValidationError):
            validate_proposer_signature(state, proposed_block,
                                        CommitteeConfig(config))
Ejemplo n.º 7
0
def run_validate_block_proposer_signature(
        state: BeaconState, state_machine: BaseBeaconStateMachine,
        block: BaseSignedBeaconBlock) -> None:
    # Fast forward to state in future slot in order to pass
    # block.slot validity check
    try:
        future_state, _ = state_machine.apply_state_transition(
            state,
            future_slot=block.slot,
        )
    except ValidationError as error:
        raise InvalidGossipMessage(
            f"Failed to fast forward to state at slot={block.slot}",
            error,
        )

    try:
        validate_proposer_signature(future_state, block, state_machine.config)
    except ValidationError as error:
        raise InvalidGossipMessage(
            f"Failed to validate block={encode_hex(block.message.hash_tree_root)}",
            error,
        )
Ejemplo n.º 8
0
def apply_fast_state_transition(
    epochs_ctx: EpochsContext,
    config: Eth2Config,
    state: BeaconState,
    signed_block: BaseSignedBeaconBlock = None,
    future_slot: Slot = None,
    check_proposer_signature: bool = True,
) -> BeaconState:
    """
    Callers should request a transition to some slot past the ``state.slot``.
    This can be done by providing either a ``block`` *or* a ``future_slot``.
    We enforce this invariant with the assertion on ``target_slot``.
    """
    target_slot = signed_block.message.slot if signed_block else future_slot
    assert target_slot is not None

    state = process_slots(epochs_ctx, state, target_slot, config)

    if signed_block:
        if check_proposer_signature:
            validate_proposer_signature(state, signed_block, config)
        state = process_block(epochs_ctx, state, signed_block.message, config)

    return state