Ejemplo n.º 1
0
def _update_shuffling_epoch(state: BeaconState,
                            slots_per_epoch: int) -> BeaconState:
    """
    Updates the ``current_shuffling_epoch`` to the ``state``'s next epoch.
    """
    return state.copy(
        current_shuffling_epoch=state.next_epoch(slots_per_epoch), )
Ejemplo n.º 2
0
def process_final_updates(state: BeaconState,
                          config: BeaconConfig) -> BeaconState:
    current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)

    state = _update_latest_active_index_roots(state, CommitteeConfig(config))

    state = state.copy(
        latest_slashed_balances=update_tuple_item(
            state.latest_slashed_balances,
            next_epoch % config.LATEST_SLASHED_EXIT_LENGTH,
            state.latest_slashed_balances[current_epoch %
                                          config.LATEST_SLASHED_EXIT_LENGTH],
        ),
        latest_randao_mixes=update_tuple_item(
            state.latest_randao_mixes,
            next_epoch % config.LATEST_SLASHED_EXIT_LENGTH,
            get_randao_mix(
                state=state,
                epoch=current_epoch,
                slots_per_epoch=config.SLOTS_PER_EPOCH,
                latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH,
            ),
        ),
    )

    latest_attestations = tuple(
        filter(
            lambda attestation:
            (slot_to_epoch(attestation.data.slot, config.SLOTS_PER_EPOCH) >=
             current_epoch), state.latest_attestations))
    state = state.copy(latest_attestations=latest_attestations, )

    return state
Ejemplo n.º 3
0
def _determine_next_eth1_votes(state: BeaconState,
                               config: Eth2Config) -> HashableList[Eth1Data]:
    if (state.next_epoch(config.SLOTS_PER_EPOCH) %
            config.EPOCHS_PER_ETH1_VOTING_PERIOD == 0):
        return HashableList.from_iterable((), state.eth1_data_votes.sedes)
    else:
        return state.eth1_data_votes
Ejemplo n.º 4
0
def get_committee_assignment(
    state: BeaconState,
    config: Eth2Config,
    epoch: Epoch,
    validator_index: ValidatorIndex,
) -> CommitteeAssignment:
    """
    Return the ``CommitteeAssignment`` in the ``epoch`` for ``validator_index``.
    ``CommitteeAssignment.committee`` is the tuple array of validators in the committee
    ``CommitteeAssignment.committee_index`` is the index to which the committee is assigned
    ``CommitteeAssignment.slot`` is the slot at which the committee is assigned
    """
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)
    if epoch > next_epoch:
        raise ValidationError(
            f"Epoch for committee assignment ({epoch}) must not be after next epoch {next_epoch}."
        )

    for committee, committee_index, slot in iterate_committees_at_epoch(
        state, epoch, CommitteeConfig(config)
    ):
        if validator_index in committee:
            return CommitteeAssignment(
                committee, CommitteeIndex(committee_index), Slot(slot)
            )

    raise NoCommitteeAssignment
Ejemplo n.º 5
0
def process_final_updates(state: BeaconState,
                          config: BeaconConfig) -> BeaconState:
    current_epoch = state.current_epoch(config.EPOCH_LENGTH)
    next_epoch = state.next_epoch(config.EPOCH_LENGTH)

    state = state.copy(
        latest_penalized_balances=update_tuple_item(
            state.latest_penalized_balances,
            next_epoch % config.LATEST_PENALIZED_EXIT_LENGTH,
            state.latest_penalized_balances[
                current_epoch % config.LATEST_PENALIZED_EXIT_LENGTH],
        ),
        latest_randao_mixes=update_tuple_item(
            state.latest_randao_mixes,
            next_epoch % config.LATEST_PENALIZED_EXIT_LENGTH,
            get_randao_mix(
                state=state,
                epoch=current_epoch,
                epoch_length=config.EPOCH_LENGTH,
                latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH,
            ),
        ),
    )

    latest_attestations = tuple(
        filter(
            lambda attestation: (slot_to_epoch(attestation.data.slot, config.
                                               EPOCH_LENGTH) >= current_epoch),
            state.latest_attestations))
    state = state.copy(latest_attestations=latest_attestations, )

    return state
Ejemplo n.º 6
0
def _update_latest_index_roots(state: BeaconState,
                               committee_config: CommitteeConfig) -> BeaconState:
    """
    Return the BeaconState with updated `latest_index_roots`.
    """
    next_epoch = state.next_epoch(committee_config.EPOCH_LENGTH)

    # TODO: chanege to hash_tree_root
    active_validator_indices = get_active_validator_indices(
        state.validator_registry,
        EpochNumber(next_epoch + committee_config.ENTRY_EXIT_DELAY),
    )
    index_root = hash_eth2(
        b''.join(
            [
                index.to_bytes(32, 'big')
                for index in active_validator_indices
            ]
        )
    )

    latest_index_roots = update_tuple_item(
        state.latest_index_roots,
        (
            (next_epoch + committee_config.ENTRY_EXIT_DELAY) %
            committee_config.LATEST_INDEX_ROOTS_LENGTH
        ),
        index_root,
    )

    return state.copy(
        latest_index_roots=latest_index_roots,
    )
Ejemplo n.º 7
0
def process_final_updates(state: BeaconState,
                          config: Eth2Config) -> BeaconState:
    current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)

    state = _update_latest_active_index_roots(state, CommitteeConfig(config))

    state = state.copy(
        latest_slashed_balances=update_tuple_item(
            state.latest_slashed_balances,
            next_epoch % config.LATEST_SLASHED_EXIT_LENGTH,
            state.latest_slashed_balances[current_epoch %
                                          config.LATEST_SLASHED_EXIT_LENGTH],
        ),
        latest_randao_mixes=update_tuple_item(
            state.latest_randao_mixes,
            next_epoch % config.LATEST_RANDAO_MIXES_LENGTH,
            get_randao_mix(
                state=state,
                epoch=current_epoch,
                slots_per_epoch=config.SLOTS_PER_EPOCH,
                latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH,
            ),
        ),
    )

    state = _update_historical_roots(state, next_epoch, config)

    # Rotate current/previous epoch attestations
    state = state.copy(
        previous_epoch_attestations=state.current_epoch_attestations,
        current_epoch_attestations=(),
    )

    return state
Ejemplo n.º 8
0
def process_eth1_data_votes(state: BeaconState,
                            config: Eth2Config) -> BeaconState:
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)
    should_process = next_epoch % config.EPOCHS_PER_ETH1_VOTING_PERIOD == 0
    if should_process:
        return _update_eth1_vote_if_exists(state, config)
    return state
Ejemplo n.º 9
0
def _compute_next_slashings(state: BeaconState,
                            config: Eth2Config) -> Tuple[Gwei, ...]:
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)
    return update_tuple_item(
        state.slashings,
        next_epoch % config.EPOCHS_PER_SLASHINGS_VECTOR,
        Gwei(0),
    )
Ejemplo n.º 10
0
def _compute_next_randao_mixes(state: BeaconState,
                               config: Eth2Config) -> Tuple[Hash32, ...]:
    current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)
    return state.randao_mixes.set(
        next_epoch % config.EPOCHS_PER_HISTORICAL_VECTOR,
        get_randao_mix(state, current_epoch,
                       config.EPOCHS_PER_HISTORICAL_VECTOR),
    )
Ejemplo n.º 11
0
def _compute_next_historical_roots(state: BeaconState, config: Eth2Config) -> Tuple[Hash32, ...]:
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)
    new_historical_roots = state.historical_roots
    if next_epoch % (config.SLOTS_PER_HISTORICAL_ROOT // config.SLOTS_PER_EPOCH) == 0:
        historical_batch = HistoricalBatch(
            block_roots=state.block_roots,
            state_roots=state.state_roots,
        )
        new_historical_roots = state.historical_roots + (historical_batch.root,)
    return new_historical_roots
Ejemplo n.º 12
0
def _compute_next_slashed_balances(state: BeaconState, config: Eth2Config) -> Tuple[Gwei, ...]:
    current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)
    return update_tuple_item(
        state.slashed_balances,
        next_epoch % config.EPOCHS_PER_SLASHED_BALANCES_VECTOR,
        state.slashed_balances[
            current_epoch % config.EPOCHS_PER_SLASHED_BALANCES_VECTOR
        ],
    )
Ejemplo n.º 13
0
def _compute_next_compact_committees_roots(
    state: BeaconState, config: Eth2Config
) -> Tuple[Hash32, ...]:
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)
    committee_root_position = next_epoch % config.EPOCHS_PER_HISTORICAL_VECTOR
    return update_tuple_item(
        state.compact_committees_roots,
        committee_root_position,
        get_compact_committees_root(state, next_epoch, CommitteeConfig(config)),
    )
Ejemplo n.º 14
0
def _compute_next_active_index_roots(state: BeaconState,
                                     config: Eth2Config) -> Tuple[Hash32, ...]:
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)
    index_root_position = (next_epoch + config.ACTIVATION_EXIT_DELAY
                           ) % config.EPOCHS_PER_HISTORICAL_VECTOR
    validator_indices_for_new_active_index_root = get_active_validator_indices(
        state.validators, Epoch(next_epoch + config.ACTIVATION_EXIT_DELAY))
    new_active_index_root = ssz.get_hash_tree_root(
        validator_indices_for_new_active_index_root,
        ssz.sedes.List(ssz.uint64, config.VALIDATOR_REGISTRY_LIMIT),
    )
    return update_tuple_item(state.active_index_roots, index_root_position,
                             new_active_index_root)
Ejemplo n.º 15
0
def get_committee_assignment(
    state: BeaconState,
    config: Eth2Config,
    epoch: Epoch,
    validator_index: ValidatorIndex,
) -> CommitteeAssignment:
    """
    Return the ``CommitteeAssignment`` in the ``epoch`` for ``validator_index``.
    ``CommitteeAssignment.committee`` is the tuple array of validators in the committee
    ``CommitteeAssignment.shard`` is the shard to which the committee is assigned
    ``CommitteeAssignment.slot`` is the slot at which the committee is assigned
    ``CommitteeAssignment.is_proposer`` is a bool signalling if the validator is expected to
        propose a beacon block at the assigned slot.
    """
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)
    if epoch > next_epoch:
        raise ValidationError(
            f"Epoch for committee assignment ({epoch}) must not be after next epoch {next_epoch}."
        )

    active_validators = get_active_validator_indices(state.validators, epoch)
    committees_per_slot = (
        get_committee_count(
            len(active_validators),
            config.SHARD_COUNT,
            config.SLOTS_PER_EPOCH,
            config.TARGET_COMMITTEE_SIZE,
        )
        // config.SLOTS_PER_EPOCH
    )
    epoch_start_slot = compute_start_slot_of_epoch(epoch, config.SLOTS_PER_EPOCH)
    epoch_start_shard = get_start_shard(state, epoch, CommitteeConfig(config))

    for slot in range(epoch_start_slot, epoch_start_slot + config.SLOTS_PER_EPOCH):
        offset = committees_per_slot * (slot % config.SLOTS_PER_EPOCH)
        slot_start_shard = (epoch_start_shard + offset) % config.SHARD_COUNT
        for i in range(committees_per_slot):
            shard = Shard((slot_start_shard + i) % config.SHARD_COUNT)
            committee = get_crosslink_committee(
                state, epoch, shard, CommitteeConfig(config)
            )
            if validator_index in committee:
                is_proposer = validator_index == get_beacon_proposer_index(
                    state.copy(slot=slot), CommitteeConfig(config)
                )
                return CommitteeAssignment(
                    committee, Shard(shard), Slot(slot), is_proposer
                )

    raise NoCommitteeAssignment
Ejemplo n.º 16
0
def get_start_shard(state: BeaconState, epoch: Epoch,
                    config: CommitteeConfig) -> Shard:
    current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    next_epoch = state.next_epoch(config.SLOTS_PER_EPOCH)
    if epoch > next_epoch:
        raise ValidationError("Asking for start shard for an epoch after next")

    check_epoch = int(next_epoch)
    shard = (state.start_shard + get_shard_delta(state, current_epoch,
                                                 config)) % config.SHARD_COUNT
    while check_epoch > epoch:
        check_epoch -= 1
        shard = (shard + config.SHARD_COUNT - get_shard_delta(
            state, Epoch(check_epoch), config)) % config.SHARD_COUNT
    return shard
Ejemplo n.º 17
0
def _update_latest_index_roots(state: BeaconState,
                               config: BeaconConfig) -> BeaconState:
    """
    Return the BeaconState with updated `latest_index_roots`.
    """
    next_epoch = state.next_epoch(config.EPOCH_LENGTH)

    # TODO: chanege to hash_tree_root
    active_validator_indices = get_active_validator_indices(
        state.validator_registry,
        # TODO: change to `per-epoch` version
        state.slot,
    )
    index_root = hash_eth2(b''.join(
        [index.to_bytes(32, 'big') for index in active_validator_indices]))

    latest_index_roots = update_tuple_item(
        state.latest_index_roots,
        next_epoch % config.LATEST_INDEX_ROOTS_LENGTH,
        index_root,
    )

    return state.copy(latest_index_roots=latest_index_roots, )
Ejemplo n.º 18
0
def _update_latest_active_index_roots(
        state: BeaconState, committee_config: CommitteeConfig) -> BeaconState:
    """
    Return the BeaconState with updated `latest_active_index_roots`.
    """
    next_epoch = state.next_epoch(committee_config.SLOTS_PER_EPOCH)

    active_validator_indices = get_active_validator_indices(
        state.validator_registry,
        Epoch(next_epoch + committee_config.ACTIVATION_EXIT_DELAY),
    )
    index_root = ssz.hash_tree_root(
        active_validator_indices,
        ssz.sedes.List(ssz.uint64),
    )

    latest_active_index_roots = update_tuple_item(
        state.latest_active_index_roots,
        ((next_epoch + committee_config.ACTIVATION_EXIT_DELAY) %
         committee_config.LATEST_ACTIVE_INDEX_ROOTS_LENGTH),
        index_root,
    )

    return state.copy(latest_active_index_roots=latest_active_index_roots, )
Ejemplo n.º 19
0
def process_crosslinks(state: BeaconState, config: BeaconConfig) -> BeaconState:
    """
    Implement 'per-epoch-processing.crosslinks' portion of Phase 0 spec:
    https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#crosslinks

    For each shard from the past two epochs, find the shard block
    root that has been attested to by the most stake.
    If enough(>= 2/3 total stake) attesting stake, update the crosslink record of that shard.
    Return resulting ``state``
    """
    latest_crosslinks = state.latest_crosslinks
    previous_epoch_attestations = get_previous_epoch_attestations(
        state,
        config.EPOCH_LENGTH,
        config.GENESIS_EPOCH,
    )
    current_epoch_attestations = get_current_epoch_attestations(state, config.EPOCH_LENGTH)
    prev_epoch_start_slot = get_epoch_start_slot(
        state.previous_epoch(config.EPOCH_LENGTH, config.GENESIS_EPOCH),
        config.EPOCH_LENGTH,
    )
    next_epoch_start_slot = get_epoch_start_slot(
        state.next_epoch(config.EPOCH_LENGTH),
        config.EPOCH_LENGTH,
    )
    for slot in range(prev_epoch_start_slot, next_epoch_start_slot):
        crosslink_committees_at_slot = get_crosslink_committees_at_slot(
            state,
            slot,
            CommitteeConfig(config),
        )
        for crosslink_committee, shard in crosslink_committees_at_slot:
            try:
                winning_root, total_attesting_balance = get_winning_root(
                    state=state,
                    shard=shard,
                    # Use `_filter_attestations_by_shard` to filter out attestations
                    # not attesting to this shard so we don't need to going over
                    # irrelevent attestations over and over again.
                    attestations=_filter_attestations_by_shard(
                        previous_epoch_attestations + current_epoch_attestations,
                        shard,
                    ),
                    max_deposit_amount=config.MAX_DEPOSIT_AMOUNT,
                    committee_config=CommitteeConfig(config),
                )
            except NoWinningRootError:
                # No winning shard block root found for this shard.
                pass
            else:
                total_balance = sum(
                    get_effective_balance(state.validator_balances, i, config.MAX_DEPOSIT_AMOUNT)
                    for i in crosslink_committee
                )
                if 3 * total_attesting_balance >= 2 * total_balance:
                    latest_crosslinks = update_tuple_item(
                        latest_crosslinks,
                        shard,
                        CrosslinkRecord(
                            epoch=state.current_epoch(config.EPOCH_LENGTH),
                            shard_block_root=winning_root,
                        ),
                    )
                else:
                    # Don't update the crosslink of this shard
                    pass
    state = state.copy(
        latest_crosslinks=latest_crosslinks,
    )
    return state
Ejemplo n.º 20
0
def process_crosslinks(state: BeaconState, config: Eth2Config) -> BeaconState:
    """
    Implement 'per-epoch-processing.crosslinks' portion of Phase 0 spec:
    https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#crosslinks

    For each shard from the past two epochs, find the shard block
    root that has been attested to by the most stake.
    If enough(>= 2/3 total stake) attesting stake, update the crosslink record of that shard.
    Return resulting ``state``
    """
    latest_crosslinks = state.latest_crosslinks
    effective_balances = {
        ValidatorIndex(index): get_effective_balance(
            state.validator_balances,
            ValidatorIndex(index),
            config.MAX_DEPOSIT_AMOUNT,
        )
        for index in range(len(state.validator_registry))
    }
    previous_epoch_start_slot = get_epoch_start_slot(
        state.previous_epoch(config.SLOTS_PER_EPOCH),
        config.SLOTS_PER_EPOCH,
    )
    next_epoch_start_slot = get_epoch_start_slot(
        state.next_epoch(config.SLOTS_PER_EPOCH),
        config.SLOTS_PER_EPOCH,
    )
    for slot in range(previous_epoch_start_slot, next_epoch_start_slot):
        crosslink_committees_at_slot = get_crosslink_committees_at_slot(
            state,
            slot,
            CommitteeConfig(config),
        )
        for crosslink_committee, shard in crosslink_committees_at_slot:
            winning_root, attesting_validator_indices = get_winning_root_and_participants(
                state=state,
                shard=shard,
                effective_balances=effective_balances,
                committee_config=CommitteeConfig(config),
            )
            if len(attesting_validator_indices) > 0:
                total_attesting_balance = get_total_balance(
                    state.validator_balances,
                    attesting_validator_indices,
                    config.MAX_DEPOSIT_AMOUNT,
                )
                total_balance = get_total_balance(
                    state.validator_balances,
                    crosslink_committee,
                    config.MAX_DEPOSIT_AMOUNT,
                )
                if 3 * total_attesting_balance >= 2 * total_balance:
                    latest_crosslinks = update_tuple_item(
                        latest_crosslinks,
                        shard,
                        CrosslinkRecord(
                            epoch=slot_to_epoch(Slot(slot),
                                                config.SLOTS_PER_EPOCH),
                            crosslink_data_root=winning_root,
                        ),
                    )
    state = state.copy(latest_crosslinks=latest_crosslinks, )
    return state
Ejemplo n.º 21
0
def _process_rewards_and_penalties_for_finality(
    state: BeaconState, config: Eth2Config,
    previous_epoch_active_validator_indices: Sequence[ValidatorIndex],
    previous_total_balance: Gwei,
    previous_epoch_attestations: Sequence[Attestation],
    previous_epoch_attester_indices: Sequence[ValidatorIndex],
    inclusion_infos: Dict[ValidatorIndex, InclusionInfo],
    effective_balances: Dict[ValidatorIndex,
                             Gwei], base_rewards: Dict[ValidatorIndex, Gwei]
) -> Tuple[Dict[ValidatorIndex, Gwei], Dict[ValidatorIndex,
                                            Gwei]]:  # noqa: E501
    previous_epoch_boundary_attestations = get_previous_epoch_boundary_attestations(
        state,
        config.SLOTS_PER_EPOCH,
        config.SLOTS_PER_HISTORICAL_ROOT,
    )
    previous_epoch_boundary_attester_indices = get_attester_indices_from_attestations(
        state=state,
        attestations=previous_epoch_boundary_attestations,
        committee_config=CommitteeConfig(config),
    )

    previous_epoch_head_attestations = get_previous_epoch_matching_head_attestations(
        state,
        config.SLOTS_PER_EPOCH,
        config.SLOTS_PER_HISTORICAL_ROOT,
    )
    previous_epoch_head_attester_indices = get_attester_indices_from_attestations(
        state=state,
        attestations=previous_epoch_head_attestations,
        committee_config=CommitteeConfig(config),
    )

    epochs_since_finality = state.next_epoch(
        config.SLOTS_PER_EPOCH) - state.finalized_epoch
    if epochs_since_finality <= 4:
        return _compute_normal_justification_and_finalization_deltas(
            state,
            config,
            previous_epoch_active_validator_indices,
            previous_total_balance,
            previous_epoch_attester_indices,
            previous_epoch_boundary_attester_indices,
            previous_epoch_head_attester_indices,
            inclusion_infos,
            effective_balances,
            base_rewards,
        )

    # epochs_since_finality > 4
    else:
        return _compute_inactivity_leak_deltas(
            state,
            config,
            previous_epoch_active_validator_indices,
            previous_epoch_attester_indices,
            previous_epoch_boundary_attester_indices,
            previous_epoch_head_attester_indices,
            inclusion_infos,
            effective_balances,
            base_rewards,
            epochs_since_finality,
        )
Ejemplo n.º 22
0
def process_validator_registry(state: BeaconState,
                               config: BeaconConfig) -> BeaconState:
    state = state.copy(
        previous_calculation_epoch=state.current_calculation_epoch,
        previous_epoch_start_shard=state.current_epoch_start_shard,
        previous_epoch_seed=state.current_epoch_seed,
    )

    need_to_update, num_shards_in_committees = _check_if_update_validator_registry(state, config)

    if need_to_update:
        state = update_validator_registry(state)

        # Update step-by-step since updated `state.current_calculation_epoch`
        # is used to calculate other value). Follow the spec tightly now.
        state = state.copy(
            current_calculation_epoch=state.next_epoch(config.EPOCH_LENGTH),
        )
        state = state.copy(
            current_epoch_start_shard=(
                state.current_epoch_start_shard + num_shards_in_committees
            ) % config.SHARD_COUNT,
        )

        # The `helpers.generate_seed` function is only present to provide an entry point
        # for mocking this out in tests.
        current_epoch_seed = helpers.generate_seed(
            state=state,
            epoch=state.current_calculation_epoch,
            epoch_length=config.EPOCH_LENGTH,
            seed_lookahead=config.SEED_LOOKAHEAD,
            entry_exit_delay=config.ENTRY_EXIT_DELAY,
            latest_index_roots_length=config.LATEST_INDEX_ROOTS_LENGTH,
            latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH,
        )
        state = state.copy(
            current_epoch_seed=current_epoch_seed,
        )
    else:
        epochs_since_last_registry_change = (
            state.current_epoch(config.EPOCH_LENGTH) - state.validator_registry_update_epoch
        )
        if is_power_of_two(epochs_since_last_registry_change):
            # Update step-by-step since updated `state.current_calculation_epoch`
            # is used to calculate other value). Follow the spec tightly now.
            state = state.copy(
                current_calculation_epoch=state.next_epoch(config.EPOCH_LENGTH),
            )

            # The `helpers.generate_seed` function is only present to provide an entry point
            # for mocking this out in tests.
            current_epoch_seed = helpers.generate_seed(
                state=state,
                epoch=state.current_calculation_epoch,
                epoch_length=config.EPOCH_LENGTH,
                seed_lookahead=config.SEED_LOOKAHEAD,
                entry_exit_delay=config.ENTRY_EXIT_DELAY,
                latest_index_roots_length=config.LATEST_INDEX_ROOTS_LENGTH,
                latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH,
            )
            state = state.copy(
                current_epoch_seed=current_epoch_seed,
            )
        else:
            pass

    return state
Ejemplo n.º 23
0
def _process_rewards_and_penalties_for_finality(
    state: BeaconState, config: BeaconConfig,
    previous_epoch_active_validator_indices: Set[ValidatorIndex],
    previous_total_balance: Gwei,
    previous_epoch_attestations: Sequence[Attestation],
    previous_epoch_attester_indices: Set[ValidatorIndex],
    inclusion_infos: Dict[ValidatorIndex, InclusionInfo],
    effective_balances: Dict[ValidatorIndex,
                             Gwei], base_rewards: Dict[ValidatorIndex, Gwei],
    old_rewards_received: Dict[ValidatorIndex, SignedGwei]
) -> Dict[ValidatorIndex, SignedGwei]:
    previous_epoch_boundary_attestations = (
        a for a in previous_epoch_attestations
        if a.data.epoch_boundary_root == get_block_root(
            state,
            get_epoch_start_slot(
                state.previous_epoch(config.SLOTS_PER_EPOCH,
                                     config.GENESIS_EPOCH),
                config.SLOTS_PER_EPOCH,
            ),
            config.LATEST_BLOCK_ROOTS_LENGTH,
        ))
    previous_epoch_boundary_attester_indices = get_attester_indices_from_attesttion(
        state=state,
        attestations=previous_epoch_boundary_attestations,
        committee_config=CommitteeConfig(config),
    )

    previous_epoch_head_attestations = get_previous_epoch_head_attestations(
        state,
        config.SLOTS_PER_EPOCH,
        config.GENESIS_EPOCH,
        config.LATEST_BLOCK_ROOTS_LENGTH,
    )
    previous_epoch_head_attester_indices = get_attester_indices_from_attesttion(
        state=state,
        attestations=previous_epoch_head_attestations,
        committee_config=CommitteeConfig(config),
    )

    rewards_received = {index: Gwei(0) for index in old_rewards_received}
    penalties_received = rewards_received.copy()
    epochs_since_finality = state.next_epoch(
        config.SLOTS_PER_EPOCH) - state.finalized_epoch
    if epochs_since_finality <= 4:
        # 1.1 Expected FFG source:
        previous_epoch_attesting_balance = get_total_balance_from_effective_balances(
            effective_balances,
            previous_epoch_attester_indices,
        )
        # Reward validators in `previous_epoch_attester_indices`
        # # Punish active validators not in `previous_epoch_attester_indices`
        excluded_active_validators_indices = previous_epoch_active_validator_indices.difference(
            previous_epoch_attester_indices, )
        rewards = {
            index:
            Gwei(base_rewards[index] * previous_epoch_attesting_balance //
                 previous_total_balance)
            for index in previous_epoch_attester_indices
        }
        penalties = {
            index: base_rewards[index]
            for index in excluded_active_validators_indices
        }
        rewards_received, penalties_received = _apply_rewards_and_penalties(
            RewardSettlementContext(
                rewards=rewards,
                indices_to_reward=previous_epoch_attester_indices,
                penalties=penalties,
                indices_to_penalize=excluded_active_validators_indices,
                rewards_received=rewards_received,
                penalties_received=penalties_received,
            ), )

        # 1.2 Expected FFG target:
        previous_epoch_boundary_attesting_balance = get_total_balance_from_effective_balances(
            effective_balances,
            previous_epoch_boundary_attester_indices,
        )
        # Reward validators in `previous_epoch_boundary_attester_indices`
        # Punish active validators not in `previous_epoch_boundary_attester_indices`
        excluded_active_validators_indices = previous_epoch_active_validator_indices.difference(
            previous_epoch_boundary_attester_indices, )
        rewards = {
            index: Gwei(base_rewards[index] *
                        previous_epoch_boundary_attesting_balance //
                        previous_total_balance)
            for index in previous_epoch_boundary_attester_indices
        }
        penalties = {
            index: base_rewards[index]
            for index in excluded_active_validators_indices
        }
        rewards_received, penalties_received = _apply_rewards_and_penalties(
            RewardSettlementContext(
                rewards=rewards,
                indices_to_reward=previous_epoch_boundary_attester_indices,
                penalties=penalties,
                indices_to_penalize=excluded_active_validators_indices,
                rewards_received=rewards_received,
                penalties_received=penalties_received,
            ), )

        # 1.3 Expected beacon chain head:
        previous_epoch_head_attesting_balance = get_total_balance_from_effective_balances(
            effective_balances,
            previous_epoch_head_attester_indices,
        )
        # Reward validators in `previous_epoch_head_attester_indices`
        # Punish active validators not in `previous_epoch_head_attester_indices`
        excluded_active_validators_indices = previous_epoch_active_validator_indices.difference(
            previous_epoch_head_attester_indices, )
        rewards = {
            index:
            Gwei(base_rewards[index] * previous_epoch_head_attesting_balance //
                 previous_total_balance)
            for index in previous_epoch_head_attester_indices
        }
        penalties = {
            index: base_rewards[index]
            for index in excluded_active_validators_indices
        }
        rewards_received, penalties_received = _apply_rewards_and_penalties(
            RewardSettlementContext(
                rewards=rewards,
                indices_to_reward=previous_epoch_head_attester_indices,
                penalties=penalties,
                indices_to_penalize=excluded_active_validators_indices,
                rewards_received=rewards_received,
                penalties_received=penalties_received,
            ), )

        # 1.4 Inclusion distance:
        # Reward validators in `previous_epoch_attester_indices`
        rewards = {
            index: Gwei(base_rewards[index] *
                        config.MIN_ATTESTATION_INCLUSION_DELAY //
                        inclusion_infos[index].inclusion_distance)
            for index in previous_epoch_attester_indices
        }
        rewards_received, penalties_received = _apply_rewards_and_penalties(
            RewardSettlementContext(
                rewards=rewards,
                indices_to_reward=previous_epoch_attester_indices,
                rewards_received=rewards_received,
                penalties_received=penalties_received,
            ), )

    # epochs_since_finality > 4
    else:
        # Punish active validators not in `previous_epoch_attester_indices`
        excluded_active_validators_indices = previous_epoch_active_validator_indices.difference(
            previous_epoch_attester_indices, )
        inactivity_penalties = {
            index: base_rewards[index] +
            (effective_balances[index] * epochs_since_finality //
             config.INACTIVITY_PENALTY_QUOTIENT // 2)
            for index in excluded_active_validators_indices
        }
        rewards_received, penalties_received = _apply_rewards_and_penalties(
            RewardSettlementContext(
                penalties=inactivity_penalties,
                indices_to_penalize=excluded_active_validators_indices,
                rewards_received=rewards_received,
                penalties_received=penalties_received,
            ), )

        # Punish active validators not in `previous_epoch_boundary_attester_indices`
        excluded_active_validators_indices = previous_epoch_active_validator_indices.difference(
            previous_epoch_boundary_attester_indices, )
        inactivity_penalties = {
            index: base_rewards[index] +
            (effective_balances[index] * epochs_since_finality //
             config.INACTIVITY_PENALTY_QUOTIENT // 2)
            for index in excluded_active_validators_indices
        }
        rewards_received, penalties_received = _apply_rewards_and_penalties(
            RewardSettlementContext(
                penalties=inactivity_penalties,
                indices_to_penalize=excluded_active_validators_indices,
                rewards_received=rewards_received,
                penalties_received=penalties_received,
            ), )

        # Punish active validators not in `previous_epoch_head_attester_indices`
        excluded_active_validators_indices = previous_epoch_active_validator_indices.difference(
            previous_epoch_head_attester_indices, )
        penalties = {
            index: base_rewards[index]
            for index in excluded_active_validators_indices
        }
        rewards_received, penalties_received = _apply_rewards_and_penalties(
            RewardSettlementContext(
                penalties=penalties,
                indices_to_penalize=excluded_active_validators_indices,
                rewards_received=rewards_received,
                penalties_received=penalties_received,
            ), )

        # Punish penalized active validators
        penalties = {
            index: 3 * base_rewards[index] + 2 *
            (effective_balances[index] * epochs_since_finality //
             config.INACTIVITY_PENALTY_QUOTIENT // 2)
            for index in previous_epoch_active_validator_indices
            if state.validator_registry[index].slashed is True
        }
        rewards_received, penalties_received = _apply_rewards_and_penalties(
            RewardSettlementContext(
                penalties=penalties,
                indices_to_penalize={index
                                     for index in penalties},
                rewards_received=rewards_received,
                penalties_received=penalties_received,
            ), )

        # Punish validators in `previous_epoch_attester_indices`
        penalties = {
            index: Gwei(base_rewards[index] -
                        (base_rewards[index] *
                         config.MIN_ATTESTATION_INCLUSION_DELAY //
                         inclusion_infos[index].inclusion_distance))
            for index in previous_epoch_attester_indices
        }
        rewards_received, penalties_received = _apply_rewards_and_penalties(
            RewardSettlementContext(
                penalties=penalties,
                indices_to_penalize=previous_epoch_attester_indices,
                rewards_received=rewards_received,
                penalties_received=penalties_received,
            ), )

    historical_rewards_received = old_rewards_received.copy()
    for index in rewards_received:
        historical_rewards_received = _update_rewards_or_penalies(
            index,
            rewards_received[index] - penalties_received[index],
            historical_rewards_received,
        )
    return historical_rewards_received