Beispiel #1
0
def test_aggregate_votes(votes_count, random, privkeys, pubkeys):
    bit_count = 10
    pre_bitfield = get_empty_bitfield(bit_count)
    pre_sigs = ()

    random_votes = random.sample(range(bit_count), votes_count)
    message = b'hello'

    # Get votes: (committee_index, sig, public_key)
    votes = [(committee_index, bls.sign(message, privkeys[committee_index]),
              pubkeys[committee_index]) for committee_index in random_votes]

    # Verify
    sigs, committee_indices = verify_votes(message, votes)

    # Aggregate the votes
    bitfield, sigs = aggregate_votes(
        bitfield=pre_bitfield,
        sigs=pre_sigs,
        voting_sigs=sigs,
        voting_committee_indices=committee_indices)

    try:
        _, _, pubs = zip(*votes)
    except ValueError:
        pubs = ()

    voted_index = [
        committee_index for committee_index in random_votes
        if has_voted(bitfield, committee_index)
    ]
    assert len(voted_index) == len(votes)

    aggregated_pubs = bls.aggregate_pubs(pubs)
    assert bls.verify(message, aggregated_pubs, sigs)
Beispiel #2
0
def test_validate_bitfield(attestation_validation_fixture, cycle_length):
    (
        crystallized_state,
        _,
        attestation,
        _,
        _,
        _,
    ) = attestation_validation_fixture

    attestation_indices = get_attestation_indices(
        crystallized_state,
        attestation,
        cycle_length,
    )

    # Case 1: Attestation has incorrect bitfield length
    attestation_case_1 = attestation.copy(
        attester_bitfield=get_empty_bitfield(10), )
    with pytest.raises(ValidationError):
        validate_bitfield(attestation_case_1, attestation_indices)

    # Case 2: End bits are not all zero
    last_bit = len(attestation_indices)
    attestation_case_2 = attestation.copy(attester_bitfield=set_voted(
        attestation.attester_bitfield, last_bit), )
    with pytest.raises(ValidationError):
        validate_bitfield(attestation_case_2, attestation_indices)
Beispiel #3
0
def test_bitfield_all_votes():
    attesters = list(range(10))

    bitfield = get_empty_bitfield(len(attesters))
    for attester in attesters:
        bitfield = set_voted(bitfield, attester)

    for attester in attesters:
        assert has_voted(bitfield, attester)
    assert bitfield == b'\xff\xc0'
Beispiel #4
0
    def attest_proposed_block(cls, post_crystallized_state: CrystallizedState,
                              post_active_state: ActiveState,
                              block_proposal: 'BlockProposal',
                              chaindb: BaseBeaconChainDB,
                              private_key: int) -> 'AttestationRecord':
        """
        Return the initial attestation by the block proposer.

        The proposer broadcasts their attestation with the proposed block.
        """
        block_committees_info = get_block_committees_info(
            block_proposal.block,
            post_crystallized_state,
            cls.config.CYCLE_LENGTH,
        )
        # Vote
        attester_bitfield = set_voted(
            get_empty_bitfield(block_committees_info.proposer_committee_size),
            block_committees_info.proposer_index_in_committee,
        )

        # Get justified_slot and justified_block_hash
        justified_slot = post_crystallized_state.last_justified_slot
        justified_block_hash = chaindb.get_canonical_block_hash_by_slot(
            justified_slot)

        # Get signing message and sign it
        parent_hashes = get_hashes_to_sign(
            post_active_state.recent_block_hashes,
            block_proposal.block,
            cls.config.CYCLE_LENGTH,
        )

        message = create_signing_message(
            block_proposal.block.slot_number,
            parent_hashes,
            block_proposal.shard_id,
            block_proposal.shard_block_hash,
            justified_slot,
        )
        sig = bls.sign(
            message,
            private_key,
        )

        return cls.get_attestation_record_class()(
            slot=block_proposal.block.slot_number,
            shard_id=block_proposal.shard_id,
            oblique_parent_hashes=(),
            shard_block_hash=block_proposal.shard_block_hash,
            attester_bitfield=attester_bitfield,
            justified_slot=justified_slot,
            justified_block_hash=justified_block_hash,
            aggregate_sig=sig,
        )
Beispiel #5
0
def test_or_bitfields():
    bitfield_1 = get_empty_bitfield(2)
    bitfield_1 = set_voted(bitfield_1, 0)
    assert get_vote_count(bitfield_1) == 1

    # same size as bitfield_1
    bitfield_2 = get_empty_bitfield(2)
    bitfield_2 = set_voted(bitfield_2, 1)
    assert get_vote_count(bitfield_2) == 1

    bitfield = or_bitfields([bitfield_1, bitfield_2])
    assert get_vote_count(bitfield) == 2

    # different size from bitfield_1
    bitfield_3 = get_empty_bitfield(100)
    bitfield_3 = set_voted(bitfield_3, 99)
    assert get_vote_count(bitfield_3) == 1

    with pytest.raises(ValueError):
        or_bitfields([bitfield_1, bitfield_3])
Beispiel #6
0
def test_has_voted_random(votes_count):
    bit_count = 1000
    bitfield = get_empty_bitfield(bit_count)
    random_votes = random.sample(range(bit_count), votes_count)

    for index in random_votes:
        bitfield = set_voted(bitfield, index)
    assert get_vote_count(bitfield) == votes_count

    for index in range(bit_count):
        if index in random_votes:
            assert has_voted(bitfield, index)
        else:
            assert not has_voted(bitfield, index)
Beispiel #7
0
def test_bitfield_some_votes():
    attesters = list(range(10))
    voters = [0, 4, 5, 9]

    bitfield = get_empty_bitfield(len(attesters))
    for voter in voters:
        bitfield = set_voted(bitfield, voter)

    assert bitfield == b'\x8c\x40'

    for attester in attesters:
        if attester in voters:
            assert has_voted(bitfield, attester)
        else:
            assert not has_voted(bitfield, attester)
Beispiel #8
0
def test_or_bitfields_random(votes):
    bitfields = []
    bit_count = 100

    for vote in votes:
        bitfield = get_empty_bitfield(bit_count)
        for index in vote:
            bitfield = set_voted(bitfield, index)
        bitfields.append(bitfield)

    bitfield = or_bitfields(bitfields)

    for index in range(bit_count):
        if has_voted(bitfield, index):
            assert any(has_voted(b, index) for b in bitfields)
Beispiel #9
0
def test_bitfield_single_votes():
    attesters = list(range(10))
    bitfield = get_empty_bitfield(len(attesters))

    assert set_voted(bitfield, 0) == b'\x80\x00'
    assert set_voted(bitfield, 1) == b'\x40\x00'
    assert set_voted(bitfield, 2) == b'\x20\x00'
    assert set_voted(bitfield, 7) == b'\x01\x00'
    assert set_voted(bitfield, 8) == b'\x00\x80'
    assert set_voted(bitfield, 9) == b'\x00\x40'

    for voter in attesters:
        bitfield = set_voted(b'\x00\x00', voter)
        for attester in attesters:
            if attester == voter:
                assert has_voted(bitfield, attester)
            else:
                assert not has_voted(bitfield, attester)
Beispiel #10
0
def test_validate_parent_block_proposer(attestation_validation_fixture,
                                        cycle_length):
    (
        crystallized_state,
        _,
        attestation,
        block,
        parent_block,
        _,
    ) = attestation_validation_fixture

    validate_parent_block_proposer(
        crystallized_state,
        block,
        parent_block,
        cycle_length,
    )

    # Case 1: No attestations
    block = block.copy(attestations=())
    with pytest.raises(ValidationError):
        validate_parent_block_proposer(
            crystallized_state,
            block,
            parent_block,
            cycle_length,
        )

    # Case 2: Proposer didn't attest
    block = block.copy(attestations=[
        attestation.copy(attester_bitfield=get_empty_bitfield(10), )
    ])
    with pytest.raises(ValidationError):
        validate_parent_block_proposer(
            crystallized_state,
            block,
            parent_block,
            cycle_length,
        )
Beispiel #11
0
def test_bitfield_multiple_votes():
    bitfield = get_empty_bitfield(1)
    bitfield = set_voted(bitfield, 0)
    bitfield = set_voted(bitfield, 0)
    assert has_voted(bitfield, 0)
Beispiel #12
0
def test_empty_bitfield():
    attesters = list(range(10))
    bitfield = get_empty_bitfield(len(attesters))

    for attester in attesters:
        assert not has_voted(bitfield, attester)
Beispiel #13
0
def test_set_vote_and_has_vote(bit_count):
    bitfield = get_empty_bitfield(bit_count)
    index = random.choice(range(bit_count))
    bitfield = set_voted(bitfield, index)
    assert has_voted(bitfield, index)
Beispiel #14
0
def test_get_vote_count():
    bitfield = get_empty_bitfield(5)
    bitfield = set_voted(bitfield, 0)
    bitfield = set_voted(bitfield, 3)
    assert get_vote_count(bitfield) == 2