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
Ejemplo n.º 2
0
def sample_attestation_data_params(sample_crosslink_record_params):
    return {
        "beacon_block_root": b"\x11" * 32,
        "source": Checkpoint(epoch=11, root=b"\x22" * 32),
        "target": Checkpoint(epoch=12, root=b"\x33" * 32),
        "crosslink": Crosslink(**sample_crosslink_record_params),
    }
Ejemplo n.º 3
0
def test_get_matching_head_attestations(genesis_state, config):
    some_epoch = config.GENESIS_EPOCH + 20
    some_slot = (
        compute_start_slot_of_epoch(some_epoch, config.SLOTS_PER_EPOCH) +
        config.SLOTS_PER_EPOCH // 4)
    some_target_root = b"\x33" * 32
    target_attestations = tuple((PendingAttestation(data=AttestationData(
        beacon_block_root=some_target_root,
        target=Checkpoint(epoch=some_epoch - 1),
        crosslink=Crosslink(shard=i),
    )) for i in range(3)))
    current_epoch_attestations = target_attestations + tuple(
        (PendingAttestation(data=AttestationData(
            beacon_block_root=b"\x44" * 32,
            target=Checkpoint(epoch=some_epoch - 1),
        )) for _ in range(3)))
    state = genesis_state.copy(
        slot=some_slot - 1,
        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_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
Ejemplo n.º 5
0
def sample_beacon_state_params(
    config,
    genesis_slot,
    genesis_epoch,
    sample_fork_params,
    sample_eth1_data_params,
    sample_block_header_params,
    sample_crosslink_record_params,
):
    return {
        # Versioning
        "genesis_time":
        0,
        "slot":
        genesis_slot + 100,
        "fork":
        Fork(**sample_fork_params),
        # History
        "latest_block_header":
        BeaconBlockHeader(**sample_block_header_params),
        "block_roots": (ZERO_HASH32, ) * config.SLOTS_PER_HISTORICAL_ROOT,
        "state_roots": (ZERO_HASH32, ) * config.SLOTS_PER_HISTORICAL_ROOT,
        "historical_roots": (),
        # Eth1
        "eth1_data":
        Eth1Data(**sample_eth1_data_params),
        "eth1_data_votes": (),
        "eth1_deposit_index":
        0,
        # Registry
        "validators": (),
        "balances": (),
        # Shuffling
        "start_shard":
        1,
        "randao_mixes": (ZERO_HASH32, ) * config.EPOCHS_PER_HISTORICAL_VECTOR,
        "active_index_roots":
        (ZERO_HASH32, ) * config.EPOCHS_PER_HISTORICAL_VECTOR,
        "compact_committees_roots":
        (ZERO_HASH32, ) * config.EPOCHS_PER_HISTORICAL_VECTOR,
        # Slashings
        "slashings": (0, ) * config.EPOCHS_PER_SLASHINGS_VECTOR,
        # Attestations
        "previous_epoch_attestations": (),
        "current_epoch_attestations": (),
        # Crosslinks
        "previous_crosslinks":
        ((Crosslink(**sample_crosslink_record_params), ) * config.SHARD_COUNT),
        "current_crosslinks":
        ((Crosslink(**sample_crosslink_record_params), ) * config.SHARD_COUNT),
        # Justification
        "justification_bits": (False, ) * JUSTIFICATION_BITS_LENGTH,
        "previous_justified_checkpoint":
        Checkpoint(epoch=0, root=b"\x99" * 32),
        "current_justified_checkpoint":
        Checkpoint(epoch=0, root=b"\x55" * 32),
        # Finality
        "finalized_checkpoint":
        Checkpoint(epoch=0, root=b"\x33" * 32),
    }
Ejemplo n.º 6
0
def test_chaindb_get_justified_head(
    chaindb_at_genesis,
    genesis_block,
    genesis_state,
    sample_beacon_block_params,
    fork_choice_scoring,
    config,
):
    chaindb = chaindb_at_genesis
    block = BeaconBlock(**sample_beacon_block_params).copy(
        parent_root=genesis_block.signing_root)

    assert chaindb.get_finalized_head(genesis_block.__class__) == genesis_block
    assert chaindb.get_justified_head(genesis_block.__class__) == genesis_block

    # test that there is only one justified head per epoch
    state_with_bad_epoch = genesis_state.copy(
        current_justified_checkpoint=Checkpoint(root=block.signing_root,
                                                epoch=config.GENESIS_EPOCH))
    chaindb.persist_state(state_with_bad_epoch)
    chaindb.persist_block(block, BeaconBlock, fork_choice_scoring)

    assert chaindb.get_finalized_head(genesis_block.__class__) == genesis_block
    assert chaindb.get_justified_head(genesis_block.__class__) == genesis_block

    # test that the we can update justified head if we satisfy the invariants
    state_with_justified_block = genesis_state.copy(
        current_justified_checkpoint=Checkpoint(
            root=block.signing_root, epoch=config.GENESIS_EPOCH + 1))
    chaindb.persist_state(state_with_justified_block)

    assert chaindb.get_finalized_head(genesis_block.__class__) == genesis_block
    assert chaindb.get_justified_head(
        BeaconBlock).signing_root == block.signing_root
Ejemplo n.º 7
0
def create_mock_slashable_attestation(
    state: BeaconState,
    config: Eth2Config,
    keymap: Dict[BLSPubkey, int],
    attestation_slot: Slot,
) -> IndexedAttestation:
    """
    Create an `IndexedAttestation` that is signed by one attester.
    """
    attester_index = ValidatorIndex(0)
    committee = (attester_index, )
    shard = Shard(0)

    # Use genesis block root as `beacon_block_root`, only for tests.
    beacon_block_root = get_block_root_at_slot(
        state, attestation_slot, config.SLOTS_PER_HISTORICAL_ROOT)

    # Get `target_root`
    target_root = _get_target_root(state, config, beacon_block_root)
    # Get `source_root`
    source_root = get_block_root_at_slot(
        state,
        compute_start_slot_of_epoch(state.current_justified_checkpoint.epoch,
                                    config.SLOTS_PER_EPOCH),
        config.SLOTS_PER_HISTORICAL_ROOT,
    )
    previous_crosslink = state.current_crosslinks[shard]

    attestation_data = AttestationData(
        beacon_block_root=beacon_block_root,
        source=Checkpoint(epoch=state.current_justified_checkpoint.epoch,
                          root=source_root),
        target=Checkpoint(
            epoch=compute_epoch_of_slot(attestation_slot,
                                        config.SLOTS_PER_EPOCH),
            root=target_root,
        ),
        crosslink=previous_crosslink,
    )

    message_hash = _get_mock_message(attestation_data)
    attesting_indices = _get_mock_attesting_indices(committee,
                                                    num_voted_attesters=1)

    signature = sign_transaction(
        message_hash=message_hash,
        privkey=keymap[state.validators[attesting_indices[0]].pubkey],
        state=state,
        slot=attestation_slot,
        signature_domain=SignatureDomain.DOMAIN_ATTESTATION,
        slots_per_epoch=config.SLOTS_PER_EPOCH,
    )
    validator_indices = tuple(committee[i] for i in attesting_indices)

    return IndexedAttestation(
        custody_bit_0_indices=validator_indices,
        custody_bit_1_indices=tuple(),
        data=attestation_data,
        signature=signature,
    )
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)
Ejemplo n.º 9
0
def create_mock_signed_attestations_at_slot(
        state: BeaconState,
        config: Eth2Config,
        state_machine: BaseBeaconStateMachine,
        attestation_slot: Slot,
        beacon_block_root: Hash32,
        keymap: Dict[BLSPubkey, int],
        voted_attesters_ratio: float = 1.0) -> Iterable[Attestation]:
    """
    Create the mocking attestations of the given ``attestation_slot`` slot with ``keymap``.
    """
    crosslink_committees_at_slot = get_crosslink_committees_at_slot(
        state,
        attestation_slot,
        config,
    )

    # Get `target_root`
    target_root = _get_target_root(state, config, beacon_block_root)
    target_epoch = compute_epoch_of_slot(
        state.slot,
        config.SLOTS_PER_EPOCH,
    )

    for crosslink_committee in crosslink_committees_at_slot:
        committee, shard = crosslink_committee

        parent_crosslink = state.current_crosslinks[shard]

        attestation_data = AttestationData(
            beacon_block_root=beacon_block_root,
            source=Checkpoint(
                epoch=state.current_justified_checkpoint.epoch,
                root=state.current_justified_checkpoint.root,
            ),
            target=Checkpoint(
                root=target_root,
                epoch=target_epoch,
            ),
            crosslink=Crosslink(
                shard=shard,
                parent_root=parent_crosslink.hash_tree_root,
                start_epoch=parent_crosslink.end_epoch,
                end_epoch=min(
                    target_epoch, parent_crosslink.end_epoch +
                    config.MAX_EPOCHS_PER_CROSSLINK),
            ))

        num_voted_attesters = int(len(committee) * voted_attesters_ratio)

        yield _create_mock_signed_attestation(
            state,
            attestation_data,
            attestation_slot,
            committee,
            num_voted_attesters,
            keymap,
            config.SLOTS_PER_EPOCH,
        )
Ejemplo n.º 10
0
def sample_attestation_data_params():
    return {
        "slot": 5,
        "index": 1,
        "beacon_block_root": b"\x11" * 32,
        "source": Checkpoint.create(epoch=11, root=b"\x22" * 32),
        "target": Checkpoint.create(epoch=12, root=b"\x33" * 32),
    }
Ejemplo n.º 11
0
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_of_epoch(current_epoch, slots_per_epoch) + 5,
        previous_justified_checkpoint=Checkpoint(
            epoch=previous_justified_epoch,
        ),
        current_justified_checkpoint=Checkpoint(
            epoch=current_justified_epoch,
        ),
    )
    start_shard = get_start_shard(
        state,
        current_epoch,
        CommitteeConfig(config),
    )
    if attestation_target_epoch == current_epoch:
        crosslinks = state.current_crosslinks
    else:
        crosslinks = state.previous_crosslinks

    parent_crosslink = crosslinks[start_shard]
    attestation_data = AttestationData(**sample_attestation_data_params).copy(
        source=Checkpoint(
            epoch=attestation_source_epoch,
        ),
        target=Checkpoint(
            epoch=attestation_target_epoch,
        ),
        crosslink=Crosslink(
            start_epoch=parent_crosslink.end_epoch,
            end_epoch=attestation_target_epoch,
            parent_root=parent_crosslink.hash_tree_root,
            shard=start_shard,
        ),
    )

    if is_valid:
        _validate_attestation_data(
            state,
            attestation_data,
            config,
        )
    else:
        with pytest.raises(ValidationError):
            _validate_attestation_data(
                state,
                attestation_data,
                config,
            )
Ejemplo n.º 12
0
def create_signed_attestation_at_slot(state: BeaconState, config: Eth2Config,
                                      state_machine: BaseBeaconStateMachine,
                                      attestation_slot: Slot,
                                      beacon_block_root: Hash32,
                                      validator_privkeys: Dict[ValidatorIndex,
                                                               int],
                                      committee: Tuple[ValidatorIndex, ...],
                                      shard: Shard) -> Attestation:
    """
    Create the attestations of the given ``attestation_slot`` slot with ``validator_privkeys``.
    """
    state_transition = state_machine.state_transition
    state = state_transition.apply_state_transition(
        state,
        future_slot=attestation_slot,
    )

    target_epoch = compute_epoch_of_slot(
        attestation_slot,
        config.SLOTS_PER_EPOCH,
    )

    target_root = _get_target_root(state, config, beacon_block_root)

    parent_crosslink = state.current_crosslinks[shard]

    attestation_data = AttestationData(
        beacon_block_root=beacon_block_root,
        source=Checkpoint(
            epoch=state.current_justified_checkpoint.epoch,
            root=state.current_justified_checkpoint.root,
        ),
        target=Checkpoint(
            root=target_root,
            epoch=target_epoch,
        ),
        crosslink=Crosslink(
            shard=shard,
            parent_root=parent_crosslink.hash_tree_root,
            start_epoch=parent_crosslink.end_epoch,
            end_epoch=target_epoch,
        ))

    return _create_mock_signed_attestation(
        state,
        attestation_data,
        attestation_slot,
        committee,
        len(committee),
        keymapper(lambda index: state.validators[index].pubkey,
                  validator_privkeys),
        config.SLOTS_PER_EPOCH,
    )
Ejemplo n.º 13
0
def test_process_justification_and_finalization(
    genesis_state,
    current_epoch,
    current_epoch_justifiable,
    previous_epoch_justifiable,
    previous_justified_epoch,
    current_justified_epoch,
    justification_bits,
    finalized_epoch,
    justified_epoch_after,
    justification_bits_after,
    finalized_epoch_after,
    config,
):
    justification_bits = _convert_to_bitfield(justification_bits)
    justification_bits_after = _convert_to_bitfield(justification_bits_after)
    previous_epoch = max(current_epoch - 1, 0)
    slot = (current_epoch + 1) * config.SLOTS_PER_EPOCH - 1

    state = genesis_state.mset(
        "slot",
        slot,
        "previous_justified_checkpoint",
        Checkpoint.create(epoch=previous_justified_epoch),
        "current_justified_checkpoint",
        Checkpoint.create(epoch=current_justified_epoch),
        "justification_bits",
        justification_bits,
        "finalized_checkpoint",
        Checkpoint.create(epoch=finalized_epoch),
        "block_roots",
        tuple(
            i.to_bytes(32, "little")
            for i in range(config.SLOTS_PER_HISTORICAL_ROOT)),
    )

    if previous_epoch_justifiable:
        attestations = mk_all_pending_attestations_with_full_participation_in_epoch(
            state, previous_epoch, config)
        state = state.set("previous_epoch_attestations", attestations)

    if current_epoch_justifiable:
        attestations = mk_all_pending_attestations_with_full_participation_in_epoch(
            state, current_epoch, config)
        state = state.set("current_epoch_attestations", attestations)

    post_state = process_justification_and_finalization(state, config)

    assert (post_state.previous_justified_checkpoint.epoch ==
            state.current_justified_checkpoint.epoch)
    assert post_state.current_justified_checkpoint.epoch == justified_epoch_after
    assert post_state.justification_bits == justification_bits_after
    assert post_state.finalized_checkpoint.epoch == finalized_epoch_after
Ejemplo n.º 14
0
def create_mock_signed_attestations_at_slot(
    state: BeaconState,
    config: Eth2Config,
    state_machine: BaseBeaconStateMachine,
    attestation_slot: Slot,
    beacon_block_root: Root,
    keymap: Dict[BLSPubkey, int],
    voted_attesters_ratio: float = 1.0,
) -> Iterable[Attestation]:
    """
    Create the mocking attestations of the given ``attestation_slot`` slot with ``keymap``.
    """
    if voted_attesters_ratio == 0:
        return ()

    committees_per_slot = get_committee_count_at_slot(
        state,
        attestation_slot,
        config.MAX_COMMITTEES_PER_SLOT,
        config.SLOTS_PER_EPOCH,
        config.TARGET_COMMITTEE_SIZE,
    )

    # Get `target_root`
    target_root = _get_target_root(state, config, beacon_block_root)
    target_epoch = compute_epoch_at_slot(state.slot, config.SLOTS_PER_EPOCH)

    for committee, committee_index, _ in iterate_committees_at_slot(
            state, attestation_slot, committees_per_slot, config):
        attestation_data = AttestationData.create(
            slot=attestation_slot,
            index=CommitteeIndex(committee_index),
            beacon_block_root=beacon_block_root,
            source=Checkpoint.create(
                epoch=state.current_justified_checkpoint.epoch,
                root=state.current_justified_checkpoint.root,
            ),
            target=Checkpoint.create(root=target_root, epoch=target_epoch),
        )

        num_voted_attesters = max(int(len(committee) * voted_attesters_ratio),
                                  1)

        yield _create_mock_signed_attestation(
            state,
            attestation_data,
            attestation_slot,
            committee,
            num_voted_attesters,
            keymap,
            config.SLOTS_PER_EPOCH,
        )
Ejemplo n.º 15
0
def sample_attestation_data_params(sample_crosslink_record_params):
    return {
        'beacon_block_root': b'\x11' * 32,
        'source': Checkpoint(
            epoch=11,
            root=b'\x22' * 32,
        ),
        'target': Checkpoint(
            epoch=12,
            root=b'\x33' * 32,
        ),
        'crosslink': Crosslink(**sample_crosslink_record_params),
    }
Ejemplo n.º 16
0
def test_get_unslashed_attesting_indices(genesis_state, config):
    state = genesis_state.copy(
        slot=compute_start_slot_of_epoch(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=Checkpoint(epoch=target_epoch),
                           crosslink=Crosslink(shard=target_shard))
    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.update_validator_with_fn(
                    index, lambda v, *_: v.copy(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(data=data, aggregation_bits=bitfield), ),
        CommitteeConfig(config),
    )

    assert set(indices) == set(some_subset)
    assert len(indices) == len(some_subset)
Ejemplo n.º 17
0
    def __init__(
        self,
        finalized_block_node: BlockNode[BaseBeaconBlock],
        justified_checkpoint: Checkpoint,
        justified_state: BeaconState,
        config: Eth2Config,
        block_sink: BlockSink,
    ) -> None:
        self._config = config
        finalized_checkpoint = Checkpoint.create(
            epoch=compute_epoch_at_slot(finalized_block_node.slot,
                                        config.SLOTS_PER_EPOCH),
            root=finalized_block_node.root,
        )
        self._impl = ProtoArrayForkChoice(
            finalized_block_node,
            finalized_checkpoint,
            justified_checkpoint,
            block_sink,
            config,
        )
        self._justified = justified_checkpoint
        self._finalized = finalized_checkpoint

        self.update_justified(justified_state)
Ejemplo n.º 18
0
def _mk_attestation_inputs_in_epoch(epoch, block_producer, state, config):
    for committee, committee_index, slot in iterate_committees_at_epoch(
            state, epoch, config):
        if not committee:
            # empty committee this slot
            continue

        if slot >= state.slot:
            # do not make attestations in the future
            break

        block = block_producer(slot)
        root = block.message.hash_tree_root
        attestation_data = AttestationData.create(
            slot=slot,
            index=committee_index,
            target=Checkpoint.create(epoch=epoch, root=root),
            beacon_block_root=root,
        )
        committee_size = len(committee)
        aggregation_bits = bitfield.get_empty_bitfield(committee_size)
        for index in range(committee_size):
            aggregation_bits = bitfield.set_voted(aggregation_bits, index)
            for index in committee:
                yield (
                    index,
                    (attestation_data.slot, (aggregation_bits,
                                             attestation_data)),
                )
Ejemplo n.º 19
0
def _determine_new_justified_checkpoint_and_bitfield(
        state: BeaconState, config: Eth2Config) -> Tuple[Checkpoint, Bitfield]:
    (
        new_current_justified_epoch,
        justification_bits,
    ) = _determine_new_justified_epoch_and_bitfield(
        state,
        config,
    )

    if new_current_justified_epoch != state.current_justified_checkpoint.epoch:
        new_current_justified_root = get_block_root(
            state,
            new_current_justified_epoch,
            config.SLOTS_PER_EPOCH,
            config.SLOTS_PER_HISTORICAL_ROOT,
        )
    else:
        new_current_justified_root = state.current_justified_checkpoint.root

    return (
        Checkpoint(
            epoch=new_current_justified_epoch,
            root=new_current_justified_root,
        ),
        justification_bits,
    )
Ejemplo n.º 20
0
    def _load_checkpoints(self) -> None:
        justified = self._chain_db.get_justified_head(BeaconBlock)
        finalized = self._chain_db.get_finalized_head(BeaconBlock)

        state_machine = self.get_state_machine(self._current_head.slot)
        config = state_machine.config
        self._justified_checkpoint = Checkpoint.create(
            epoch=compute_epoch_at_slot(justified.slot,
                                        config.SLOTS_PER_EPOCH),
            root=justified.hash_tree_root,
        )
        self._finalized_checkpoint = Checkpoint.create(
            epoch=compute_epoch_at_slot(finalized.slot,
                                        config.SLOTS_PER_EPOCH),
            root=finalized.hash_tree_root,
        )
Ejemplo n.º 21
0
def _find_collision(state, config, validator_index, epoch, block_producer):
    """
    Given a target epoch, make the attestation expected for the
    validator w/ the given ``validator_index``.
    """
    for committee, committee_index, slot in iterate_committees_at_epoch(
            state, epoch, config):
        if slot >= state.slot:
            # do not make attestations in the future
            return {}

        if validator_index in committee:
            # TODO(ralexstokes) refactor w/ tools/builder
            block = block_producer(slot)
            root = block.message.hash_tree_root
            attestation_data = AttestationData.create(
                slot=slot,
                index=committee_index,
                target=Checkpoint.create(epoch=epoch, root=root),
                beacon_block_root=root,
            )
            committee_count = len(committee)
            aggregation_bits = bitfield.get_empty_bitfield(committee_count)
            for i in range(committee_count):
                aggregation_bits = bitfield.set_voted(aggregation_bits, i)

            return {
                index: (slot, (aggregation_bits, attestation_data))
                for index in committee
            }
    else:
        raise Exception("should have found a duplicate validator")
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)
Ejemplo n.º 23
0
def _determine_new_finalized_checkpoint(state: BeaconState,
                                        justification_bits: Bitfield,
                                        config: Eth2Config) -> Checkpoint:
    current_epoch = state.current_epoch(config.SLOTS_PER_EPOCH)

    new_finalized_epoch = _determine_new_finalized_epoch(
        state.finalized_checkpoint.epoch,
        state.previous_justified_checkpoint.epoch,
        state.current_justified_checkpoint.epoch,
        current_epoch,
        justification_bits,
    )
    if new_finalized_epoch != state.finalized_checkpoint.epoch:
        # NOTE: we only want to call ``get_block_root``
        # upon some change, not unconditionally
        # Given the way it reads the block roots, it can cause
        # validation problems with some configurations, esp. in testing.
        # This is implicitly happening above for the justified roots.
        new_finalized_root = get_block_root(
            state,
            new_finalized_epoch,
            config.SLOTS_PER_EPOCH,
            config.SLOTS_PER_HISTORICAL_ROOT,
        )
    else:
        new_finalized_root = state.finalized_checkpoint.root

    return Checkpoint.create(epoch=new_finalized_epoch,
                             root=new_finalized_root)
Ejemplo n.º 24
0
def _mk_attestation_inputs_in_epoch(epoch, block_producer, state, config):
    for committee, committee_index, slot in iterate_committees_at_epoch(
        state, epoch, config
    ):
        if not committee:
            # empty committee this slot
            continue

        block = block_producer(slot)
        root = block.signing_root
        attestation_data = AttestationData(
            slot=slot,
            index=committee_index,
            target=Checkpoint(epoch=epoch, root=root),
            beacon_block_root=root,
        )
        committee_size = len(committee)
        aggregation_bits = bitfield.get_empty_bitfield(committee_size)
        for index in range(committee_size):
            aggregation_bits = bitfield.set_voted(aggregation_bits, index)
            for index in committee:
                yield (
                    index,
                    (attestation_data.slot, (aggregation_bits, attestation_data)),
                )
Ejemplo n.º 25
0
def create_signed_attestation_at_slot(
    state: BeaconState,
    config: Eth2Config,
    state_machine: BaseBeaconStateMachine,
    attestation_slot: Slot,
    beacon_block_root: SigningRoot,
    validator_privkeys: Dict[ValidatorIndex, int],
    committee: Tuple[ValidatorIndex, ...],
    committee_index: CommitteeIndex,
    attesting_indices: Sequence[CommitteeValidatorIndex],
) -> Attestation:
    """
    Create the attestations of the given ``attestation_slot`` slot with ``validator_privkeys``.
    """
    state_transition = state_machine.state_transition
    state = state_transition.apply_state_transition(
        state, future_slot=attestation_slot)

    target_epoch = compute_epoch_at_slot(attestation_slot,
                                         config.SLOTS_PER_EPOCH)

    target_root = _get_target_root(state, config, beacon_block_root)

    attestation_data = AttestationData(
        slot=attestation_slot,
        index=committee_index,
        beacon_block_root=beacon_block_root,
        source=Checkpoint(
            epoch=state.current_justified_checkpoint.epoch,
            root=state.current_justified_checkpoint.root,
        ),
        target=Checkpoint(root=target_root, epoch=target_epoch),
    )

    return _create_mock_signed_attestation(
        state,
        attestation_data,
        attestation_slot,
        committee,
        len(committee),
        keymapper(lambda index: state.validators[index].pubkey,
                  validator_privkeys),
        config.SLOTS_PER_EPOCH,
        is_for_simulation=False,
        attesting_indices=attesting_indices,
    )
Ejemplo n.º 26
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)
Ejemplo n.º 27
0
 def from_genesis(cls, genesis_state: BeaconState, config: Eth2Config,
                  block_sink: BlockSink) -> "LMDGHOSTForkChoice":
     # NOTE: patch up genesis state to reflect the genesis block as an initial checkpoint
     # this only has to be patched once at genesis
     genesis_block = get_genesis_block(genesis_state.hash_tree_root,
                                       BeaconBlock)
     genesis_block_node = _block_to_block_node(genesis_block)
     justified_checkpoint = Checkpoint.create()
     return cls(genesis_block_node, justified_checkpoint, genesis_state,
                config, block_sink)
Ejemplo n.º 28
0
def sample_beacon_state_params(config, sample_fork_params,
                               sample_eth1_data_params,
                               sample_block_header_params):
    return {
        # Versioning
        "genesis_time":
        0,
        "slot":
        GENESIS_SLOT + 100,
        "fork":
        Fork.create(**sample_fork_params),
        # History
        "latest_block_header":
        BeaconBlockHeader.create(**sample_block_header_params),
        "block_roots": (ZERO_HASH32, ) * config.SLOTS_PER_HISTORICAL_ROOT,
        "state_roots": (ZERO_HASH32, ) * config.SLOTS_PER_HISTORICAL_ROOT,
        "historical_roots": (),
        # Eth1
        "eth1_data":
        Eth1Data.create(**sample_eth1_data_params),
        "eth1_data_votes": (),
        "eth1_deposit_index":
        0,
        # Registry
        "validators": (),
        "balances": (),
        # Shuffling
        "randao_mixes": (ZERO_HASH32, ) * config.EPOCHS_PER_HISTORICAL_VECTOR,
        # Slashings
        "slashings": (0, ) * config.EPOCHS_PER_SLASHINGS_VECTOR,
        # Attestations
        "previous_epoch_attestations": (),
        "current_epoch_attestations": (),
        # Justification
        "justification_bits": (False, ) * JUSTIFICATION_BITS_LENGTH,
        "previous_justified_checkpoint":
        Checkpoint.create(epoch=0, root=b"\x99" * 32),
        "current_justified_checkpoint":
        Checkpoint.create(epoch=0, root=b"\x55" * 32),
        # Finality
        "finalized_checkpoint":
        Checkpoint.create(epoch=0, root=b"\x33" * 32),
    }
Ejemplo n.º 29
0
def _mk_attestation_inputs_in_epoch(epoch, state, config):
    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 random.sample(range(epoch_committee_count), epoch_committee_count):
        shard = Shard((epoch_start_shard + shard_offset) % config.SHARD_COUNT)
        committee = get_crosslink_committee(
            state,
            epoch,
            shard,
            CommitteeConfig(config),
        )

        if not committee:
            # empty crosslink committee this epoch
            continue

        attestation_data = AttestationData(
            target=Checkpoint(
                epoch=epoch,
            ),
            crosslink=Crosslink(
                shard=shard,
            ),
        )
        committee_count = len(committee)
        aggregation_bits = bitfield.get_empty_bitfield(committee_count)
        for index in range(committee_count):
            aggregation_bits = bitfield.set_voted(aggregation_bits, index)

            for index in committee:
                yield (
                    index,
                    (
                        get_attestation_data_slot(
                            state,
                            attestation_data,
                            config,
                        ),
                        (
                            aggregation_bits,
                            attestation_data,
                        ),
                    ),
                )
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)