def fill_recent_block_hashes(active_state, parent_block, block):
    return ActiveState(
        pending_attestations=deepcopy(active_state.pending_attestations),
        recent_block_hashes=get_new_recent_block_hashes(
            active_state.recent_block_hashes, parent_block.slot_number,
            block.slot_number, block.parent_hash),
        block_vote_cache=deepcopy(active_state.block_vote_cache))
def get_updated_block_vote_cache(crystallized_state, active_state, attestation,
                                 block, block_vote_cache, config):
    new_block_vote_cache = deepcopy(block_vote_cache)

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

    for parent_hash in parent_hashes:
        if parent_hash in attestation.oblique_parent_hashes:
            continue
        if parent_hash not in new_block_vote_cache:
            new_block_vote_cache[parent_hash] = {
                'voter_indices': set(),
                'total_voter_deposits': 0
            }
        for i, index in enumerate(attestation_indices):
            if (has_voted(attestation.attester_bitfield, i) and index
                    not in new_block_vote_cache[parent_hash]['voter_indices']):
                new_block_vote_cache[parent_hash]['voter_indices'].add(index)
                new_block_vote_cache[parent_hash][
                    'total_voter_deposits'] += crystallized_state.validators[
                        index].balance

    return new_block_vote_cache
def process_updated_crosslinks(crystallized_state,
                               active_state,
                               config=DEFAULT_CONFIG):
    total_attestation_balance = {}
    crosslinks = deepcopy(crystallized_state.crosslink_records)

    for attestation in active_state.pending_attestations:
        shard_tuple = (attestation.shard_id, attestation.shard_block_hash)
        if shard_tuple not in total_attestation_balance:
            total_attestation_balance[shard_tuple] = 0

        attestation_indices = get_attestation_indices(crystallized_state,
                                                      attestation, config)
        # find total committee size by balance
        total_committee_balance = sum([
            crystallized_state.validators[index].balance
            for index in attestation_indices
        ])
        # find votes cast in attestation by balance
        total_attestation_balance[shard_tuple] += sum([
            crystallized_state.validators[index].balance
            for in_cycle_slot_height, index in enumerate(attestation_indices)
            if has_voted(attestation.attester_bitfield, in_cycle_slot_height)
        ])

        # if 2/3 of committee voted on crosslink and do no yet have crosslink
        # for this shard, for this dynasty, add updated crosslink
        if (3 * total_attestation_balance[shard_tuple] >=
                2 * total_committee_balance
                and crystallized_state.current_dynasty >
                crosslinks[attestation.shard_id].dynasty):
            crosslinks[attestation.shard_id] = CrosslinkRecord(
                dynasty=crystallized_state.current_dynasty,
                hash=attestation.shard_block_hash)
    return crosslinks
Ejemplo n.º 4
0
def process_block(crystallized_state: CrystallizedState,
                  active_state: ActiveState,
                  block: 'Block',
                  config: dict = DEFAULT_CONFIG) -> ActiveState:
    new_block_vote_cache = deepcopy(active_state.block_vote_cache)
    for attestation in block.attestations:
        validate_attestation(crystallized_state,
                             active_state,
                             attestation,
                             block,
                             config)
        new_block_vote_cache = get_updated_block_vote_cache(
            crystallized_state,
            active_state,
            attestation,
            block,
            new_block_vote_cache,
            config
        )

    new_attestations = active_state.pending_attestations + block.attestations

    new_active_state = ActiveState(
        pending_attestations=new_attestations,
        recent_block_hashes=active_state.recent_block_hashes[:],
        block_vote_cache=new_block_vote_cache
    )
    return new_active_state
def initialize_new_cycle(crystallized_state,
                         active_state,
                         block,
                         config=DEFAULT_CONFIG):
    cycle_length = config['cycle_length']
    last_state_recalc = crystallized_state.last_state_recalc
    last_justified_slot = crystallized_state.last_justified_slot
    last_finalized_slot = crystallized_state.last_finalized_slot
    justified_streak = crystallized_state.justified_streak
    # walk through slots last_state_recalc - CYCLE_LENGTH ... last_state_recalc - 1
    # and check for justification, streaks, and finality
    for i in range(cycle_length):
        slot = i + (last_state_recalc - cycle_length)

        block_hash = active_state.recent_block_hashes[i]
        if block_hash in active_state.block_vote_cache:
            vote_balance = active_state.block_vote_cache[block_hash][
                'total_voter_deposits']
        else:
            vote_balance = 0

        if 3 * vote_balance >= 2 * crystallized_state.total_deposits:
            last_justified_slot = max(last_justified_slot, slot)
            justified_streak += 1
        else:
            justified_streak = 0

        if justified_streak >= cycle_length + 1:
            last_finalized_slot = max(last_finalized_slot,
                                      slot - cycle_length - 1)

    crosslink_records = process_updated_crosslinks(crystallized_state,
                                                   active_state, config)

    # remove attestations older than last_state_recalc
    pending_attestations = [
        a for a in active_state.pending_attestations
        if a.slot >= last_state_recalc
    ]

    dynasty = crystallized_state.current_dynasty  # STUB
    dynasty_seed = crystallized_state.dynasty_seed  # STUB
    dynasty_seed_last_reset = crystallized_state.dynasty_seed_last_reset  # STUB
    crosslinking_start_shard = 0  # stub. Needs to see where this epoch left off
    validators = deepcopy(crystallized_state.validators)  # STUB
    indices_for_heights = (
        crystallized_state.indices_for_heights[cycle_length:] +
        # this is a stub and will be addressed by shuffling at dynasty change
        crystallized_state.indices_for_heights[cycle_length:])
    active_validator_indices = get_active_validator_indices(
        dynasty, validators)

    new_crystallized_state = CrystallizedState(
        validators=validators,
        last_state_recalc=last_state_recalc + cycle_length,
        indices_for_heights=indices_for_heights,
        last_justified_slot=last_justified_slot,
        justified_streak=justified_streak,
        last_finalized_slot=last_finalized_slot,
        current_dynasty=crystallized_state.current_dynasty,
        crosslinking_start_shard=crosslinking_start_shard,
        crosslink_records=crosslink_records,
        total_deposits=sum(
            map(lambda i: validators[i].balance, active_validator_indices)),
        dynasty_seed=dynasty_seed,
        dynasty_seed_last_reset=dynasty_seed_last_reset)

    new_active_state = ActiveState(
        pending_attestations=pending_attestations,
        recent_block_hashes=active_state.recent_block_hashes[:],
        # Should probably clean up block_vote_cache but old records won't break cache
        # so okay for now
        block_vote_cache=deepcopy(active_state.block_vote_cache))

    return new_crystallized_state, new_active_state
Ejemplo n.º 6
0
def _initialize_new_epoch(crystallized_state, active_state):
    print('Processing epoch transition')
    # Process rewards from FFG/crosslink votes
    new_validator_records = deepcopy(crystallized_state.active_validators)
    # Who voted in the last epoch
    ffg_voter_bitfield = bytearray(active_state.ffg_voter_bitfield)
    # Balance changes, and total vote counts for FFG
    deltas1, total_vote_count, total_vote_deposits, justify, finalize = \
        process_ffg_deposits(crystallized_state, ffg_voter_bitfield)
    # Balance changes, and total vote counts for crosslinks
    deltas2, new_crosslink_records = process_crosslinks(
        crystallized_state, active_state.partial_crosslinks)
    # Process other balance deltas
    deltas3 = process_balance_deltas(crystallized_state,
                                     active_state.balance_deltas)
    for i, v in enumerate(new_validator_records):
        v.balance += deltas1[i] + deltas2[i] + deltas3[i]
    total_deposits = crystallized_state.total_deposits + sum(deltas1 +
                                                             deltas2 + deltas3)
    print('New total deposits: %d' % total_deposits)

    if justify:
        last_justified_epoch = crystallized_state.current_epoch
    else:
        last_justified_epoch = crystallized_state.last_justified_epoch

    if finalize:
        last_finalized_epoch = crystallized_state.current_epoch - 1
        dynasty = crystallized_state.dynasty + 1
        new_queued_validators, new_active_validators, new_exited_validators = \
            get_incremented_validator_sets(crystallized_state, new_validator_records)
    else:
        last_finalized_epoch = crystallized_state.last_finalized_epoch
        dynasty = crystallized_state.dynasty
        new_queued_validators = crystallized_state.queued_validators
        new_active_validators = crystallized_state.active_validators
        new_exited_validators = crystallized_state.exited_validators

    crystallized_state = CrystallizedState(
        queued_validators=new_queued_validators,
        active_validators=new_active_validators,
        exited_validators=new_exited_validators,
        current_shuffling=get_shuffling(active_state.randao,
                                        len(new_active_validators)),
        last_justified_epoch=last_justified_epoch,
        last_finalized_epoch=last_finalized_epoch,
        dynasty=dynasty,
        next_shard=0,
        current_epoch=crystallized_state.current_epoch + 1,
        crosslink_records=new_crosslink_records,
        total_deposits=total_deposits)
    # Reset the active state
    active_state = ActiveState(
        height=active_state.height,
        randao=active_state.randao,
        ffg_voter_bitfield=bytearray(
            (len(crystallized_state.active_validators) + 7) // 8),
        balance_deltas=[],
        partial_crosslinks=[],
        total_skip_count=active_state.total_skip_count)

    return crystallized_state, active_state
Ejemplo n.º 7
0
def _initialize_new_epoch(crystallized_state,
                          active_state,
                          config=DEFAULT_CONFIG):
    print('Processing epoch transition')
    # Process rewards from FFG/crosslink votes
    new_validator_records = deepcopy(crystallized_state.active_validators)
    # Who voted in the last epoch
    ffg_voter_bitfield = active_state.ffg_voter_bitfield
    # Balance changes, and total vote counts for FFG
    deltas_casper, total_vote_count, total_vote_deposits, justify, finalize = \
        process_ffg_deposits(crystallized_state, ffg_voter_bitfield)
    # Balance changes, and total vote counts for crosslinks
    deltas_crosslinks, new_crosslink_records = process_crosslinks(
        crystallized_state,
        active_state.partial_crosslinks,
        config=config,
    )
    # process recent attesters balance deltas
    deltas_recent_attesters = process_recent_attesters(
        crystallized_state,
        active_state.recent_attesters,
        config=config,
    )
    # process recent proposers balance deltas
    deltas_recent_proposers = process_recent_proposers(
        crystallized_state, active_state.recent_proposers)

    for i, validator in enumerate(new_validator_records):
        validator.balance += (deltas_casper[i] + deltas_crosslinks[i] +
                              deltas_recent_attesters[i] +
                              deltas_recent_proposers[i])
    total_deposits = crystallized_state.total_deposits + sum(
        deltas_casper + deltas_crosslinks + deltas_recent_attesters +
        deltas_recent_proposers)
    print('New total deposits: %d' % total_deposits)

    if justify:
        last_justified_epoch = crystallized_state.current_epoch
    else:
        last_justified_epoch = crystallized_state.last_justified_epoch

    if finalize:
        last_finalized_epoch = crystallized_state.current_epoch - 1
        dynasty = crystallized_state.dynasty + 1
        new_queued_validators, new_active_validators, new_exited_validators = \
            get_incremented_validator_sets(crystallized_state, new_validator_records)
    else:
        last_finalized_epoch = crystallized_state.last_finalized_epoch
        dynasty = crystallized_state.dynasty
        new_queued_validators = crystallized_state.queued_validators
        new_active_validators = crystallized_state.active_validators
        new_exited_validators = crystallized_state.exited_validators

    crystallized_state = CrystallizedState(
        queued_validators=new_queued_validators,
        active_validators=new_active_validators,
        exited_validators=new_exited_validators,
        current_shuffling=get_shuffling(active_state.randao,
                                        len(new_active_validators),
                                        config=config),
        last_justified_epoch=last_justified_epoch,
        last_finalized_epoch=last_finalized_epoch,
        dynasty=dynasty,
        next_shard=0,
        current_epoch=crystallized_state.current_epoch + 1,
        crosslink_records=new_crosslink_records,
        total_deposits=total_deposits)
    # Reset the active state
    active_state = ActiveState(height=active_state.height,
                               randao=active_state.randao,
                               ffg_voter_bitfield=get_empty_bitfield(
                                   crystallized_state.num_active_validators),
                               balance_deltas=[],
                               partial_crosslinks=[],
                               total_skip_count=active_state.total_skip_count,
                               recent_proposers=[])

    return crystallized_state, active_state