示例#1
0
def test_get_committee_assignment(
    genesis_state,
    slots_per_epoch,
    max_committees_per_slot,
    config,
    validator_count,
    state_epoch,
    epoch,
):
    state_slot = compute_start_slot_at_epoch(state_epoch, slots_per_epoch)
    state = genesis_state.set("slot", state_slot)
    committee_validator_count = [0 for _ in range(max_committees_per_slot)]
    slots = []

    epoch_start_slot = compute_start_slot_at_epoch(epoch, slots_per_epoch)

    for validator_index in range(validator_count):
        assignment = get_committee_assignment(state, config, epoch,
                                              validator_index)
        assert assignment.slot >= epoch_start_slot
        assert assignment.slot < epoch_start_slot + slots_per_epoch

        committee_validator_count[assignment.committee_index] += 1
        slots.append(assignment.slot)

    assert sum(committee_validator_count) == validator_count
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)
def test_validate_attestation_data(
    genesis_state,
    sample_attestation_data_params,
    attestation_source_epoch,
    attestation_target_epoch,
    current_epoch,
    previous_justified_epoch,
    current_justified_epoch,
    slots_per_epoch,
    config,
    is_valid,
):
    state = genesis_state.copy(
        slot=compute_start_slot_at_epoch(current_epoch, slots_per_epoch) + 5,
        previous_justified_checkpoint=Checkpoint(
            epoch=previous_justified_epoch),
        current_justified_checkpoint=Checkpoint(epoch=current_justified_epoch),
    )
    target_slot = compute_start_slot_at_epoch(current_epoch,
                                              config.SLOTS_PER_EPOCH)
    committee_index = 0

    attestation_data = AttestationData(**sample_attestation_data_params).copy(
        slot=target_slot,
        index=committee_index,
        source=Checkpoint(epoch=attestation_source_epoch),
        target=Checkpoint(epoch=attestation_target_epoch),
    )

    if is_valid:
        _validate_attestation_data(state, attestation_data, config)
    else:
        with pytest.raises(ValidationError):
            _validate_attestation_data(state, attestation_data, config)
def test_randao_reveal_validation(
    is_valid,
    epoch,
    expected_epoch,
    proposer_key_index,
    expected_proposer_key_index,
    privkeys,
    pubkeys,
    sample_fork_params,
    genesis_state,
    config,
):
    state = genesis_state.set(
        "slot", compute_start_slot_at_epoch(epoch, config.SLOTS_PER_EPOCH))
    slots_per_epoch = config.SLOTS_PER_EPOCH
    domain = get_domain(state, SignatureDomain.DOMAIN_RANDAO, slots_per_epoch)
    signing_root = compute_signing_root(SerializableUint64(epoch), domain)

    proposer_privkey = privkeys[proposer_key_index]
    randao_reveal = bls.sign(proposer_privkey, signing_root)

    try:
        validate_randao_reveal(
            state=state,
            proposer_index=expected_proposer_key_index,
            epoch=expected_epoch,
            randao_reveal=randao_reveal,
            slots_per_epoch=slots_per_epoch,
        )
    except ValidationError:
        if is_valid:
            raise
    else:
        if not is_valid:
            pytest.fail("Did not raise")
示例#5
0
async def validate_peer_status(chain: BaseBeaconChain,
                               peer_status: Status) -> None:
    state_machine = chain.get_state_machine()
    state = chain.get_head_state()
    config = state_machine.config
    if peer_status.head_fork_version != state.fork.current_version:
        raise IrrelevantNetwork(
            "`fork_version` mismatches: "
            f"peer_status.head_fork_version={peer_status.head_fork_version}, "
            f"state.fork.current_version={state.fork.current_version}")

    # Can not validate the checkpoint with `finalized_epoch` higher than ours
    if peer_status.finalized_epoch > state.finalized_checkpoint.epoch:
        return

    # Edge case where nothing is finalized yet
    if (peer_status.finalized_epoch == 0
            and peer_status.finalized_root == ZERO_ROOT):
        return

    finalized_epoch_start_slot = compute_start_slot_at_epoch(
        peer_status.finalized_epoch,
        config.SLOTS_PER_EPOCH,
    )
    finalized_root = chain.get_canonical_block_root(finalized_epoch_start_slot)

    if peer_status.finalized_root != finalized_root:
        raise IrrelevantNetwork(
            "`finalized_root` mismatches: "
            f"peer_status.finalized_root={peer_status.finalized_root.hex()}, "
            f"peer_status.finalized_epoch={peer_status.finalized_epoch}, "
            f"our `finalized_root` at the same `finalized_epoch`={finalized_root.hex()}"
        )
def test_get_matching_target_attestations(genesis_state, config):
    some_epoch = GENESIS_EPOCH + 20
    some_slot = compute_start_slot_at_epoch(some_epoch, config.SLOTS_PER_EPOCH)
    some_target_root = b"\x33" * 32
    target_attestations = tuple(
        PendingAttestation.create(
            data=AttestationData.create(target=Checkpoint.create(root=some_target_root))
        )
        for _ in range(3)
    )
    current_epoch_attestations = target_attestations + tuple(
        PendingAttestation.create(
            data=AttestationData.create(target=Checkpoint.create(root=b"\x44" * 32))
        )
        for _ in range(3)
    )
    state = genesis_state.transform(
        ["slot"],
        some_slot + 1,
        ["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
示例#7
0
def create_mock_attester_slashing_is_surround_vote(
    state: BeaconState,
    config: Eth2Config,
    keymap: Dict[BLSPubkey, int],
    attestation_epoch: Epoch,
) -> AttesterSlashing:
    # target_epoch_2 < target_epoch_1
    attestation_slot_2 = compute_start_slot_at_epoch(attestation_epoch,
                                                     config.SLOTS_PER_EPOCH)
    attestation_slot_1 = Slot(attestation_slot_2 + config.SLOTS_PER_EPOCH)

    slashable_attestation_1 = create_mock_slashable_attestation(
        state.mset("slot", attestation_slot_1, "current_justified_epoch",
                   config.GENESIS_EPOCH),
        config,
        keymap,
        attestation_slot_1,
    )
    slashable_attestation_2 = create_mock_slashable_attestation(
        state.mset(
            "slot",
            attestation_slot_1,
            "current_justified_epoch",
            config.GENESIS_EPOCH + 1,  # source_epoch_1 < source_epoch_2
        ),
        config,
        keymap,
        attestation_slot_2,
    )

    return AttesterSlashing.create(attestation_1=slashable_attestation_1,
                                   attestation_2=slashable_attestation_2)
def test_process_slashings(
    genesis_state,
    config,
    current_epoch,
    slashings,
    slots_per_epoch,
    epochs_per_slashings_vector,
    expected_penalty,
):
    state = genesis_state.mset(
        "slot",
        compute_start_slot_at_epoch(current_epoch, slots_per_epoch),
        "slashings",
        slashings,
    )
    slashing_validator_index = 0
    validator = state.validators[slashing_validator_index].mset(
        "slashed",
        True,
        "withdrawable_epoch",
        current_epoch + epochs_per_slashings_vector // 2,
    )
    state = state.transform(["validators", slashing_validator_index],
                            validator)

    result_state = process_slashings(state, config)
    penalty = (state.balances[slashing_validator_index] -
               result_state.balances[slashing_validator_index])
    assert penalty == expected_penalty
def test_validate_eligible_exit_epoch(
    genesis_state,
    keymap,
    current_epoch,
    voluntary_exit_epoch,
    slots_per_epoch,
    config,
    success,
):
    state = genesis_state.set(
        "slot", compute_start_slot_at_epoch(current_epoch, slots_per_epoch))

    validator_index = 0
    signed_voluntary_exit = create_mock_voluntary_exit(
        state,
        config,
        keymap,
        validator_index,
        exit_epoch=voluntary_exit_epoch)
    voluntary_exit = signed_voluntary_exit.message
    if success:
        _validate_eligible_exit_epoch(voluntary_exit.epoch,
                                      state.current_epoch(slots_per_epoch))
    else:
        with pytest.raises(ValidationError):
            _validate_eligible_exit_epoch(voluntary_exit.epoch,
                                          state.current_epoch(slots_per_epoch))
示例#10
0
def test_process_slashings(
    genesis_state,
    config,
    current_epoch,
    slashings,
    slots_per_epoch,
    epochs_per_slashings_vector,
    expected_penalty,
):
    state = genesis_state.copy(
        slot=compute_start_slot_at_epoch(current_epoch, slots_per_epoch),
        slashings=slashings,
    )
    slashing_validator_index = 0
    validator = state.validators[slashing_validator_index].copy(
        slashed=True,
        withdrawable_epoch=current_epoch + epochs_per_slashings_vector // 2,
    )
    state = state.update_validator(slashing_validator_index, validator)

    result_state = process_slashings(state, config)
    penalty = (
        state.balances[slashing_validator_index]
        - result_state.balances[slashing_validator_index]
    )
    assert penalty == expected_penalty
示例#11
0
文件: lmd_ghost.py 项目: veox/trinity
    def _should_update_justified_checkpoint(
            self, new_justified_checkpoint: Checkpoint) -> bool:
        """
        To address the bouncing attack, only update conflicting justified
        checkpoints in the fork choice if in the early slots of the epoch.
        Otherwise, delay incorporation of new justified checkpoint until next epoch boundary.
        See https://ethresear.ch/t/prevention-of-bouncing-attack-on-ffg/6114 for more
        detailed analysis and discussion.
        """
        current_slot = self.get_current_slot()
        slots_since_epoch_start = compute_slots_since_epoch_start(
            current_slot, self._config.SLOTS_PER_EPOCH)
        within_safe_slots = (slots_since_epoch_start <
                             self._config.SAFE_SLOTS_TO_UPDATE_JUSTIFIED)
        if within_safe_slots:
            return True

        new_justified_block = self._context.blocks[
            new_justified_checkpoint.root]
        justified_epoch = self._context.justified_checkpoint.epoch
        if new_justified_block.slot <= compute_start_slot_at_epoch(
                justified_epoch, self._config.SLOTS_PER_EPOCH):
            return False

        justified_root = self._context.justified_checkpoint.root
        justified_ancestor = self.get_ancestor_root(
            new_justified_checkpoint.root, self._context.justified_slot)
        return justified_ancestor == justified_root
示例#12
0
文件: lmd_ghost.py 项目: veox/trinity
    def on_block(
        self,
        block: BaseBeaconBlock,
        post_state: BeaconState = None,
        state_machine: BaseBeaconStateMachine = None,
    ) -> None:
        """
        Handler to update the fork choice context upon receiving a new ``block``.

        This handler requests the ``post_state`` of this block to avoid recomputing
        it if it is already known.
        """
        # NOTE: this invariant should hold based on how we handle
        # block importing in the chain but we will sanity check for now
        assert block.parent_root in self._context.block_states

        pre_state = self._context.block_states[block.parent_root]

        # NOTE: this invariant should hold based on how we handle
        # block importing in the chain but we will sanity check for now
        assert (self._context.time >= pre_state.genesis_time +
                block.slot * self._config.SECONDS_PER_SLOT)

        root = block.signing_root

        self._context.blocks[root] = block

        finalized_slot = self._context.finalized_slot
        finalized_ancestor = self.get_ancestor_root(root, finalized_slot)
        is_ancestor_of_finalized_block = (
            finalized_ancestor == self._context.finalized_checkpoint.root)
        if not is_ancestor_of_finalized_block:
            raise ValidationError(
                f"block with signing root {root.hex()} is not a descendant of the finalized"
                f" checkpoint with root {finalized_ancestor.hex()}")

        # NOTE: sanity check implied by the previous verification on finalized ancestor
        assert block.slot > compute_start_slot_at_epoch(
            self._context.finalized_checkpoint.epoch,
            self._config.SLOTS_PER_EPOCH)

        if not post_state:
            # NOTE: error to not provide a post_state and not provide a way to compute it
            assert state_machine is not None
            post_state, _ = state_machine.import_block(block, pre_state)

        self._context.block_states[root] = post_state

        if (post_state.current_justified_checkpoint.epoch >
                self._context.justified_checkpoint.epoch):
            self._context.best_justified_checkpoint = (
                post_state.current_justified_checkpoint)
            if self._should_update_justified_checkpoint(
                    post_state.current_justified_checkpoint):
                self._context.justified_checkpoint = (
                    post_state.current_justified_checkpoint)

        if (post_state.finalized_checkpoint.epoch >
                self._context.finalized_checkpoint.epoch):
            self._context.finalized_checkpoint = post_state.finalized_checkpoint
def test_get_matching_head_attestations(genesis_state, config):
    some_epoch = config.GENESIS_EPOCH + 20
    some_slot = (
        compute_start_slot_at_epoch(some_epoch, config.SLOTS_PER_EPOCH) +
        config.SLOTS_PER_EPOCH // 4)
    some_target_root = b"\x33" * 32
    target_attestations = tuple(
        (PendingAttestation.create(data=AttestationData.create(
            slot=some_slot - 1,
            index=0,
            beacon_block_root=some_target_root,
            target=Checkpoint.create(epoch=some_epoch - 1),
        )) for i in range(3)))
    current_epoch_attestations = target_attestations + tuple(
        (PendingAttestation.create(data=AttestationData.create(
            beacon_block_root=b"\x44" * 32,
            target=Checkpoint.create(epoch=some_epoch - 1),
        )) for _ in range(3)))
    state = genesis_state.mset(
        "slot",
        some_slot,
        "block_roots",
        tuple(some_target_root
              for _ in range(config.SLOTS_PER_HISTORICAL_ROOT)),
        "current_epoch_attestations",
        current_epoch_attestations,
    )

    attestations = get_matching_head_attestations(state, some_epoch, config)

    assert attestations == target_attestations
def test_validate_validator_minimum_lifespan(
    genesis_state,
    keymap,
    current_epoch,
    activation_epoch,
    slots_per_epoch,
    persistent_committee_period,
    success,
):
    state = genesis_state.copy(
        slot=compute_start_slot_at_epoch(current_epoch, slots_per_epoch))
    validator_index = 0
    validator = state.validators[validator_index].copy(
        activation_epoch=activation_epoch)
    state = state.update_validator(validator_index, validator)

    if success:
        _validate_validator_minimum_lifespan(
            validator, state.current_epoch(slots_per_epoch),
            persistent_committee_period)
    else:
        with pytest.raises(ValidationError):
            _validate_validator_minimum_lifespan(
                validator,
                state.current_epoch(slots_per_epoch),
                persistent_committee_period,
            )
def test_get_matching_source_attestations(genesis_state, current_epoch,
                                          target_epoch, success, config):
    state = genesis_state.mset(
        "slot",
        compute_start_slot_at_epoch(current_epoch, config.SLOTS_PER_EPOCH),
        "current_epoch_attestations",
        (PendingAttestation.create(data=AttestationData.create(
            beacon_block_root=current_epoch.to_bytes(32, "little"))), ),
        "previous_epoch_attestations",
        (PendingAttestation.create(data=AttestationData.create(
            beacon_block_root=(current_epoch - 1).to_bytes(32, "little"))), ),
    )

    if success:
        attestations = get_matching_source_attestations(
            state, target_epoch, config)
    else:
        with pytest.raises(InvalidEpochError):
            get_matching_source_attestations(state, target_epoch, config)
        return

    if current_epoch == target_epoch:
        assert attestations == state.current_epoch_attestations
    else:
        assert attestations == state.previous_epoch_attestations
示例#16
0
def compute_slots_since_epoch_start(slot: Slot, slots_per_epoch: int) -> Slot:
    return Slot(
        slot
        - compute_start_slot_at_epoch(
            compute_epoch_at_slot(slot, slots_per_epoch), slots_per_epoch
        )
    )
def test_validate_validator_minimum_lifespan(
    genesis_state,
    keymap,
    current_epoch,
    activation_epoch,
    slots_per_epoch,
    persistent_committee_period,
    success,
):
    state = genesis_state.set(
        "slot", compute_start_slot_at_epoch(current_epoch, slots_per_epoch))
    validator_index = 0
    validator = state.validators[validator_index].set("activation_epoch",
                                                      activation_epoch)
    state = state.transform(["validators", validator_index], validator)

    if success:
        _validate_validator_minimum_lifespan(
            validator, state.current_epoch(slots_per_epoch),
            persistent_committee_period)
    else:
        with pytest.raises(ValidationError):
            _validate_validator_minimum_lifespan(
                validator,
                state.current_epoch(slots_per_epoch),
                persistent_committee_period,
            )
def test_validate_voluntary_exit(genesis_state, keymap, slots_per_epoch,
                                 persistent_committee_period, config):
    state = genesis_state.copy(slot=compute_start_slot_at_epoch(
        config.GENESIS_EPOCH + persistent_committee_period, slots_per_epoch))
    validator_index = 0
    valid_voluntary_exit = create_mock_voluntary_exit(state, config, keymap,
                                                      validator_index)
    validate_voluntary_exit(state, valid_voluntary_exit, slots_per_epoch,
                            persistent_committee_period)
示例#19
0
def _get_target_checkpoint(state: BeaconState, head_root: Root,
                           config: Eth2Config) -> Checkpoint:
    epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    start_slot = compute_start_slot_at_epoch(epoch, config.SLOTS_PER_EPOCH)
    if start_slot == state.slot:
        root = head_root
    else:
        root = get_block_root_at_slot(state, start_slot,
                                      config.SLOTS_PER_HISTORICAL_ROOT)
    return Checkpoint.create(epoch=epoch, root=root)
示例#20
0
def _get_target_root(state: BeaconState, config: Eth2Config,
                     beacon_block_root: Root) -> Root:

    epoch = compute_epoch_at_slot(state.slot, config.SLOTS_PER_EPOCH)
    epoch_start_slot = compute_start_slot_at_epoch(epoch,
                                                   config.SLOTS_PER_EPOCH)
    if epoch_start_slot == state.slot:
        return beacon_block_root
    else:
        return get_block_root(state, epoch, config.SLOTS_PER_EPOCH,
                              config.SLOTS_PER_HISTORICAL_ROOT)
示例#21
0
def validate_start_slot(chain: BaseBeaconChain, start_slot: Slot) -> None:
    config = chain.get_state_machine().config
    state = chain.get_head_state()
    finalized_epoch_start_slot = compute_start_slot_at_epoch(
        epoch=state.finalized_checkpoint.epoch,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
    )
    if start_slot < finalized_epoch_start_slot:
        raise ValidationError(
            f"`start_slot`({start_slot}) lower than our"
            f" latest finalized slot({finalized_epoch_start_slot})")
示例#22
0
def test_validate_voluntary_exit(genesis_state, keymap, slots_per_epoch,
                                 shard_committee_period, config):
    state = genesis_state.set(
        "slot",
        compute_start_slot_at_epoch(GENESIS_EPOCH + shard_committee_period,
                                    slots_per_epoch),
    )
    validator_index = 0
    valid_voluntary_exit = create_mock_voluntary_exit(state, config, keymap,
                                                      validator_index)
    validate_voluntary_exit(state, valid_voluntary_exit, slots_per_epoch,
                            shard_committee_period)
def test_process_voluntary_exits(
    genesis_state,
    sample_beacon_block_params,
    sample_beacon_block_body_params,
    config,
    keymap,
    success,
):
    state = genesis_state.copy(
        slot=compute_start_slot_at_epoch(
            config.GENESIS_EPOCH + config.PERSISTENT_COMMITTEE_PERIOD,
            config.SLOTS_PER_EPOCH,
        )
    )
    validator_index = 0
    validator = state.validators[validator_index].copy(
        activation_epoch=config.GENESIS_EPOCH
    )
    state = state.update_validator(validator_index, validator)
    valid_voluntary_exit = create_mock_voluntary_exit(
        state, config, keymap, validator_index
    )

    if success:
        block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
            voluntary_exits=(valid_voluntary_exit,)
        )
        block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
            slot=state.slot, body=block_body
        )

        new_state = process_voluntary_exits(state, block, config)
        updated_validator = new_state.validators[validator_index]
        assert updated_validator.exit_epoch != FAR_FUTURE_EPOCH
        assert updated_validator.exit_epoch > state.current_epoch(
            config.SLOTS_PER_EPOCH
        )
        assert updated_validator.withdrawable_epoch == (
            updated_validator.exit_epoch + config.MIN_VALIDATOR_WITHDRAWABILITY_DELAY
        )
    else:
        invalid_voluntary_exit = valid_voluntary_exit.copy(
            signature=b"\x12" * 96  # Put wrong signature
        )
        block_body = BeaconBlockBody(**sample_beacon_block_body_params).copy(
            voluntary_exits=(invalid_voluntary_exit,)
        )
        block = SerenityBeaconBlock(**sample_beacon_block_params).copy(
            slot=state.slot, body=block_body
        )

        with pytest.raises(ValidationError):
            process_voluntary_exits(state, block, config)
示例#24
0
 def _determine_sync_requests(self, peer_id: PeerID,
                              status: Status) -> Iterable[SyncRequest]:
     """
     If the peer has a higher finalized epoch or head slot, sync blocks from them.
     """
     head_state = self._chain.get_canonical_head_state()
     finalized_slot = compute_start_slot_at_epoch(
         head_state.finalized_checkpoint.epoch,
         self._eth2_config.SLOTS_PER_EPOCH)
     while finalized_slot < status.head_slot:
         count = min(status.head_slot - finalized_slot, MAX_REQUEST_BLOCKS)
         yield SyncRequest(peer_id, Slot(finalized_slot + 1), count)
         finalized_slot += count
def test_validate_attestation_data(
    genesis_state,
    sample_attestation_data_params,
    attestation_source_epoch,
    attestation_target_epoch,
    current_epoch,
    previous_justified_epoch,
    current_justified_epoch,
    slots_per_epoch,
    config,
    is_valid,
):
    state = genesis_state.mset(
        "slot",
        compute_start_slot_at_epoch(current_epoch, slots_per_epoch) + 5,
        "previous_justified_checkpoint",
        Checkpoint.create(epoch=previous_justified_epoch),
        "current_justified_checkpoint",
        Checkpoint.create(epoch=current_justified_epoch),
    )
    target_slot = compute_start_slot_at_epoch(current_epoch, config.SLOTS_PER_EPOCH)
    committee_index = 0

    attestation_data = AttestationData.create(**sample_attestation_data_params).mset(
        "slot",
        target_slot,
        "index",
        committee_index,
        "source",
        Checkpoint.create(epoch=attestation_source_epoch),
        "target",
        Checkpoint.create(epoch=attestation_target_epoch),
    )

    if is_valid:
        _validate_attestation_data(state, attestation_data, config)
    else:
        with pytest.raises(ValidationError):
            _validate_attestation_data(state, attestation_data, config)
def test_get_unslashed_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, CommitteeConfig(config)
    )

    data = AttestationData.create(
        slot=state.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:
            if random.choice([True, False]):
                state = state.transform(["validators", index, "slashed"], True)
            bitfield = set_voted(bitfield, i)

    some_subset = tuple(
        filter(lambda index: not state.validators[index].slashed, some_subset)
    )

    indices = get_unslashed_attesting_indices(
        state,
        (PendingAttestation.create(data=data, aggregation_bits=bitfield),),
        CommitteeConfig(config),
    )

    assert set(indices) == set(some_subset)
    assert len(indices) == len(some_subset)
示例#27
0
 def _determine_sync_request(self, peer_id: PeerID,
                             status: Status) -> Optional[SyncRequest]:
     """
     If the peer has a higher finalized epoch or head slot, sync blocks from them.
     """
     head_state = self._chain.get_canonical_head_state()
     finalized_slot = compute_start_slot_at_epoch(
         head_state.finalized_checkpoint.epoch,
         self._eth2_config.SLOTS_PER_EPOCH)
     if finalized_slot < status.head_slot:
         span = status.head_slot - finalized_slot
         return SyncRequest(peer_id, Slot(finalized_slot + 1), span)
     else:
         return None
示例#28
0
def _get_slot_with_validator_selected(candidate_indices, state, config):
    epoch = state.current_epoch(config.SLOTS_PER_EPOCH)
    epoch_start_slot = compute_start_slot_at_epoch(epoch, config.SLOTS_PER_EPOCH)

    for index in candidate_indices:
        try:
            for slot in range(epoch_start_slot, epoch_start_slot + config.SLOTS_PER_EPOCH):
                state = state.copy(slot=slot)
                if is_proposer(state, index, config):
                    return slot, index
        except NoCommitteeAssignment:
            continue
    raise Exception(
        "Check the parameters of the genesis state; the above code should return"
        " some proposer if the set of ``candidate_indices`` is big enough."
    )
示例#29
0
def create_mock_attester_slashing_is_double_vote(
    state: BeaconState,
    config: Eth2Config,
    keymap: Dict[BLSPubkey, int],
    attestation_epoch: Epoch,
) -> AttesterSlashing:
    attestation_slot_1 = compute_start_slot_at_epoch(attestation_epoch,
                                                     config.SLOTS_PER_EPOCH)
    attestation_slot_2 = Slot(attestation_slot_1 + 1)

    slashable_attestation_1 = create_mock_slashable_attestation(
        state, config, keymap, attestation_slot_1)
    slashable_attestation_2 = create_mock_slashable_attestation(
        state, config, keymap, attestation_slot_2)

    return AttesterSlashing.create(attestation_1=slashable_attestation_1,
                                   attestation_2=slashable_attestation_2)
示例#30
0
    def _get_finalized_root_by_epoch(self, epoch: Epoch) -> Optional[Root]:
        slots_per_epoch = self._eth2_config.SLOTS_PER_EPOCH
        head_state = self._chain.get_head_state()
        finalized_checkpoint = head_state.finalized_checkpoint

        if epoch > finalized_checkpoint.epoch:
            return None

        if epoch == finalized_checkpoint.epoch:
            return finalized_checkpoint.root

        # NOTE: get a historical finalized root
        # This root will be the block at the start slot of the ``epoch``
        # in our canonical chain as implied by having a more recent
        # finalized head.
        slot = compute_start_slot_at_epoch(epoch, slots_per_epoch)
        return self._chain.get_canonical_block_root(slot)