コード例 #1
0
def _is_threshold_met_against_committee(
    state: BeaconState,
    attesting_indices: Set[ValidatorIndex],
    committee: Set[ValidatorIndex],
) -> bool:
    total_attesting_balance = get_total_balance(state, attesting_indices)
    total_committee_balance = get_total_balance(state, committee)
    return _bft_threshold_met(total_attesting_balance, total_committee_balance)
コード例 #2
0
def get_crosslink_deltas(
        state: BeaconState,
        config: Eth2Config) -> Tuple[Sequence[Gwei], Sequence[Gwei]]:
    rewards = tuple(0 for _ in range(len(state.validators)))
    penalties = tuple(0 for _ in range(len(state.validators)))
    epoch = state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH)
    active_validators_indices = get_active_validator_indices(
        state.validators, epoch)
    epoch_committee_count = get_committee_count(
        len(active_validators_indices),
        config.SHARD_COUNT,
        config.SLOTS_PER_EPOCH,
        config.TARGET_COMMITTEE_SIZE,
    )
    epoch_start_shard = get_start_shard(
        state,
        epoch,
        CommitteeConfig(config),
    )
    for shard_offset in range(epoch_committee_count):
        shard = Shard((epoch_start_shard + shard_offset) % config.SHARD_COUNT)
        crosslink_committee = set(
            get_crosslink_committee(
                state,
                epoch,
                shard,
                CommitteeConfig(config),
            ))
        _, attesting_indices = get_winning_crosslink_and_attesting_indices(
            state=state,
            epoch=epoch,
            shard=shard,
            config=config,
        )
        total_attesting_balance = get_total_balance(
            state,
            attesting_indices,
        )
        total_committee_balance = get_total_balance(
            state,
            crosslink_committee,
        )
        for index in crosslink_committee:
            base_reward = get_base_reward(state, index, config)
            if index in attesting_indices:
                rewards = update_tuple_item_with_fn(
                    rewards, index, lambda balance, delta: balance + delta,
                    base_reward * total_attesting_balance //
                    total_committee_balance)
            else:
                penalties = update_tuple_item_with_fn(
                    penalties,
                    index,
                    lambda balance, delta: balance + delta,
                    base_reward,
                )
    return tuple(Gwei(reward) for reward in rewards), tuple(
        Gwei(penalty) for penalty in penalties)
コード例 #3
0
def _is_epoch_justifiable(state: BeaconState,
                          attestations: Sequence[PendingAttestationRecord],
                          epoch: Epoch, config: Eth2Config) -> bool:
    """
    Determine if epoch boundary attesting balance is greater than 2/3 of total_balance
    for the given ``epoch``.
    """
    active_validator_indices = get_active_validator_indices(
        state.validator_registry,
        epoch,
    )

    if not active_validator_indices:
        return False

    total_balance = get_total_balance(
        state.validator_balances,
        active_validator_indices,
        config.MAX_DEPOSIT_AMOUNT,
    )

    attesting_balance = get_epoch_boundary_attesting_balance(
        state, attestations, epoch, config)

    return 3 * attesting_balance >= 2 * total_balance
コード例 #4
0
def _process_rewards_and_penalties_for_crosslinks(
    state: BeaconState, config: Eth2Config,
    effective_balances: Dict[ValidatorIndex,
                             Gwei], base_rewards: Dict[ValidatorIndex, Gwei]
) -> Tuple[Dict[ValidatorIndex, Gwei], Dict[ValidatorIndex,
                                            Gwei]]:  # noqa: E501
    previous_epoch_start_slot = get_epoch_start_slot(
        state.previous_epoch(config.SLOTS_PER_EPOCH),
        config.SLOTS_PER_EPOCH,
    )
    current_epoch_start_slot = get_epoch_start_slot(
        state.current_epoch(config.SLOTS_PER_EPOCH),
        config.SLOTS_PER_EPOCH,
    )
    rewards_received = {
        ValidatorIndex(index): Gwei(0)
        for index in range(len(state.validator_registry))
    }
    penalties_received = rewards_received.copy()
    for slot in range(previous_epoch_start_slot, current_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),
            )
            total_attesting_balance = get_total_balance(
                state.validator_balances,
                attesting_validator_indices,
                config.MAX_DEPOSIT_AMOUNT,
            )
            total_balance = get_total_balance_from_effective_balances(
                effective_balances,
                crosslink_committee,
            )
            for index in attesting_validator_indices:
                rewards_received = _update_rewards_or_penalies(
                    index,
                    base_rewards[index] * total_attesting_balance //
                    total_balance,
                    rewards_received,
                )
            for index in set(crosslink_committee).difference(
                    attesting_validator_indices):
                penalties_received = _update_rewards_or_penalies(
                    index,
                    base_rewards[index],
                    penalties_received,
                )
    return (rewards_received, penalties_received)
コード例 #5
0
def _current_previous_epochs_justifiable(
        state: BeaconState, current_epoch: Epoch, previous_epoch: Epoch,
        config: BeaconConfig) -> Tuple[bool, bool]:
    """
    Determine if epoch boundary attesting balance is greater than 2/3 of current_total_balance
    for current and previous epochs.
    """

    current_epoch_active_validator_indices = get_active_validator_indices(
        state.validator_registry,
        current_epoch,
    )
    previous_epoch_active_validator_indices = get_active_validator_indices(
        state.validator_registry,
        previous_epoch,
    )
    current_total_balance = get_total_balance(
        state.validator_balances,
        current_epoch_active_validator_indices,
        config.MAX_DEPOSIT_AMOUNT,
    )
    previous_total_balance = get_total_balance(
        state.validator_balances,
        previous_epoch_active_validator_indices,
        config.MAX_DEPOSIT_AMOUNT,
    )

    (previous_epoch_boundary_attesting_balance,
     current_epoch_boundary_attesting_balance
     ) = get_epoch_boundary_attesting_balances(current_epoch, previous_epoch,
                                               state, config)

    previous_epoch_justifiable = (3 * previous_epoch_boundary_attesting_balance
                                  >= 2 * previous_total_balance)
    current_epoch_justifiable = (3 * current_epoch_boundary_attesting_balance
                                 >= 2 * current_total_balance)
    return current_epoch_justifiable, previous_epoch_justifiable
コード例 #6
0
def get_attestation_deltas(
        state: BeaconState,
        config: Eth2Config) -> Tuple[Sequence[Gwei], Sequence[Gwei]]:
    rewards = tuple(0 for _ in range(len(state.validators)))
    penalties = tuple(0 for _ in range(len(state.validators)))
    previous_epoch = state.previous_epoch(config.SLOTS_PER_EPOCH)
    total_balance = get_total_active_balance(state, config)
    eligible_validator_indices = tuple(
        ValidatorIndex(index) for index, v in enumerate(state.validators)
        if v.is_active(previous_epoch) or (
            v.slashed and previous_epoch + 1 < v.withdrawable_epoch))

    matching_source_attestations = get_matching_source_attestations(
        state, previous_epoch, config)
    matching_target_attestations = get_matching_target_attestations(
        state, previous_epoch, config)
    matching_head_attestations = get_matching_head_attestations(
        state, previous_epoch, config)

    increment = config.EFFECTIVE_BALANCE_INCREMENT
    total_balance_in_increment = total_balance // increment
    for attestations in (
            matching_source_attestations,
            matching_target_attestations,
            matching_head_attestations,
    ):
        unslashed_attesting_indices = get_unslashed_attesting_indices(
            state, attestations, config)
        attesting_balance = get_total_balance(state,
                                              unslashed_attesting_indices,
                                              config)
        attesting_balance_in_increment = attesting_balance // increment
        for index in eligible_validator_indices:
            if index in unslashed_attesting_indices:
                if is_in_inactivity_leak(state, config):
                    reward = get_base_reward(state, index, config)
                else:
                    reward = Gwei((get_base_reward(state, index, config) *
                                   attesting_balance_in_increment) //
                                  total_balance_in_increment)
                rewards = update_tuple_item_with_fn(
                    rewards, index, lambda balance, delta: balance + delta,
                    reward)
            else:
                penalties = update_tuple_item_with_fn(
                    penalties,
                    index,
                    lambda balance, delta: balance + delta,
                    get_base_reward(state, index, config),
                )

    for index in get_unslashed_attesting_indices(state,
                                                 matching_source_attestations,
                                                 config):
        attestation = min(
            (a for a in matching_source_attestations if index in
             get_attesting_indices(state, a.data, a.aggregation_bits, config)),
            key=lambda a: a.inclusion_delay,
        )
        proposer_reward = get_proposer_reward(state, index, config)
        rewards = update_tuple_item_with_fn(
            rewards,
            attestation.proposer_index,
            lambda balance, delta: balance + delta,
            proposer_reward,
        )
        base_reward = get_base_reward(state, index, config)
        max_attester_reward = base_reward - proposer_reward
        rewards = update_tuple_item_with_fn(
            rewards,
            index,
            lambda balance, delta: balance + delta,
            (max_attester_reward // attestation.inclusion_delay),
        )

    if is_in_inactivity_leak(state, config):
        matching_target_attesting_indices = get_unslashed_attesting_indices(
            state, matching_target_attestations, config)
        for index in eligible_validator_indices:
            base_reward = get_base_reward(state, index, config)
            penalties = update_tuple_item_with_fn(
                penalties,
                index,
                lambda balance, delta: balance + delta,
                BASE_REWARDS_PER_EPOCH * base_reward -
                get_proposer_reward(state, index, config),
            )
            if index not in matching_target_attesting_indices:
                effective_balance = state.validators[index].effective_balance
                penalties = update_tuple_item_with_fn(
                    penalties,
                    index,
                    lambda balance, delta: balance + delta,
                    effective_balance *
                    get_finality_delay(state, config.SLOTS_PER_EPOCH) //
                    config.INACTIVITY_PENALTY_QUOTIENT,
                )
    return (
        tuple(Gwei(reward) for reward in rewards),
        tuple(Gwei(penalty) for penalty in penalties),
    )
コード例 #7
0
def get_attestation_deltas(state: BeaconState,
                           config: Eth2Config) -> Tuple[Sequence[Gwei], Sequence[Gwei]]:
    committee_config = CommitteeConfig(config)
    rewards = tuple(
        0 for _ in range(len(state.validators))
    )
    penalties = tuple(
        0 for _ in range(len(state.validators))
    )
    previous_epoch = state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH)
    total_balance = get_total_active_balance(state, config)
    eligible_validator_indices = tuple(
        ValidatorIndex(index) for index, v in enumerate(state.validators)
        if v.is_active(previous_epoch) or (
            v.slashed and previous_epoch + 1 < v.withdrawable_epoch
        )
    )

    matching_source_attestations = get_matching_source_attestations(
        state,
        previous_epoch,
        config,
    )
    matching_target_attestations = get_matching_target_attestations(
        state,
        previous_epoch,
        config,
    )
    matching_head_attestations = get_matching_head_attestations(
        state,
        previous_epoch,
        config,
    )

    for attestations in (
            matching_source_attestations,
            matching_target_attestations,
            matching_head_attestations
    ):
        unslashed_attesting_indices = get_unslashed_attesting_indices(
            state,
            attestations,
            committee_config,
        )
        attesting_balance = get_total_balance(state, unslashed_attesting_indices)
        for index in eligible_validator_indices:
            if index in unslashed_attesting_indices:
                rewards = update_tuple_item_with_fn(
                    rewards,
                    index,
                    lambda balance, delta: balance + delta,
                    get_base_reward(
                        state,
                        index,
                        config,
                    ) * attesting_balance // total_balance,
                )
            else:
                penalties = update_tuple_item_with_fn(
                    penalties,
                    index,
                    lambda balance, delta: balance + delta,
                    get_base_reward(
                        state,
                        index,
                        config,
                    ),
                )

    for index in get_unslashed_attesting_indices(
            state,
            matching_source_attestations,
            committee_config,
    ):
        attestation = min(
            (
                a for a in matching_source_attestations
                if index in get_attesting_indices(
                    state,
                    a.data,
                    a.aggregation_bitfield,
                    committee_config,
                )
            ),
            key=lambda a: a.inclusion_delay,
        )
        base_reward = get_base_reward(state, index, config)
        proposer_reward = base_reward // config.PROPOSER_REWARD_QUOTIENT
        rewards = update_tuple_item_with_fn(
            rewards,
            attestation.proposer_index,
            lambda balance, delta: balance + delta,
            proposer_reward,
        )
        max_attester_reward = base_reward - proposer_reward
        rewards = update_tuple_item_with_fn(
            rewards,
            index,
            lambda balance, delta: balance + delta,
            (
                max_attester_reward *
                config.MIN_ATTESTATION_INCLUSION_DELAY //
                attestation.inclusion_delay
            )
        )

    finality_delay = previous_epoch - state.finalized_epoch
    if finality_delay > config.MIN_EPOCHS_TO_INACTIVITY_PENALTY:
        matching_target_attesting_indices = get_unslashed_attesting_indices(
            state,
            matching_target_attestations,
            committee_config,
        )
        for index in eligible_validator_indices:
            penalties = update_tuple_item_with_fn(
                penalties,
                index,
                lambda balance, delta: balance + delta,
                BASE_REWARDS_PER_EPOCH * get_base_reward(
                    state,
                    index,
                    config,
                ),
            )
            if index not in matching_target_attesting_indices:
                effective_balance = state.validators[index].effective_balance
                penalties = update_tuple_item_with_fn(
                    penalties,
                    index,
                    lambda balance, delta: balance + delta,
                    effective_balance * finality_delay // config.INACTIVITY_PENALTY_QUOTIENT,
                )
    return tuple(
        Gwei(reward) for reward in rewards
    ), tuple(
        Gwei(penalty) for penalty in penalties
    )
コード例 #8
0
def test_get_winning_root(random, monkeypatch, target_committee_size,
                          block_root_1_participants, block_root_2_participants,
                          config, committee_config, n_validators_state,
                          sample_attestation_data_params,
                          sample_attestation_params):
    shard = 1
    committee = tuple([i for i in range(target_committee_size)])

    from eth2.beacon import committee_helpers

    def mock_get_crosslink_committees_at_slot(state,
                                              slot,
                                              committee_config,
                                              registry_change=False):
        return ((
            committee,
            shard,
        ), )

    monkeypatch.setattr(committee_helpers, 'get_crosslink_committees_at_slot',
                        mock_get_crosslink_committees_at_slot)

    competing_block_roots = [
        hash_eth2(bytearray(random.getrandbits(8) for _ in range(10))),
        hash_eth2(bytearray(random.getrandbits(8) for _ in range(10)))
    ]

    # Generate bitfield of each participants set
    root_1_participants_bitfield = get_aggregation_bitfield(
        block_root_1_participants,
        target_committee_size,
    )
    root_2_participants_bitfield = get_aggregation_bitfield(
        block_root_2_participants,
        target_committee_size,
    )
    # `attestions` contains attestation to different block root by different set of participants
    attestations = (
        # Attestation to `crosslink_data_root_1` by `attestation_participants_1`
        Attestation(**sample_attestation_params).copy(
            aggregation_bitfield=root_1_participants_bitfield,
            data=AttestationData(**sample_attestation_data_params).copy(
                shard=shard,
                crosslink_data_root=competing_block_roots[0],
            ),
        ),
        # Attestation to `crosslink_data_root_2` by `attestation_participants_2`
        Attestation(**sample_attestation_params).copy(
            aggregation_bitfield=root_2_participants_bitfield,
            data=AttestationData(**sample_attestation_data_params).copy(
                shard=shard,
                crosslink_data_root=competing_block_roots[1],
            ),
        ),
    )

    try:
        winning_root, attesting_balance = get_winning_root(
            state=n_validators_state,
            shard=shard,
            attestations=attestations,
            max_deposit_amount=config.MAX_DEPOSIT_AMOUNT,
            committee_config=committee_config,
        )
        attesting_validators_indices = get_attester_indices_from_attesttion(
            state=n_validators_state,
            attestations=(a for a in attestations if a.data.shard == shard
                          and a.data.crosslink_data_root == winning_root),
            committee_config=committee_config,
        )
        total_attesting_balance = get_total_balance(
            n_validators_state.validator_balances,
            attesting_validators_indices,
            config.MAX_DEPOSIT_AMOUNT,
        )
        assert attesting_balance == total_attesting_balance
    except NoWinningRootError:
        assert len(block_root_1_participants) == 0 and len(
            block_root_2_participants) == 0
    else:
        if len(block_root_1_participants) == len(block_root_2_participants):
            if competing_block_roots[0] < competing_block_roots[1]:
                assert winning_root == competing_block_roots[0]
            else:
                assert winning_root == competing_block_roots[1]
        elif len(block_root_1_participants) < len(block_root_2_participants):
            assert winning_root == competing_block_roots[1]
        else:
            assert winning_root == competing_block_roots[0]
コード例 #9
0
def update_validator_registry(state: BeaconState,
                              config: BeaconConfig) -> BeaconState:
    """
    Update validator registry.
    """
    current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    # The active validators
    active_validator_indices = get_active_validator_indices(
        state.validator_registry, current_epoch)
    # The total effective balance of active validators
    total_balance = get_total_balance(
        state.validator_balances,
        active_validator_indices,
        config.MAX_DEPOSIT_AMOUNT,
    )

    # The maximum balance churn in Gwei (for deposits and exits separately)
    max_balance_churn = max(
        config.MAX_DEPOSIT_AMOUNT,
        total_balance // (2 * config.MAX_BALANCE_CHURN_QUOTIENT))

    # Activate validators within the allowable balance churn
    # linter didn't like a bare lambda
    state = _churn_validators(
        state=state,
        config=config,
        check_should_churn_fn=lambda state, index: _is_ready_to_activate(
            state,
            index,
            max_deposit_amount=config.MAX_DEPOSIT_AMOUNT,
        ),
        churn_fn=lambda state, index: activate_validator(
            state,
            index,
            is_genesis=False,
            genesis_epoch=config.GENESIS_EPOCH,
            slots_per_epoch=config.SLOTS_PER_EPOCH,
            activation_exit_delay=config.ACTIVATION_EXIT_DELAY,
        ),
        max_balance_churn=max_balance_churn,
    )

    # Exit validators within the allowable balance churn
    # linter didn't like a bare lambda
    state = _churn_validators(
        state=state,
        config=config,
        check_should_churn_fn=lambda state, index: _is_ready_to_exit(
            state, index),
        churn_fn=lambda state, index: exit_validator(
            state,
            index,
            slots_per_epoch=config.SLOTS_PER_EPOCH,
            activation_exit_delay=config.ACTIVATION_EXIT_DELAY,
        ),
        max_balance_churn=max_balance_churn,
    )

    state = state.copy(validator_registry_update_epoch=current_epoch, )

    return state
コード例 #10
0
def process_rewards_and_penalties(state: BeaconState,
                                  config: BeaconConfig) -> BeaconState:
    # Compute previous epoch active validator indices and the total balance they account for
    # for later use.
    previous_epoch_active_validator_indices = set(
        get_active_validator_indices(
            state.validator_registry,
            state.previous_epoch(config.SLOTS_PER_EPOCH,
                                 config.GENESIS_EPOCH)))
    previous_total_balance: Gwei = get_total_balance(
        state.validator_balances,
        tuple(previous_epoch_active_validator_indices),
        config.MAX_DEPOSIT_AMOUNT,
    )

    # Compute previous epoch attester indices and the total balance they account for
    # for later use.
    previous_epoch_attestations = get_previous_epoch_attestations(
        state,
        config.SLOTS_PER_EPOCH,
        config.GENESIS_EPOCH,
    )
    previous_epoch_attester_indices = get_attester_indices_from_attesttion(
        state=state,
        attestations=previous_epoch_attestations,
        committee_config=CommitteeConfig(config),
    )

    # Compute inclusion slot/distance of previous attestations for later use.
    inclusion_infos = get_inclusion_infos(
        state=state,
        attestations=previous_epoch_attestations,
        committee_config=CommitteeConfig(config),
    )

    # Compute effective balance of each previous epoch active validator for later use
    effective_balances = {
        index: get_effective_balance(
            state.validator_balances,
            index,
            config.MAX_DEPOSIT_AMOUNT,
        )
        for index in previous_epoch_active_validator_indices
    }
    # Compute base reward of each previous epoch active validator for later use
    _base_reward_quotient = (integer_squareroot(previous_total_balance) //
                             config.BASE_REWARD_QUOTIENT)
    base_rewards = {
        index: get_base_reward(
            state=state,
            index=index,
            base_reward_quotient=_base_reward_quotient,
            max_deposit_amount=config.MAX_DEPOSIT_AMOUNT,
        )
        for index in previous_epoch_active_validator_indices
    }

    # Initialize the reward (validator) received map
    rewards_received = {
        index: SignedGwei(0)
        for index in previous_epoch_active_validator_indices
    }

    # 1. Process rewards and penalties for justification and finalization
    rewards_received = pipe(
        rewards_received,
        _process_rewards_and_penalties_for_finality(
            state,
            config,
            previous_epoch_active_validator_indices,
            previous_total_balance,
            previous_epoch_attestations,
            previous_epoch_attester_indices,
            inclusion_infos,
            effective_balances,
            base_rewards,
        ),
        _process_rewards_and_penalties_for_attestation_inclusion(
            state,
            config,
            previous_epoch_attester_indices,
            inclusion_infos,
            base_rewards,
        ),
        _process_rewards_and_penalties_for_crosslinks(
            state,
            config,
            previous_epoch_attestations,
            effective_balances,
            base_rewards,
        ))

    # Apply the overall rewards/penalties
    for index in previous_epoch_active_validator_indices:
        state = state.update_validator_balance(
            index,
            # Prevent validator balance under flow
            max(state.validator_balances[index] + rewards_received[index], 0),
        )

    return state
コード例 #11
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.SLOTS_PER_EPOCH,
        config.GENESIS_EPOCH,
    )
    current_epoch_attestations = get_current_epoch_attestations(
        state, config.SLOTS_PER_EPOCH)
    previous_epoch_start_slot = get_epoch_start_slot(
        state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_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:
            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 = 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=state.current_epoch(config.SLOTS_PER_EPOCH),
                            crosslink_data_root=winning_root,
                        ),
                    )
                else:
                    # Don't update the crosslink of this shard
                    pass
    state = state.copy(latest_crosslinks=latest_crosslinks, )
    return state
コード例 #12
0
def process_rewards_and_penalties(state: BeaconState,
                                  config: Eth2Config) -> BeaconState:
    # Compute previous epoch active validator indices and the total balance they account for
    # for later use.
    previous_epoch_active_validator_indices = set(
        get_active_validator_indices(
            state.validator_registry,
            state.previous_epoch(config.SLOTS_PER_EPOCH)))
    previous_total_balance: Gwei = get_total_balance(
        state.validator_balances,
        tuple(previous_epoch_active_validator_indices),
        config.MAX_DEPOSIT_AMOUNT,
    )

    # Compute previous epoch attester indices and the total balance they account for
    # for later use.
    previous_epoch_attestations = state.previous_epoch_attestations
    previous_epoch_attester_indices = get_attester_indices_from_attestations(
        state=state,
        attestations=previous_epoch_attestations,
        committee_config=CommitteeConfig(config),
    )

    # Compute inclusion slot/distance of previous attestations for later use.
    inclusion_infos = get_inclusion_infos(
        state=state,
        attestations=previous_epoch_attestations,
        committee_config=CommitteeConfig(config),
    )

    # Compute effective balance of each previous epoch active validator for later use
    effective_balances = {
        ValidatorIndex(index): get_effective_balance(
            state.validator_balances,
            ValidatorIndex(index),
            config.MAX_DEPOSIT_AMOUNT,
        )
        for index in range(len(state.validator_registry))
    }
    # Compute base reward of each previous epoch active validator for later use
    base_rewards = {
        ValidatorIndex(index): get_base_reward(
            state=state,
            index=ValidatorIndex(index),
            base_reward_quotient=config.BASE_REWARD_QUOTIENT,
            previous_total_balance=previous_total_balance,
            max_deposit_amount=config.MAX_DEPOSIT_AMOUNT,
        )
        for index in range(len(state.validator_registry))
    }

    # 1. Process rewards and penalties for justification and finalization
    finality_rewards, finality_penalties = _process_rewards_and_penalties_for_finality(
        state,
        config,
        previous_epoch_active_validator_indices,
        previous_total_balance,
        previous_epoch_attestations,
        previous_epoch_attester_indices,
        inclusion_infos,
        effective_balances,
        base_rewards,
    )
    # 2. Process rewards and penalties for crosslinks
    crosslinks_rewards, crosslinks_penalties = _process_rewards_and_penalties_for_crosslinks(
        state,
        config,
        effective_balances,
        base_rewards,
    )

    # Apply the overall rewards/penalties
    for index in range(len(state.validator_registry)):
        state = state.update_validator_balance(
            ValidatorIndex(index),
            # Prevent validator balance under flow
            max(
                (state.validator_balances[index] + finality_rewards[index] +
                 crosslinks_rewards[index] - finality_penalties[index] -
                 crosslinks_penalties[index]),
                0,
            ),
        )

    return state
コード例 #13
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