Пример #1
0
def update_ffg_and_crosslink_progress(crystallized_state,
                                      crosslinks,
                                      ffg_voter_bitfield,
                                      votes,
                                      config=DEFAULT_CONFIG):
    # Verify the attestations of crosslink hashes
    crosslink_votes = {
        vote.shard_block_hash + vote.shard_id.to_bytes(2, 'big'):
        vote.voter_bitfield
        for vote in crosslinks
    }
    new_ffg_bitfield = ffg_voter_bitfield
    total_voters = 0

    # The shards that are selected to be crosslinking
    crosslink_shards = get_crosslink_shards(crystallized_state, config=config)

    for vote in votes:
        attestation = get_crosslink_aggvote_msg(vote.shard_id,
                                                vote.shard_block_hash,
                                                crystallized_state)
        # Check if this shard is in the crosslink shards list
        assert vote.shard_id in crosslink_shards

        indices = get_crosslink_notaries(
            crystallized_state,
            vote.shard_id,
            crosslink_shards=crosslink_shards,
            config=config,
        )
        votekey = vote.shard_block_hash + vote.shard_id.to_bytes(2, 'big')
        if votekey not in crosslink_votes:
            crosslink_votes[votekey] = b"" * get_bitfield_length(len(indices))
        bitfield = crosslink_votes[votekey]
        pubs = []
        for i, index in enumerate(indices):
            if has_voted(vote.notary_bitfield, i):
                pubs.append(crystallized_state.active_validators[index].pubkey)
                if has_voted(new_ffg_bitfield, index):
                    new_ffg_bitfield = set_voted(new_ffg_bitfield, index)
                    bitfield = set_voted(bitfield, i)
                    total_voters += 1
        assert bls.verify(attestation, bls.aggregate_pubs(pubs),
                          vote.aggregate_sig)
        crosslink_votes[votekey] = bitfield
        print('Verified aggregate vote')

    new_crosslinks = [
        PartialCrosslinkRecord(shard_id=int.from_bytes(h[32:], 'big'),
                               shard_block_hash=h[:32],
                               voter_bitfield=crosslink_votes[h])
        for h in sorted(crosslink_votes.keys())
    ]

    return new_crosslinks, new_ffg_bitfield, total_voters
Пример #2
0
    def mock_make_attestations(parent_state, block, attester_share=0.8):
        crystallized_state, active_state = parent_state
        cycle_length = config['cycle_length']

        in_cycle_slot_height = block.slot_number % cycle_length
        indices = crystallized_state.indices_for_slots[cycle_length +
                                                       in_cycle_slot_height]

        print("Generating attestations for shards: %s" % len(indices))

        attestations = []
        for shard_and_committee in indices:
            shard_id = shard_and_committee.shard_id
            committee_indices = shard_and_committee.committee
            print("Generating attestation for shard %s" % shard_id)
            print("Committee size %s" % len(committee_indices))

            # Create attestation
            attestation = AttestationRecord(
                slot=block.slot_number,
                shard_id=shard_and_committee.shard_id,
                oblique_parent_hashes=[],
                shard_block_hash=blake(bytes(str(shard_id), 'utf-8')),
                attester_bitfield=get_empty_bitfield(len(committee_indices)))

            # Randomly pick indices to include
            is_attesting = [
                random.random() < attester_share
                for _ in range(len(committee_indices))
            ]
            # Proposer always attests
            is_attesting[0] = True

            # Generating signatures and aggregating result
            parent_hashes = get_hashes_to_sign(active_state, block, config)
            message = blake(
                attestation.slot.to_bytes(8, byteorder='big') +
                b''.join(parent_hashes) +
                shard_id.to_bytes(2, byteorder='big') +
                attestation.shard_block_hash)
            sigs = [
                bls.sign(message,
                         keymap[crystallized_state.validators[indice].pubkey])
                for i, indice in enumerate(committee_indices)
                if is_attesting[i]
            ]
            attestation.aggregate_sig = bls.aggregate_sigs(sigs)
            print('Aggregated sig')

            attestation_bitfield = get_empty_bitfield(len(committee_indices))
            for i, attesting in enumerate(is_attesting):
                if attesting:
                    attestation_bitfield = set_voted(attestation_bitfield, i)
            attestation.attester_bitfield = attestation_bitfield
            print('Aggregate bitfield:',
                  bin(int.from_bytes(attestation_bitfield, 'big')))

            attestations.append(attestation)

        return attestations
Пример #3
0
def test_validate_attestation_attester_bitfield(attestation_validation_fixture,
                                                config):
    (crystallized_state, active_state, original_attestation, block,
     parent_block) = attestation_validation_fixture

    attestation = copy.deepcopy(original_attestation)
    attestation.attester_bitfield = get_empty_bitfield(10)
    with pytest.raises(ValidationError):
        validate_attestation(
            crystallized_state,
            active_state,
            attestation,
            block,
            parent_block,
            config,
        )

    attestation = copy.deepcopy(original_attestation)
    attestation_indices = get_attestation_indices(crystallized_state,
                                                  attestation, config)
    last_bit = len(attestation_indices)
    attestation.attester_bitfield = set_voted(attestation.attester_bitfield,
                                              last_bit)

    with pytest.raises(ValidationError):
        validate_attestation(
            crystallized_state,
            active_state,
            attestation,
            block,
            parent_block,
            config,
        )
Пример #4
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'
Пример #5
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)
Пример #6
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)
Пример #7
0
    def mock_make_attestations(parent_state, block, attester_share=0.8):
        crystallized_state, active_state = parent_state
        cycle_length = config['cycle_length']

        in_cycle_slot_height = block.slot_number % cycle_length
        indices = crystallized_state.shard_and_committee_for_slots[
            cycle_length + in_cycle_slot_height]

        print("Generating attestations for shards: %s" % len(indices))

        proposer_index_in_committee, proposer_shard_id = get_proposer_position(
            block,
            crystallized_state,
            config=config,
        )

        attestations = []
        for shard_and_committee in indices:
            shard_id = shard_and_committee.shard_id
            committee_indices = shard_and_committee.committee
            print("Generating attestation for shard %s" % shard_id)
            print("Committee size %s" % len(committee_indices))

            justified_slot = crystallized_state.last_justified_slot
            justified_block_hash = active_state.chain.get_block_by_slot_number(
                justified_slot).hash

            # Create attestation
            attestation = AttestationRecord(
                slot=block.slot_number,
                shard_id=shard_and_committee.shard_id,
                oblique_parent_hashes=[],
                shard_block_hash=blake(bytes(str(shard_id), 'utf-8')),
                attester_bitfield=get_empty_bitfield(len(committee_indices)),
                justified_slot=justified_slot,
                justified_block_hash=justified_block_hash,
            )

            # fill with roughly attester share fraction of voters
            is_attesting = [
                i < attester_share * len(committee_indices)
                for i in range(len(committee_indices))
            ]
            # Proposer always attests
            if shard_id == proposer_shard_id:
                is_attesting[proposer_index_in_committee] = True

            # Generating signatures and aggregating result
            parent_hashes = get_hashes_to_sign(active_state, block, config)
            message = blake(
                attestation.slot.to_bytes(8, byteorder='big') +
                b''.join(parent_hashes) +
                shard_id.to_bytes(2, byteorder='big') +
                attestation.shard_block_hash +
                attestation.justified_slot.to_bytes(8, byteorder='big'))
            sigs = [
                bls.sign(message,
                         keymap[crystallized_state.validators[indice].pubkey])
                for i, indice in enumerate(committee_indices)
                if is_attesting[i]
            ]
            attestation.aggregate_sig = bls.aggregate_sigs(sigs)
            print('Aggregated sig')

            attestation_bitfield = get_empty_bitfield(len(committee_indices))
            for i, attesting in enumerate(is_attesting):
                if attesting:
                    attestation_bitfield = set_voted(attestation_bitfield, i)
            attestation.attester_bitfield = attestation_bitfield
            print('Aggregate bitfield:',
                  bin(int.from_bytes(attestation_bitfield, 'big')))

            attestations.append(attestation)

        return attestations
Пример #8
0
    def make_unfinished_block(parent_state,
                              parent,
                              skips,
                              attester_share=0.8,
                              crosslink_shards_and_shares=None):
        if crosslink_shards_and_shares is None:
            crosslink_shards_and_shares = []

        crystallized_state, active_state = parent_state
        parent_attestation = serialize(parent)
        indices, proposer = get_attesters_and_proposer(
            crystallized_state,
            active_state,
            skips,
            config
        )

        print('Selected indices: %r' % indices)
        print('Selected block proposer: %d' % proposer)

        # Randomly pick indices to include
        is_attesting = [random.random() < attester_share for _ in indices]
        # Attestations
        sigs = [
            bls.sign(
                parent_attestation,
                keymap[crystallized_state.active_validators[indices[i]].pubkey]
            )
            for i, attesting in enumerate(is_attesting) if attesting
        ]
        attestation_aggregate_sig = bls.aggregate_sigs(sigs)
        print('Aggregated sig')

        attestation_bitfield = get_empty_bitfield(len(indices))
        for i, attesting in enumerate(is_attesting):
            if attesting:
                attestation_bitfield = set_voted(attestation_bitfield, i)
        print('Aggregate bitfield:', bin(int.from_bytes(attestation_bitfield, 'big')))

        # Randomly pick indices to include for crosslinks
        shard_aggregate_votes = []

        # The shards that are selected to be crosslinking
        crosslink_shards = get_crosslink_shards(crystallized_state, config=config)

        for shard, crosslinker_share in crosslink_shards_and_shares:
            # Check if this shard is in the crosslink shards list
            assert shard in crosslink_shards

            print('Making crosslink in shard %d' % shard)
            indices = get_crosslink_notaries(crystallized_state, shard, crosslink_shards=crosslink_shards, config=config)
            print('Indices: %r' % indices)
            is_notarizing = [random.random() < attester_share for _ in indices]
            notary_bitfield = get_empty_bitfield(len(indices))
            for i, notarizing in enumerate(is_notarizing):
                if notarizing:
                    notary_bitfield = set_voted(notary_bitfield, i)
            print('Bitfield:', bin(int.from_bytes(notary_bitfield, 'big')))
            shard_block_hash = blake(bytes([shard]))
            crosslink_attestation_hash = get_crosslink_aggvote_msg(
                shard,
                shard_block_hash,
                crystallized_state
            )
            sigs = [
                bls.sign(
                    crosslink_attestation_hash,
                    keymap[crystallized_state.active_validators[indices[i]].pubkey]
                )
                for i, notarizing in enumerate(is_notarizing) if notarizing
            ]
            v = AggregateVote(
                shard_id=shard,
                shard_block_hash=shard_block_hash,
                notary_bitfield=notary_bitfield,
                aggregate_sig=list(bls.aggregate_sigs(sigs))
            )
            shard_aggregate_votes.append(v)
        print('Added %d shard aggregate votes' % len(crosslink_shards_and_shares))

        block = Block(
            parent_hash=blake(parent_attestation),
            skip_count=skips,
            randao_reveal=blake(str(random.random()).encode('utf-8')),
            attestation_bitfield=attestation_bitfield,
            attestation_aggregate_sig=list(attestation_aggregate_sig),
            shard_aggregate_votes=shard_aggregate_votes,
            main_chain_ref=b'\x00'*32,
            state_hash=b'\x00'*64
        )
        return block, proposer
Пример #9
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)