Пример #1
0
def calc_merkle_tree_from_leaves(leaves: Sequence[Hash32]) -> MerkleTree:
    if len(leaves) == 0:
        raise ValueError("No leaves given")
    tree: Tuple[Sequence[Hash32], ...] = (leaves, )
    for i in range(TreeDepth):
        if len(tree[0]) % 2 == 1:
            tree = update_tuple_item(
                tree,
                0,
                tuple(tree[0]) + (EmptyNodeHashes[i], ),
            )
        tree = tuple(cons(_hash_layer(tree[0]), tree))
    return MerkleTree(tree)
Пример #2
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 update_tuple_item(
        state.randao_mixes,
        next_epoch % config.EPOCHS_PER_HISTORICAL_VECTOR,
        get_randao_mix(
            state,
            current_epoch,
            config.SLOTS_PER_EPOCH,
            config.EPOCHS_PER_HISTORICAL_VECTOR,
        ),
    )
Пример #3
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)
Пример #4
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 = _update_latest_index_roots(state, CommitteeConfig(config))

    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
Пример #5
0
def _determine_updated_justification_data(
    justified_epoch: Epoch,
    bitfield: Bitfield,
    is_epoch_justifiable: bool,
    candidate_epoch: Epoch,
    bit_offset: int,
) -> Tuple[Epoch, Bitfield]:
    if is_epoch_justifiable:
        return (
            candidate_epoch,
            Bitfield(update_tuple_item(bitfield, bit_offset, True)),
        )
    else:
        return (justified_epoch, bitfield)
def test_process_final_updates(genesis_state,
                               state_slot,
                               attestation_slot,
                               len_latest_attestations,
                               expected_result_len_latest_attestations,
                               config,
                               sample_attestation_params):
    state = genesis_state.copy(
        slot=state_slot,
    )
    epoch = state.slot // config.EPOCH_LENGTH
    current_index = (epoch + 1) % config.LATEST_PENALIZED_EXIT_LENGTH
    previous_index = epoch % config.LATEST_PENALIZED_EXIT_LENGTH

    # Assume `len_latest_attestations` attestations in state.latest_attestations
    # with attestation.data.slot = attestation_slot
    attestation = Attestation(**sample_attestation_params)
    latest_attestations = [
        attestation.copy(
            data=attestation.data.copy(
                slot=attestation_slot
            )
        )
        for i in range(len_latest_attestations)
    ]

    # Fill latest_penalized_balances
    penalized_balance_of_previous_epoch = 100
    latest_penalized_balances = update_tuple_item(
        state.latest_penalized_balances,
        previous_index,
        penalized_balance_of_previous_epoch,
    )
    state = state.copy(
        latest_penalized_balances=latest_penalized_balances,
        latest_attestations=latest_attestations,
    )

    result_state = process_final_updates(state, config)

    assert (
        result_state.latest_penalized_balances[current_index] ==
        penalized_balance_of_previous_epoch
    )

    assert len(result_state.latest_attestations) == expected_result_len_latest_attestations
    for attestation in result_state.latest_attestations:
        assert attestation.data.slot >= state_slot - config.EPOCH_LENGTH
Пример #7
0
    def _update_validator_balance(self,
                                  validator_index: ValidatorIndex,
                                  balance: Gwei) -> 'BeaconState':
        """
        Update the balance of validator of the given ``validator_index``.
        """
        if validator_index >= len(self.balances) or validator_index < 0:
            raise IndexError("Incorrect validator index")

        return self.copy(
            balances=update_tuple_item(
                self.balances,
                validator_index,
                balance,
            )
        )
Пример #8
0
def process_final_updates(state: BeaconState,
                          config: BeaconConfig) -> BeaconState:
    epoch = state.slot // config.EPOCH_LENGTH
    current_index = (epoch + 1) % config.LATEST_PENALIZED_EXIT_LENGTH
    previous_index = epoch % config.LATEST_PENALIZED_EXIT_LENGTH

    state = state.copy(latest_penalized_balances=update_tuple_item(
        state.latest_penalized_balances,
        current_index,
        state.latest_penalized_balances[previous_index],
    ), )

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

    return state
def test_check_if_update_validator_registry(genesis_state,
                                            state_slot,
                                            validator_registry_update_epoch,
                                            finalized_epoch,
                                            has_crosslink,
                                            crosslink_epoch,
                                            expected_need_to_update,
                                            config):
    state = genesis_state.copy(
        slot=state_slot,
        finalized_epoch=finalized_epoch,
        validator_registry_update_epoch=validator_registry_update_epoch,
    )
    if has_crosslink:
        crosslink = CrosslinkRecord(
            epoch=crosslink_epoch,
            crosslink_data_root=ZERO_HASH32,
        )
        latest_crosslinks = state.latest_crosslinks
        for shard in range(config.SHARD_COUNT):
            latest_crosslinks = update_tuple_item(
                latest_crosslinks,
                shard,
                crosslink,
            )
        state = state.copy(
            latest_crosslinks=latest_crosslinks,
        )

    need_to_update, num_shards_in_committees = _check_if_update_validator_registry(state, config)

    assert need_to_update == expected_need_to_update
    if expected_need_to_update:
        expected_num_shards_in_committees = get_current_epoch_committee_count(
            state,
            shard_count=config.SHARD_COUNT,
            slots_per_epoch=config.SLOTS_PER_EPOCH,
            target_committee_size=config.TARGET_COMMITTEE_SIZE,
        )
        assert num_shards_in_committees == expected_num_shards_in_committees
    else:
        assert num_shards_in_committees == 0
Пример #10
0
def process_crosslinks(state: BeaconState, config: Eth2Config) -> BeaconState:
    current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    previous_epoch = state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH)

    new_current_crosslinks = state.current_crosslinks

    for epoch in (previous_epoch, current_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))
            )

            if not crosslink_committee:
                # empty crosslink committee this epoch
                continue

            winning_crosslink, attesting_indices = get_winning_crosslink_and_attesting_indices(
                state=state, epoch=epoch, shard=shard, config=config
            )
            threshold_met = _is_threshold_met_against_committee(
                state, attesting_indices, crosslink_committee
            )
            if threshold_met:
                new_current_crosslinks = update_tuple_item(
                    new_current_crosslinks, shard, winning_crosslink
                )

    return state.copy(
        previous_crosslinks=state.current_crosslinks,
        current_crosslinks=new_current_crosslinks,
    )
Пример #11
0
def process_eth1_data(state: BeaconState,
                      block: BaseBeaconBlock) -> BeaconState:
    try:
        vote_index, original_vote = first(
            (index, eth1_data_vote)
            for index, eth1_data_vote in enumerate(state.eth1_data_votes)
            if block.eth1_data == eth1_data_vote.eth1_data)
    except StopIteration:
        new_vote = Eth1DataVote(
            eth1_data=block.eth1_data,
            vote_count=1,
        )
        state = state.copy(eth1_data_votes=state.eth1_data_votes +
                           (new_vote, ))
    else:
        updated_vote = original_vote.copy(vote_count=original_vote.vote_count +
                                          1)
        state = state.copy(eth1_data_votes=update_tuple_item(
            state.eth1_data_votes, vote_index, updated_vote))

    return state
Пример #12
0
def test_get_matching_target_attestations(genesis_state, config):
    some_epoch = config.GENESIS_EPOCH + 20
    some_slot = compute_start_slot_of_epoch(some_epoch, config.SLOTS_PER_EPOCH)
    some_target_root = b"\x33" * 32
    target_attestations = tuple((PendingAttestation(data=AttestationData(
        target=Checkpoint(root=some_target_root))) for _ in range(3)))
    current_epoch_attestations = target_attestations + tuple(
        (PendingAttestation(data=AttestationData(target=Checkpoint(
            root=b"\x44" * 32))) for _ in range(3)))
    state = genesis_state.copy(
        slot=some_slot + 1,
        block_roots=update_tuple_item(
            genesis_state.block_roots,
            some_slot % config.SLOTS_PER_HISTORICAL_ROOT,
            some_target_root,
        ),
        current_epoch_attestations=current_epoch_attestations,
    )

    attestations = get_matching_target_attestations(state, some_epoch, config)

    assert attestations == target_attestations
Пример #13
0
def get_compact_committees_root(state: BeaconState, epoch: Epoch,
                                config: CommitteeConfig) -> Hash32:
    shard_count = config.SHARD_COUNT

    committees = (CompactCommittee(), ) * shard_count
    start_shard = get_start_shard(state, epoch, config)
    active_validator_indices = get_active_validator_indices(
        state.validators, epoch)
    committee_count = get_committee_count(
        len(active_validator_indices),
        config.SHARD_COUNT,
        config.SLOTS_PER_EPOCH,
        config.TARGET_COMMITTEE_SIZE,
    )
    for committee_number in range(committee_count):
        shard = Shard((start_shard + committee_number) % shard_count)
        compact_committee = _compute_compact_committee_for_shard_in_epoch(
            state, epoch, shard, config)
        committees = update_tuple_item(committees, shard, compact_committee)
    return ssz.get_hash_tree_root(committees,
                                  sedes=ssz.sedes.Vector(
                                      CompactCommittee, shard_count))
Пример #14
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,
        next_epoch,
    )
    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, )
Пример #15
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)

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

    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, )
Пример #16
0
def process_randao(state: BeaconState,
                   block: BaseBeaconBlock,
                   config: BeaconConfig) -> BeaconState:
    proposer_index = get_beacon_proposer_index(
        state=state,
        slot=state.slot,
        committee_config=CommitteeConfig(config),
    )
    proposer = state.validator_registry[proposer_index]

    epoch = state.current_epoch(config.EPOCH_LENGTH)

    validate_randao_reveal(
        randao_reveal=block.randao_reveal,
        proposer_pubkey=proposer.pubkey,
        epoch=epoch,
        fork=state.fork,
    )

    randao_mix_index = epoch % config.LATEST_RANDAO_MIXES_LENGTH
    new_randao_mix = bitwise_xor(
        get_randao_mix(
            state=state,
            epoch=epoch,
            epoch_length=config.EPOCH_LENGTH,
            latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH,
        ),
        hash_eth2(block.randao_reveal),
    )

    return state.copy(
        latest_randao_mixes=update_tuple_item(
            state.latest_randao_mixes,
            randao_mix_index,
            new_randao_mix,
        ),
    )
Пример #17
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, )
Пример #18
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
Пример #19
0
def _settle_penality_to_validator_and_whistleblower(
        *,
        state: BeaconState,
        validator_index: ValidatorIndex,
        latest_penalized_exit_length: int,
        whistleblower_reward_quotient: int,
        genesis_epoch: EpochNumber,
        epoch_length: int,
        max_deposit_amount: Gwei,
        target_committee_size: int,
        shard_count: int) -> BeaconState:
    """
    Apply penality/reward to validator and whistleblower and update the meta data

    More intuitive pseudo-code:
    current_epoch_penalization_index = (state.slot // EPOCH_LENGTH) % LATEST_PENALIZED_EXIT_LENGTH
    state.latest_penalized_balances[current_epoch_penalization_index] += (
        get_effective_balance(state, index)
    )
    whistleblower_index = get_beacon_proposer_index(state, state.slot)
    whistleblower_reward = get_effective_balance(state, index) // WHISTLEBLOWER_REWARD_QUOTIENT
    state.validator_balances[whistleblower_index] += whistleblower_reward
    state.validator_balances[index] -= whistleblower_reward
    validator.penalized_epoch = slot_to_epoch(state.slot)
    """
    # Update `state.latest_penalized_balances`
    current_epoch_penalization_index = state.current_epoch(
        epoch_length) % latest_penalized_exit_length
    effective_balance = get_effective_balance(
        state.validator_balances,
        validator_index,
        max_deposit_amount,
    )
    penalized_exit_balance = (
        state.latest_penalized_balances[current_epoch_penalization_index] +
        effective_balance
    )
    latest_penalized_balances = update_tuple_item(
        tuple_data=state.latest_penalized_balances,
        index=current_epoch_penalization_index,
        new_value=penalized_exit_balance,
    )
    state = state.copy(
        latest_penalized_balances=latest_penalized_balances,
    )

    # Update whistleblower's balance
    whistleblower_reward = (
        effective_balance //
        whistleblower_reward_quotient
    )
    whistleblower_index = get_beacon_proposer_index(
        state,
        state.slot,
        genesis_epoch=genesis_epoch,
        epoch_length=epoch_length,
        target_committee_size=target_committee_size,
        shard_count=shard_count,
    )
    state = state.update_validator_balance(
        whistleblower_index,
        state.validator_balances[whistleblower_index] + whistleblower_reward,
    )

    # Update validator's balance and `penalized_epoch` field
    validator = state.validator_registry[validator_index]
    validator = validator.copy(
        penalized_epoch=state.current_epoch(epoch_length),
    )
    state = state.update_validator(
        validator_index,
        validator,
        state.validator_balances[validator_index] - whistleblower_reward,
    )

    return state
Пример #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
def test_process_rewards_and_penalties_for_finality(
        n_validators_state,
        config,
        slots_per_epoch,
        target_committee_size,
        shard_count,
        min_attestation_inclusion_delay,
        inactivity_penalty_quotient,
        finalized_epoch,
        current_slot,
        penalized_validator_indices,
        previous_epoch_active_validator_indices,
        previous_epoch_attester_indices,
        previous_epoch_boundary_head_attester_indices,
        inclusion_distances,
        effective_balance,
        base_reward,
        expected_rewards_received,
        sample_pending_attestation_record_params,
        sample_attestation_data_params):
    validator_registry = n_validators_state.validator_registry
    for index in penalized_validator_indices:
        validator_record = validator_registry[index].copy(
            slashed=True,
        )
        validator_registry = update_tuple_item(validator_registry, index, validator_record)
    state = n_validators_state.copy(
        slot=current_slot,
        finalized_epoch=finalized_epoch,
        validator_registry=validator_registry,
    )
    previous_total_balance = len(previous_epoch_active_validator_indices) * effective_balance

    attestation_slot = current_slot - slots_per_epoch
    inclusion_infos = {
        index: InclusionInfo(
            attestation_slot + inclusion_distances[index],
            attestation_slot,
        )
        for index in previous_epoch_attester_indices
    }

    effective_balances = {
        index: effective_balance
        for index in previous_epoch_active_validator_indices
    }

    base_rewards = {
        index: base_reward
        for index in previous_epoch_active_validator_indices
    }

    rewards_received = {
        index: 0
        for index in range(len(state.validator_registry))
    }

    prev_epoch_start_slot = get_epoch_start_slot(
        state.previous_epoch(config.SLOTS_PER_EPOCH, config.GENESIS_EPOCH), slots_per_epoch,
    )
    prev_epoch_crosslink_committees = [
        get_crosslink_committees_at_slot(
            state,
            slot,
            CommitteeConfig(config),
        )[0] for slot in range(prev_epoch_start_slot, prev_epoch_start_slot + slots_per_epoch)
    ]

    prev_epoch_attestations = []
    for i in range(slots_per_epoch):
        committee, shard = prev_epoch_crosslink_committees[i]
        participants_bitfield = get_empty_bitfield(target_committee_size)
        for index in previous_epoch_boundary_head_attester_indices:
            if index in committee:
                participants_bitfield = set_voted(participants_bitfield, committee.index(index))
        prev_epoch_attestations.append(
            PendingAttestationRecord(**sample_pending_attestation_record_params).copy(
                data=AttestationData(**sample_attestation_data_params).copy(
                    slot=(prev_epoch_start_slot + i),
                    shard=shard,
                    epoch_boundary_root=get_block_root(
                        state,
                        prev_epoch_start_slot,
                        config.LATEST_BLOCK_ROOTS_LENGTH,
                    ),
                    beacon_block_root=get_block_root(
                        state,
                        (prev_epoch_start_slot + i),
                        config.LATEST_BLOCK_ROOTS_LENGTH,
                    ),
                ),
                aggregation_bitfield=participants_bitfield,
            )
        )
    state = state.copy(
        latest_attestations=prev_epoch_attestations,
    )

    rewards_received = _process_rewards_and_penalties_for_finality(
        state,
        config,
        previous_epoch_active_validator_indices,
        previous_total_balance,
        prev_epoch_attestations,
        previous_epoch_attester_indices,
        inclusion_infos,
        effective_balances,
        base_rewards,
        rewards_received,
    )

    for index, reward_received in rewards_received.items():
        assert reward_received == expected_rewards_received[index]
Пример #22
0
def _settle_penality_to_validator_and_whistleblower(
        *, state: BeaconState, validator_index: ValidatorIndex,
        latest_slashed_exit_length: int, whistleblower_reward_quotient: int,
        max_deposit_amount: Gwei,
        committee_config: CommitteeConfig) -> BeaconState:
    """
    Apply penality/reward to validator and whistleblower and update the meta data

    More intuitive pseudo-code:
    current_epoch_penalization_index = (state.slot // SLOTS_PER_EPOCH) % LATEST_SLASHED_EXIT_LENGTH
    state.latest_slashed_balances[current_epoch_penalization_index] += (
        get_effective_balance(state, index)
    )
    whistleblower_index = get_beacon_proposer_index(state, state.slot)
    whistleblower_reward = get_effective_balance(state, index) // WHISTLEBLOWER_REWARD_QUOTIENT
    state.validator_balances[whistleblower_index] += whistleblower_reward
    state.validator_balances[index] -= whistleblower_reward
    validator.slashed = True
    validator.withdrawable_epoch = get_current_epoch(state) + LATEST_SLASHED_EXIT_LENGTH
    """
    slots_per_epoch = committee_config.SLOTS_PER_EPOCH

    # Update `state.latest_slashed_balances`
    current_epoch_penalization_index = state.current_epoch(
        slots_per_epoch) % latest_slashed_exit_length
    effective_balance = get_effective_balance(
        state.validator_balances,
        validator_index,
        max_deposit_amount,
    )
    slashed_exit_balance = (
        state.latest_slashed_balances[current_epoch_penalization_index] +
        effective_balance)
    latest_slashed_balances = update_tuple_item(
        tuple_data=state.latest_slashed_balances,
        index=current_epoch_penalization_index,
        new_value=slashed_exit_balance,
    )
    state = state.copy(latest_slashed_balances=latest_slashed_balances, )

    # Update whistleblower's balance
    whistleblower_reward = (effective_balance // whistleblower_reward_quotient)
    whistleblower_index = get_beacon_proposer_index(
        state,
        state.slot,
        committee_config,
    )
    state = state.update_validator_balance(
        whistleblower_index,
        state.validator_balances[whistleblower_index] + whistleblower_reward,
    )

    # Update validator's balance and `slashed`, `withdrawable_epoch` field
    validator = state.validator_registry[validator_index].copy(
        slashed=True,
        withdrawable_epoch=state.current_epoch(slots_per_epoch) +
        latest_slashed_exit_length,
    )
    state = state.update_validator(
        validator_index,
        validator,
        state.validator_balances[validator_index] - whistleblower_reward,
    )

    return state
Пример #23
0
def get_initial_beacon_state(*, initial_validator_deposits: Sequence[Deposit],
                             genesis_time: Timestamp,
                             latest_eth1_data: Eth1Data,
                             genesis_slot: SlotNumber,
                             genesis_epoch: EpochNumber,
                             genesis_fork_version: int,
                             genesis_start_shard: ShardNumber,
                             shard_count: int, seed_lookahead: int,
                             latest_block_roots_length: int,
                             latest_index_roots_length: int, epoch_length: int,
                             max_deposit_amount: Gwei,
                             latest_penalized_exit_length: int,
                             latest_randao_mixes_length: int,
                             entry_exit_delay: int) -> BeaconState:
    state = BeaconState(
        # Misc
        slot=genesis_slot,
        genesis_time=genesis_time,
        fork=Fork(
            previous_version=genesis_fork_version,
            current_version=genesis_fork_version,
            epoch=genesis_epoch,
        ),

        # Validator registry
        validator_registry=(),
        validator_balances=(),
        validator_registry_update_epoch=genesis_epoch,
        validator_registry_exit_count=0,

        # Randomness and committees
        latest_randao_mixes=tuple(ZERO_HASH32
                                  for _ in range(latest_randao_mixes_length)),
        previous_epoch_start_shard=genesis_start_shard,
        current_epoch_start_shard=genesis_start_shard,
        previous_calculation_epoch=genesis_epoch,
        current_calculation_epoch=genesis_epoch,
        previous_epoch_seed=ZERO_HASH32,
        current_epoch_seed=ZERO_HASH32,

        # Finality
        previous_justified_epoch=genesis_epoch,
        justified_epoch=genesis_epoch,
        justification_bitfield=0,
        finalized_epoch=genesis_epoch,

        # Recent state
        latest_crosslinks=tuple([
            CrosslinkRecord(epoch=genesis_epoch, shard_block_root=ZERO_HASH32)
            for _ in range(shard_count)
        ]),
        latest_block_roots=tuple(ZERO_HASH32
                                 for _ in range(latest_block_roots_length)),
        latest_index_roots=tuple(ZERO_HASH32
                                 for _ in range(latest_index_roots_length)),
        latest_penalized_balances=tuple(
            Gwei(0) for _ in range(latest_penalized_exit_length)),
        latest_attestations=(),
        batched_block_roots=(),

        # Ethereum 1.0 chain data
        latest_eth1_data=latest_eth1_data,
        eth1_data_votes=(),
    )

    # Process initial deposits
    for deposit in initial_validator_deposits:
        state = process_deposit(
            state=state,
            pubkey=deposit.deposit_data.deposit_input.pubkey,
            amount=deposit.deposit_data.amount,
            proof_of_possession=deposit.deposit_data.deposit_input.
            proof_of_possession,
            withdrawal_credentials=deposit.deposit_data.deposit_input.
            withdrawal_credentials,
            randao_commitment=deposit.deposit_data.deposit_input.
            randao_commitment,
            epoch_length=epoch_length,
        )

    # Process initial activations
    for validator_index, _ in enumerate(state.validator_registry):
        validator_index = ValidatorIndex(validator_index)
        is_enough_effective_balance = get_effective_balance(
            state.validator_balances,
            validator_index,
            max_deposit_amount,
        ) >= max_deposit_amount
        if is_enough_effective_balance:
            state = activate_validator(
                state=state,
                index=validator_index,
                is_genesis=True,
                genesis_epoch=genesis_epoch,
                epoch_length=epoch_length,
                entry_exit_delay=entry_exit_delay,
            )

    # TODO: chanege to hash_tree_root
    active_validator_indices = get_active_validator_indices(
        state.validator_registry,
        genesis_epoch,
    )
    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,
        genesis_epoch % latest_index_roots_length,
        index_root,
    )
    state = state.copy(latest_index_roots=latest_index_roots, )

    current_epoch_seed = generate_seed(
        state=state,
        epoch=genesis_epoch,
        epoch_length=epoch_length,
        seed_lookahead=seed_lookahead,
        entry_exit_delay=entry_exit_delay,
        latest_index_roots_length=latest_index_roots_length,
        latest_randao_mixes_length=latest_randao_mixes_length,
    )
    state = state.copy(current_epoch_seed=current_epoch_seed, )

    return state
Пример #24
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)
    )