Ejemplo n.º 1
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
Ejemplo n.º 2
0
def genesis_crystallized_state(init_validator_keys,
                               init_shuffling_seed,
                               config):
    return CrystallizedState(
        active_validators=[ValidatorRecord(
            pubkey=pub,
            withdrawal_shard=0,
            withdrawal_address=blake(pub.to_bytes(32, 'big'))[-20:],
            randao_commitment=b'\x55'*32,
            balance=DEFAULT_BALANCE,
            switch_dynasty=DEFAULT_SWITCH_DYNASTY
        ) for pub in init_validator_keys],
        queued_validators=[],
        exited_validators=[],
        current_shuffling=get_shuffling(init_shuffling_seed, len(init_validator_keys), config=config),
        current_epoch=1,
        last_justified_epoch=0,
        last_finalized_epoch=0,
        dynasty=1,
        next_shard=0,
        current_checkpoint=blake(b'insert EOS constitution here'),
        crosslink_records=[
            CrosslinkRecord(hash=b'\x00'*32, epoch=0) for i in range(SHARD_COUNT)
        ],
        total_deposits=DEFAULT_BALANCE*len(init_validator_keys)
    )
Ejemplo n.º 3
0
    def mock_make_child(parent_state, parent, slot_number, attestations=None):
        if attestations is None:
            attestations = []

        crystallized_state, active_state = parent_state
        block = Block(parent_hash=parent.hash,
                      slot_number=slot_number,
                      randao_reveal=blake(
                          str(random.random()).encode('utf-8')),
                      attestations=attestations,
                      pow_chain_ref=b'\x00' * 32,
                      active_state_root=b'\x00' * 32,
                      crystallized_state_root=b'\x00' * 32)
        print('Generated preliminary block header')

        new_crystallized_state, new_active_state = compute_state_transition(
            (crystallized_state, active_state), parent, block, config=config)
        print('Calculated state transition')

        if crystallized_state == new_crystallized_state:
            block.crystallized_state_root = parent.crystallized_state_root
        else:
            block.crystallized_state_root = blake(
                serialize(crystallized_state))

        block.active_state_root = blake(serialize(active_state))

        return block, new_crystallized_state, new_active_state
Ejemplo n.º 4
0
    def mock_make_child(parent_state,
                        parent,
                        skips,
                        attester_share=0.8,
                        crosslink_shards=[]):
        crystallized_state, active_state = parent_state
        block, proposer = make_unfinished_block(parent_state, parent, skips,
                                                attester_share,
                                                crosslink_shards)
        print('Generated preliminary block header')

        new_crystallized_state, new_active_state = compute_state_transition(
            (crystallized_state, active_state),
            parent,
            block,
            verify_sig=False,
            config=config)
        print('Calculated state transition')

        if crystallized_state == new_crystallized_state:
            block.state_hash = blake(parent.state_hash[:32] +
                                     blake(serialize(new_active_state)))
        else:
            block.state_hash = blake(
                blake(serialize(new_crystallized_state)) +
                blake(serialize(new_active_state)))
        # Main signature
        block.sign(
            keymap[crystallized_state.active_validators[proposer].pubkey])
        print('Signed')

        return block, new_crystallized_state, new_active_state
Ejemplo n.º 5
0
def genesis_block(genesis_active_state, genesis_crystallized_state):
    active_state_root = blake(serialize(genesis_active_state))
    crystallized_state_root = blake(serialize(genesis_crystallized_state))

    return get_genesis_block(
        active_state_root=active_state_root,
        crystallized_state_root=crystallized_state_root,
    )
Ejemplo n.º 6
0
 def mock_make_child(parent_state, parent, skips, attester_share=0.8, crosslink_shards=[]):
     crystallized_state, active_state = parent_state
     parent_attestation = serialize(parent)
     indices, main_signer = get_attesters_and_signer(crystallized_state, active_state, skips)
     print('Selected indices: %r' % indices)
     print('Selected main signer: %d' % main_signer)
     # Randomly pick indices to include
     bitfield = [1 if random.random() < attester_share else 0 for i in indices]
     # Attestations
     sigs = [bls.sign(parent_attestation, keymap[crystallized_state.active_validators[indices[i]].pubkey])
             for i in range(len(indices)) if bitfield[i]]
     attestation_aggregate_sig = bls.aggregate_sigs(sigs)
     print('Aggregated sig')
     attestation_bitmask = bytearray((len(bitfield)-1) // 8 + 1)
     for i, b in enumerate(bitfield):
         attestation_bitmask[i//8] ^= (128 >> (i % 8)) * b
     print('Aggregate bitmask:', bin(int.from_bytes(attestation_bitmask, 'big')))
     # Randomly pick indices to include for crosslinks
     shard_aggregate_votes = []
     for shard, crosslinker_share in crosslink_shards:
         print('Making crosslink in shard %d' % shard)
         indices = get_shard_attesters(crystallized_state, shard)
         print('Indices: %r' % indices)
         bitfield = [1 if random.random() < crosslinker_share else 0 for i in indices]
         bitmask = bytearray((len(bitfield)+7) // 8)
         for i, b in enumerate(bitfield):
             bitmask[i//8] ^= (128 >> (i % 8)) * b
         print('Bitmask:', bin(int.from_bytes(bitmask, '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 in range(len(indices)) if bitfield[i]]
         v = AggregateVote(shard_id=shard,
                           shard_block_hash=shard_block_hash,
                           signer_bitmask=bitmask,
                           aggregate_sig=list(bls.aggregate_sigs(sigs)))
         shard_aggregate_votes.append(v)
     print('Added %d shard aggregate votes' % len(crosslink_shards))
     # State calculations
     o = Block(parent_hash=blake(parent_attestation),
               skip_count=skips,
               randao_reveal=blake(str(random.random()).encode('utf-8')),
               attestation_bitmask=attestation_bitmask,
               attestation_aggregate_sig=list(attestation_aggregate_sig),
               shard_aggregate_votes=shard_aggregate_votes,
               main_chain_ref=b'\x00'*32,
               state_hash=b'\x00'*64)
     print('Generated preliminary block header')
     new_crystallized_state, new_active_state = \
         compute_state_transition((crystallized_state, active_state), parent, o, verify_sig=False)
     print('Calculated state transition')
     if crystallized_state == new_crystallized_state:
         o.state_hash = blake(parent.state_hash[:32] + blake(serialize(new_active_state)))
     else:
         o.state_hash = blake(blake(serialize(new_crystallized_state)) + blake(serialize(new_active_state)))
     # Main signature
     o.sign(keymap[crystallized_state.active_validators[main_signer].pubkey])
     print('Signed')
     return o, new_crystallized_state, new_active_state
Ejemplo n.º 7
0
def validate_attestation(crystallized_state: CrystallizedState,
                         active_state: ActiveState,
                         attestation: 'AttestationRecord',
                         block: 'Block',
                         config: Dict[str, Any]=DEFAULT_CONFIG) -> None:
    if not attestation.slot < block.slot_number:
        raise Exception("Attestation slot number too high")

    if not (attestation.slot > block.slot_number - config['cycle_length']):
        raise Exception(
            "Attestation slot number too low:\n"
            "\tFound: %s, Needed greater than: %s" %
            (attestation.slot, block.slot_number - config['cycle_length'])
        )

    parent_hashes = get_signed_parent_hashes(
        active_state,
        block,
        attestation,
        config
    )
    attestation_indices = get_attestation_indices(
        crystallized_state,
        attestation,
        config
    )

    #
    # validate bitfield
    #
    if not (len(attestation.attester_bitfield) == get_bitfield_length(len(attestation_indices))):
        raise Exception(
            "Attestation has incorrect bitfield length. Found: %s, Expected: %s" %
            (len(attestation.attester_bitfield), get_bitfield_length(len(attestation_indices)))
        )

    # check if end bits are zero
    last_bit = len(attestation_indices)
    if last_bit % 8 != 0:
        for i in range(8 - last_bit % 8):
            if has_voted(attestation.attester_bitfield, last_bit + i):
                raise Exception("Attestation has non-zero trailing bits")

    #
    # validate aggregate_sig
    #
    in_cycle_slot_height = attestation.slot % config['cycle_length']
    pub_keys = [
        crystallized_state.validators[index].pubkey
        for i, index in enumerate(attestation_indices)
        if has_voted(attestation.attester_bitfield, i)
    ]
    message = blake(
        in_cycle_slot_height.to_bytes(8, byteorder='big') +
        b''.join(parent_hashes) +
        attestation.shard_id.to_bytes(2, byteorder='big') +
        attestation.shard_block_hash
    )
    if not bls.verify(message, bls.aggregate_pubs(pub_keys), attestation.aggregate_sig):
        raise Exception("Attestation aggregate signature fails")
Ejemplo n.º 8
0
def test_get_genesis_block(genesis_active_state, genesis_crystallized_state):
    active_state_root = blake(serialize(genesis_active_state))
    crystallized_state_root = blake(serialize(genesis_crystallized_state))

    block = get_genesis_block(
        active_state_root=active_state_root,
        crystallized_state_root=crystallized_state_root,
    )

    assert block.parent_hash == ZERO_HASH32
    assert block.slot_number == 0
    assert block.randao_reveal == ZERO_HASH32
    assert block.num_attestations == 0
    assert block.pow_chain_ref == ZERO_HASH32
    assert block.active_state_root == active_state_root
    assert block.crystallized_state_root == crystallized_state_root
Ejemplo n.º 9
0
def genesis_validators(init_validator_keys, config):
    current_dynasty = 1
    return [
        ValidatorRecord(pubkey=pub,
                        withdrawal_shard=0,
                        withdrawal_address=blake(pub.to_bytes(32,
                                                              'big'))[-20:],
                        randao_commitment=b'\x55' * 32,
                        balance=config['deposit_size'],
                        start_dynasty=current_dynasty,
                        end_dynasty=config['default_end_dynasty'])
        for pub in init_validator_keys
    ]
Ejemplo n.º 10
0
def get_hashes_to_sign(
        active_state: 'ActiveState',
        block: 'Block',
        config: Dict[str, Any] = DEFAULT_CONFIG) -> List[Hash32]:
    cycle_length = config['cycle_length']

    hashes = get_hashes_from_active_state(
        active_state,
        block,
        from_slot=block.slot_number - cycle_length + 1,
        to_slot=block.slot_number - 1,
        config=config,
    ) + [blake(serialize(block))]

    return hashes
Ejemplo n.º 11
0
def get_shuffling(seed, validator_count, sample=None):
    assert validator_count <= MAX_VALIDATORS
    rand_max = MAX_VALIDATORS - MAX_VALIDATORS % validator_count
    o = list(range(validator_count))
    source = seed
    i = 0
    maxvalue = sample if sample is not None else validator_count
    while i < maxvalue:
        source = blake(source)
        for pos in range(0, 30, 3):
            m = int.from_bytes(source[pos:pos + 3], 'big')
            remaining = validator_count - i
            if remaining == 0:
                break
            if validator_count < rand_max:
                replacement_pos = (m % remaining) + i
                o[i], o[replacement_pos] = o[replacement_pos], o[i]
                i += 1
    return o[:maxvalue]
Ejemplo n.º 12
0
def shuffle(lst, seed, config=DEFAULT_CONFIG):
    lst_count = len(lst)
    assert lst_count <= 16777216
    o = [x for x in lst]
    source = seed
    i = 0
    while i < lst_count:
        source = blake(source)
        for pos in range(0, 30, 3):
            m = int.from_bytes(source[pos:pos + 3], 'big')
            remaining = lst_count - i
            if remaining == 0:
                break
            rand_max = 16777216 - 16777216 % remaining
            if m < rand_max:
                replacement_pos = (m % remaining) + i
                o[i], o[replacement_pos] = o[replacement_pos], o[i]
                i += 1
    return o
Ejemplo n.º 13
0
def get_shuffling(seed, validator_count, sample=None, config=DEFAULT_CONFIG):
    max_validators = config['max_validators']
    assert validator_count <= max_validators

    rand_max = max_validators - max_validators % validator_count
    o = list(range(validator_count))
    source = seed
    i = 0
    maxvalue = sample if sample is not None else validator_count
    while i < maxvalue:
        source = blake(source)
        for pos in range(0, 30, 3):
            m = int.from_bytes(source[pos:pos + 3], 'big')
            remaining = validator_count - i
            if remaining == 0:
                break
            if validator_count < rand_max:
                replacement_pos = (m % remaining) + i
                o[i], o[replacement_pos] = o[replacement_pos], o[i]
                i += 1
    return o[:maxvalue]
Ejemplo n.º 14
0
def test_initialize_new_cycle(
        genesis_crystallized_state, genesis_active_state, genesis_block,
        last_state_recalc, last_justified_slot, justified_streak,
        last_finalized_slot, fraction_voted, result_last_state_recalc,
        result_justified_streak, result_last_finalized_slot, config):
    # Fill the parent_crystallized_state with parematers
    parent_crystallized_state = genesis_crystallized_state
    parent_crystallized_state.last_state_recalc = last_state_recalc
    parent_crystallized_state.last_justified_slot = last_justified_slot
    parent_crystallized_state.justified_streak = justified_streak
    parent_crystallized_state.last_finalized_slot = last_finalized_slot

    parent_active_state = genesis_active_state

    parent_block = genesis_block
    block = copy.deepcopy(genesis_block)
    block.slot_number = 258
    block.parent_hash = blake(serialize(parent_block))

    active_state = fill_recent_block_hashes(parent_active_state, parent_block,
                                            block)

    fraction_voted *= 1.01  # add margin for rounding error
    # Fill the total_voter_deposits to simulate the different committee results
    active_state.block_vote_cache[block.parent_hash] = {
        'voter_indices':
        set(),
        'total_voter_deposits':
        int(parent_crystallized_state.total_deposits * fraction_voted)
    }

    crystallized_state, active_state = initialize_new_cycle(
        parent_crystallized_state,
        active_state,
        block,
        config=config,
    )
    assert crystallized_state.last_state_recalc == result_last_state_recalc
    assert crystallized_state.justified_streak == result_justified_streak
    assert crystallized_state.last_finalized_slot == result_last_finalized_slot
Ejemplo n.º 15
0
 def hash(self):
     return blake(serialize(self))
Ejemplo n.º 16
0
def validate_attestation(crystallized_state: CrystallizedState,
                         active_state: ActiveState,
                         attestation: 'AttestationRecord',
                         block: 'Block',
                         parent_block: 'Block',
                         config: Dict[str, Any] = DEFAULT_CONFIG) -> bool:
    #
    # validate slot number
    #
    if not attestation.slot <= parent_block.slot_number:
        raise ValidationError("Attestation slot number too high:\n"
                              "\tFound: %s Needed less than or equal to %s" %
                              (attestation.slot, parent_block.slot_number))
    if not (attestation.slot >= max(
            parent_block.slot_number - config['cycle_length'] + 1, 0)):
        raise ValidationError(
            "Attestation slot number too low:\n"
            "\tFound: %s, Needed greater than or equalt to: %s" %
            (attestation.slot,
             max(parent_block.slot_number - config['cycle_length'] + 1, 0)))

    #
    # validate justified_slot and justified_block_hash
    #
    if attestation.justified_slot > crystallized_state.last_justified_slot:
        raise ValidationError(
            "attestation.justified_slot %s should be equal to or earlier than"
            " crystallized_state.last_justified_slot %s" % (
                attestation.justified_slot,
                crystallized_state.last_justified_slot,
            ))

    justified_block = active_state.chain.get_block_by_hash(
        attestation.justified_block_hash)
    if justified_block is None:
        raise ValidationError(
            "justified_block_hash %s is not in the canonical chain" %
            attestation.justified_block_hash)
    if justified_block.slot_number != attestation.justified_slot:
        raise ValidationError(
            "justified_slot %s doesn't match justified_block_hash" %
            attestation.justified_slot)

    parent_hashes = get_signed_parent_hashes(active_state, block, attestation,
                                             config)
    attestation_indices = get_attestation_indices(crystallized_state,
                                                  attestation, config)

    #
    # validate bitfield
    #
    if not (len(attestation.attester_bitfield) == get_bitfield_length(
            len(attestation_indices))):
        raise ValidationError(
            "Attestation has incorrect bitfield length. Found: %s, Expected: %s"
            % (len(attestation.attester_bitfield),
               get_bitfield_length(len(attestation_indices))))

    # check if end bits are zero
    last_bit = len(attestation_indices)
    if last_bit % 8 != 0:
        for i in range(8 - last_bit % 8):
            if has_voted(attestation.attester_bitfield, last_bit + i):
                raise ValidationError("Attestation has non-zero trailing bits")

    #
    # validate aggregate_sig
    #
    pub_keys = [
        crystallized_state.validators[validator_index].pubkey
        for committee_index, validator_index in enumerate(attestation_indices)
        if has_voted(attestation.attester_bitfield, committee_index)
    ]
    message = blake(
        attestation.slot.to_bytes(8, byteorder='big') +
        b''.join(parent_hashes) +
        attestation.shard_id.to_bytes(2, byteorder='big') +
        attestation.shard_block_hash +
        attestation.justified_slot.to_bytes(8, 'big'))
    if not bls.verify(message, bls.aggregate_pubs(pub_keys),
                      attestation.aggregate_sig):
        raise ValidationError("Attestation aggregate signature fails")

    return True
Ejemplo n.º 17
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
Ejemplo n.º 18
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
        bitfield = [
            1 if random.random() < attester_share else 0 for i in indices
        ]
        # Attestations
        sigs = [
            bls.sign(
                parent_attestation, keymap[
                    crystallized_state.active_validators[indices[i]].pubkey])
            for i in range(len(indices)) if bitfield[i]
        ]
        attestation_aggregate_sig = bls.aggregate_sigs(sigs)
        print('Aggregated sig')

        attestation_bitfield = bytearray((len(bitfield) - 1) // 8 + 1)
        for i, b in enumerate(bitfield):
            attestation_bitfield[i // 8] ^= (128 >> (i % 8)) * b
        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)
            bitfield = [
                1 if random.random() < crosslinker_share else 0
                for i in indices
            ]
            bitmask = bytearray((len(bitfield) + 7) // 8)
            for i, b in enumerate(bitfield):
                bitmask[i // 8] ^= (128 >> (i % 8)) * b
            print('Bitmask:', bin(int.from_bytes(bitmask, '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 in range(len(indices))
                if bitfield[i]
            ]
            v = AggregateVote(shard_id=shard,
                              shard_block_hash=shard_block_hash,
                              signer_bitmask=bitmask,
                              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
Ejemplo n.º 19
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
Ejemplo n.º 20
0
def validate_attestation(crystallized_state: CrystallizedState,
                         active_state: ActiveState,
                         attestation: 'AttestationRecord',
                         block: 'Block',
                         parent_block: 'Block',
                         config: Dict[str, Any] = DEFAULT_CONFIG) -> None:
    # Verify attestation.slot_number
    if not attestation.slot <= parent_block.slot_number:
        raise Exception("Attestation slot number too high:\n"
                        "\tFound: %s Needed less than or equal to %s" %
                        (attestation.slot, parent_block.slot_number))
    if not (attestation.slot >= max(
            parent_block.slot_number - config['cycle_length'] + 1, 0)):
        raise Exception(
            "Attestation slot number too low:\n"
            "\tFound: %s, Needed greater than or equalt to: %s" %
            (attestation.slot,
             max(parent_block.slot_number - config['cycle_length'] + 1, 0)))

    # TODO: Verify that the justified_slot and justified_block_hash given are in
    # the chain and are equal to or earlier than the last_justified_slot
    # in the crystallized state.

    parent_hashes = get_signed_parent_hashes(active_state, block, attestation,
                                             config)
    attestation_indices = get_attestation_indices(crystallized_state,
                                                  attestation, config)

    #
    # validate bitfield
    #
    if not (len(attestation.attester_bitfield) == get_bitfield_length(
            len(attestation_indices))):
        raise Exception(
            "Attestation has incorrect bitfield length. Found: %s, Expected: %s"
            % (len(attestation.attester_bitfield),
               get_bitfield_length(len(attestation_indices))))

    # check if end bits are zero
    last_bit = len(attestation_indices)
    if last_bit % 8 != 0:
        for i in range(8 - last_bit % 8):
            if has_voted(attestation.attester_bitfield, last_bit + i):
                raise Exception("Attestation has non-zero trailing bits")

    #
    # validate aggregate_sig
    #
    pub_keys = [
        crystallized_state.validators[index].pubkey
        for i, index in enumerate(attestation_indices)
        if has_voted(attestation.attester_bitfield, i)
    ]
    message = blake(
        attestation.slot.to_bytes(8, byteorder='big') +
        b''.join(parent_hashes) +
        attestation.shard_id.to_bytes(2, byteorder='big') +
        attestation.shard_block_hash +
        attestation.justified_slot.to_bytes(8, 'big'))
    if not bls.verify(message, bls.aggregate_pubs(pub_keys),
                      attestation.aggregate_sig):
        raise Exception("Attestation aggregate signature fails")
Ejemplo n.º 21
0
def state_hash(crystallized_state, active_state):
    return blake(serialize(crystallized_state)) + blake(
        serialize(active_state))
Ejemplo n.º 22
0
def privkeys():
    return [int.from_bytes(blake(str(i).encode('utf-8'))[:4], 'big') for i in range(1000)]