Beispiel #1
0
def test_get_attestation_participants(
        monkeypatch,
        num_validators,
        epoch_length,
        committee,
        aggregation_bitfield,
        expected,
        sample_state,
        target_committee_size,
        shard_count,
        sample_attestation_data_params):
    shard = 1

    from eth2.beacon import helpers

    def mock_get_crosslink_committees_at_slot(state,
                                              slot,
                                              epoch_length,
                                              target_committee_size,
                                              shard_count):
        return (
            (committee, shard,),
        )

    monkeypatch.setattr(
        helpers,
        'get_crosslink_committees_at_slot',
        mock_get_crosslink_committees_at_slot
    )

    attestation_data = AttestationData(**sample_attestation_data_params).copy(
        slot=0,
        shard=shard,
    )
    if isinstance(expected, Exception):
        with pytest.raises(ValidationError):
            get_attestation_participants(
                state=sample_state,
                attestation_data=attestation_data,
                aggregation_bitfield=aggregation_bitfield,
                epoch_length=epoch_length,
                target_committee_size=target_committee_size,
                shard_count=shard_count,
            )
    else:
        result = get_attestation_participants(
            state=sample_state,
            attestation_data=attestation_data,
            aggregation_bitfield=aggregation_bitfield,
            epoch_length=epoch_length,
            target_committee_size=target_committee_size,
            shard_count=shard_count,
        )

        assert result == expected
Beispiel #2
0
def test_get_attestation_participants(
        monkeypatch,
        num_validators,
        epoch_length,
        committee,
        participation_bitfield,
        expected,
        sample_state):
    from eth2.beacon import helpers

    def mock_get_shard_committees_at_slot(state,
                                          slot,
                                          epoch_length):
        return (
            ShardCommittee(
                shard=0,
                committee=committee,
                total_validator_count=num_validators,
            ),
        )

    monkeypatch.setattr(
        helpers,
        'get_shard_committees_at_slot',
        mock_get_shard_committees_at_slot
    )

    if isinstance(expected, Exception):
        with pytest.raises(ValidationError):
            get_attestation_participants(
                state=sample_state,
                slot=0,
                shard=0,
                participation_bitfield=participation_bitfield,
                epoch_length=epoch_length,
            )
    else:
        result = get_attestation_participants(
            state=sample_state,
            slot=0,
            shard=0,
            participation_bitfield=participation_bitfield,
            epoch_length=epoch_length,
        )

        assert result == expected
Beispiel #3
0
def validate_attestation_aggregate_signature(state: BeaconState,
                                             attestation: Attestation,
                                             epoch_length: int,
                                             target_committee_size: int,
                                             shard_count: int) -> None:
    """
    Validate ``aggregate_signature`` field of ``attestation``.
    Raise ``ValidationError`` if it's invalid.

    Note: This is the phase 0 version of `aggregate_signature`` validation.
    All proof of custody bits are assumed to be 0 within the signed data.
    This will change to reflect real proof of custody bits in the Phase 1.
    """
    participant_indices = get_attestation_participants(
        state=state,
        attestation_data=attestation.data,
        aggregation_bitfield=attestation.aggregation_bitfield,
        epoch_length=epoch_length,
        target_committee_size=target_committee_size,
        shard_count=shard_count,
    )
    pubkeys = tuple(state.validator_registry[validator_index].pubkey
                    for validator_index in participant_indices)
    group_public_key = bls.aggregate_pubkeys(pubkeys)
    # TODO: change to tree hashing when we have SSZ
    message = AttestationDataAndCustodyBit.create_attestation_message(
        attestation.data)
    domain = get_domain(
        fork=state.fork,
        slot=attestation.data.slot,
        domain_type=SignatureDomain.DOMAIN_ATTESTATION,
    )

    is_valid_signature = bls.verify(
        message=message,
        pubkey=group_public_key,
        signature=attestation.aggregate_signature,
        domain=domain,
    )

    if not is_valid_signature:
        raise ValidationError("Attestation aggregate_signature is invalid. "
                              "message={}, participant_indices={} "
                              "domain={}".format(
                                  message,
                                  participant_indices,
                                  domain,
                              ))
Beispiel #4
0
def validate_serenity_attestation_aggregate_signature(
        state: BeaconState, attestation: Attestation,
        epoch_length: int) -> None:
    """
    Validate ``aggregate_signature`` field of ``attestation``.
    Raise ``ValidationError`` if it's invalid.

    Note: This is the phase 0 version of `aggregate_signature`` validation.
    All proof of custody bits are assumed to be 0 within the signed data.
    This will change to reflect real proof of custody bits in the Phase 1.
    """
    participant_indices = get_attestation_participants(
        state=state,
        slot=attestation.data.slot,
        shard=attestation.data.shard,
        participation_bitfield=attestation.participation_bitfield,
        epoch_length=epoch_length,
    )

    pubkeys = tuple(state.validator_registry[validator_index].pubkey
                    for validator_index in participant_indices)
    group_public_key = bls.aggregate_pubkeys(pubkeys)

    # TODO: change to tree hashing when we have SSZ
    # TODO: Replace with AttestationAndCustodyBit data structure
    message = hash_eth2(rlp.encode(attestation.data) + (0).to_bytes(1, "big"))

    is_valid_signature = bls.verify(
        message=message,
        pubkey=group_public_key,
        signature=attestation.aggregate_signature,
        domain=get_domain(
            fork_data=state.fork_data,
            slot=attestation.data.slot,
            domain_type=SignatureDomain.DOMAIN_ATTESTATION,
        ),
    )
    if not is_valid_signature:
        raise ValidationError(
            "Attestation ``aggregate_signature`` is invalid.")