def test_get_attesting_indices(genesis_state, config):
    state = genesis_state.set(
        "slot", compute_start_slot_at_epoch(3, config.SLOTS_PER_EPOCH))
    target_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    target_slot = compute_start_slot_at_epoch(target_epoch,
                                              config.SLOTS_PER_EPOCH)
    committee_index = 0
    some_committee = get_beacon_committee(state, target_slot, committee_index,
                                          config)

    data = AttestationData.create(
        slot=target_slot,
        index=committee_index,
        target=Checkpoint.create(epoch=target_epoch),
    )
    some_subset_count = random.randrange(1, len(some_committee) // 2)
    some_subset = random.sample(some_committee, some_subset_count)

    bitfield = get_empty_bitfield(len(some_committee))
    for i, index in enumerate(some_committee):
        if index in some_subset:
            bitfield = set_voted(bitfield, i)

    indices = get_attesting_indices(state, data, bitfield, config)

    assert set(indices) == set(some_subset)
    assert len(indices) == len(some_subset)
예제 #2
0
def test_get_attesting_indices(genesis_state, config):
    state = genesis_state.copy(
        slot=get_epoch_start_slot(3, config.SLOTS_PER_EPOCH))
    target_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    target_shard = (state.start_shard + 3) % config.SHARD_COUNT
    some_committee = get_crosslink_committee(
        state,
        target_epoch,
        target_shard,
        CommitteeConfig(config),
    )

    data = AttestationData(
        target_epoch=target_epoch,
        crosslink=Crosslink(shard=target_shard, ),
    )
    some_subset_count = random.randint(1, len(some_committee) // 2)
    some_subset = random.sample(some_committee, some_subset_count)

    bitfield = get_empty_bitfield(len(some_committee))
    for i, index in enumerate(some_committee):
        if index in some_subset:
            bitfield = set_voted(bitfield, i)

    indices = get_attesting_indices(
        state,
        data,
        bitfield,
        CommitteeConfig(config),
    )

    assert set(indices) == set(some_subset)
    assert len(indices) == len(some_subset)
예제 #3
0
def _iter_attestation_by_validator_index(state, attestation, config):
    for index in get_attesting_indices(
            state,
            attestation.data,
            attestation.aggregation_bits,
            config,
    ):
        yield index
예제 #4
0
파일: altona.py 프로젝트: gengmoqi/trinity
 def _get_indices_from_attestation(
         self, attestation: Attestation) -> Collection[ValidatorIndex]:
     target_block = self._chain_db.get_block_by_root(
         attestation.data.target.root, BeaconBlock)
     try:
         target_state = self._chain_db.get_state_by_root(
             target_block.state_root, BeaconState)
     except StateNotFound:
         target_state = self._compute_missing_state(target_block)
     sm = self.get_state_machine(target_block.slot)
     return get_attesting_indices(target_state, attestation.data,
                                  attestation.aggregation_bits, sm.config)
예제 #5
0
    def _mk_pre_index_from_attestation(
            self, state: BeaconState,
            attestation: AttestationLike) -> Iterable[PreIndex]:
        attestation_data = attestation.data
        slot = get_attestation_data_slot(state, attestation_data, self._config)

        return ({
            index: (slot, attestation_data)
        } for index in get_attesting_indices(
            state,
            attestation.data,
            attestation.aggregation_bits,
            CommitteeConfig(self._config),
        ))
예제 #6
0
def validate_aggregate_and_proof(
    state: BeaconState,
    aggregate_and_proof: AggregateAndProof,
    attestation_propagation_slot_range: int,
    config: Eth2Config,
) -> None:
    """
    Validate aggregate_and_proof

    Reference: https://github.com/ethereum/eth2.0-specs/blob/master/specs/networking/p2p-interface.md#global-topics  # noqa: E501
    """
    attestation = aggregate_and_proof.aggregate

    validate_attestation_propagation_slot_range(
        state, attestation, attestation_propagation_slot_range
    )

    attesting_indices = get_attesting_indices(
        state, attestation.data, attestation.aggregation_bits, config
    )
    if aggregate_and_proof.aggregator_index not in attesting_indices:
        raise ValidationError(
            f"The aggregator index ({aggregate_and_proof.aggregator_index}) is not within"
            f" the aggregate's committee {attesting_indices}"
        )

    if not is_aggregator(
        state,
        attestation.data.slot,
        attestation.data.index,
        aggregate_and_proof.selection_proof,
        config,
    ):
        raise ValidationError(
            f"The given validator {aggregate_and_proof.aggregator_index}"
            " is not a selected aggregator"
        )

    validate_aggregator_proof(state, aggregate_and_proof, config)

    validate_attestation_signature(state, attestation, config)
예제 #7
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),
    )
예제 #8
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
    )