Exemple #1
0
def genesis_state(filled_beacon_state,
                  activated_genesis_validators,
                  genesis_balances,
                  epoch_length,
                  target_committee_size,
                  genesis_epoch,
                  shard_count,
                  latest_block_roots_length,
                  latest_penalized_exit_length,
                  latest_randao_mixes_length):
    return filled_beacon_state.copy(
        validator_registry=activated_genesis_validators,
        validator_balances=genesis_balances,
        latest_block_roots=tuple(ZERO_HASH32 for _ in range(latest_block_roots_length)),
        latest_penalized_balances=(0,) * latest_penalized_exit_length,
        latest_crosslinks=tuple(
            CrosslinkRecord(
                epoch=genesis_epoch,
                shard_block_root=ZERO_HASH32,
            )
            for _ in range(shard_count)
        ),
        latest_randao_mixes=tuple(
            ZERO_HASH32
            for _ in range(latest_randao_mixes_length)
        ),
    )
def validate_attestation_previous_crosslink_or_root(
        attestation_data: AttestationData,
        state_latest_crosslink: CrosslinkRecord, slots_per_epoch: int) -> None:
    """
    Validate that either the attestation ``previous_crosslink`` or ``crosslink_data_root``
    field of ``attestation_data`` is the provided ``latest_crosslink``.
    Raise ``ValidationError`` if it's invalid.
    """
    attestation_creating_crosslink = CrosslinkRecord(
        epoch=slot_to_epoch(attestation_data.slot, slots_per_epoch),
        crosslink_data_root=attestation_data.crosslink_data_root,
    )
    acceptable_crosslink_data = {
        # Case 1: Latest crosslink matches the one in the state
        attestation_data.previous_crosslink,
        # Case 2: State has already been updated, state's latest crosslink matches the crosslink
        # the attestation is trying to create
        attestation_creating_crosslink,
    }
    if state_latest_crosslink not in acceptable_crosslink_data:
        raise ValidationError(
            f"State's latests crosslink ({state_latest_crosslink}) doesn't match "
            " case 1: the `attestation_data.previous_crosslink` "
            f"({attestation_data.previous_crosslink.root}) or "
            "`case 2: the crosslink the attestation is trying to create "
            f"({attestation_creating_crosslink})")
Exemple #3
0
async def test_send_multiple_attestations(request, event_loop):
    alice, msg_buffer = await get_command_setup(request, event_loop)

    attestations = tuple(
        Attestation(
            aggregation_bitfield=b"\x00\x00\x00",
            data=AttestationData(
                slot=0,
                beacon_block_root=ZERO_HASH32,
                source_epoch=SERENITY_CONFIG.GENESIS_EPOCH,
                target_root=ZERO_HASH32,
                source_root=ZERO_HASH32,
                shard=shard,
                previous_crosslink=CrosslinkRecord(
                    SERENITY_CONFIG.GENESIS_EPOCH, ZERO_HASH32),
                crosslink_data_root=ZERO_HASH32,
            ),
            custody_bitfield=b"\x00\x00\x00",
        ) for shard in range(10))

    alice.sub_proto.send_attestation_records(attestations)

    message = await msg_buffer.msg_queue.get()
    assert isinstance(message.command, AttestationRecords)
    assert message.payload == tuple(
        ssz.encode(attestation) for attestation in attestations)
Exemple #4
0
def genesis_state(sample_beacon_state_params,
                  activated_genesis_validators,
                  genesis_balances,
                  epoch_length,
                  target_committee_size,
                  genesis_slot,
                  shard_count,
                  latest_block_roots_length):
    initial_shuffling = get_shuffling(
        seed=ZERO_HASH32,
        validators=activated_genesis_validators,
        crosslinking_start_shard=0,
        slot=genesis_slot,
        epoch_length=epoch_length,
        target_committee_size=target_committee_size,
        shard_count=shard_count
    )
    return BeaconState(**sample_beacon_state_params).copy(
        validator_registry=activated_genesis_validators,
        validator_balances=genesis_balances,
        shard_committees_at_slots=initial_shuffling + initial_shuffling,
        latest_block_roots=tuple(ZERO_HASH32 for _ in range(latest_block_roots_length)),
        latest_crosslinks=tuple(
            CrosslinkRecord(
                slot=genesis_slot,
                shard_block_root=ZERO_HASH32,
            )
            for _ in range(shard_count)
        )
    )
Exemple #5
0
def test_num_crosslink_records(expected, sample_crosslink_record_params,
                               filled_beacon_state):
    crosslink_records = [
        CrosslinkRecord(**sample_crosslink_record_params)
        for i in range(expected)
    ]
    state = filled_beacon_state.copy(latest_crosslinks=crosslink_records, )

    assert state.num_crosslinks == expected
Exemple #6
0
def sample_attestation_data_params(sample_crosslink_record_params):
    return {
        'slot': 10,
        'beacon_block_root': b'\x11' * 32,
        'source_epoch': 11,
        'source_root': b'\x22' * 32,
        'target_root': b'\x33' * 32,
        'shard': 12,
        'previous_crosslink': CrosslinkRecord(**sample_crosslink_record_params),
        'crosslink_data_root': b'\x44' * 32,
    }
def sample_attestation_data_params(sample_crosslink_record_params):
    return {
        'slot': 10,
        'shard': 12,
        'beacon_block_root': b'\x11' * 32,
        'epoch_boundary_root': b'\x22' * 32,
        'crosslink_data_root': b'\x33' * 32,
        'latest_crosslink': CrosslinkRecord(**sample_crosslink_record_params),
        'justified_epoch': 0,
        'justified_block_root': b'\x55' * 32,
    }
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
Exemple #9
0
async def test_send_single_attestation(request, event_loop):
    alice, msg_buffer = await get_command_setup(request, event_loop)

    attestation = Attestation(
        aggregation_bitfield=b"\x00\x00\x00",
        data=AttestationData(
            slot=0,
            shard=1,
            beacon_block_root=ZERO_HASH32,
            epoch_boundary_root=ZERO_HASH32,
            crosslink_data_root=ZERO_HASH32,
            latest_crosslink=CrosslinkRecord(SERENITY_CONFIG.GENESIS_EPOCH,
                                             ZERO_HASH32),
            justified_epoch=SERENITY_CONFIG.GENESIS_EPOCH,
            justified_block_root=ZERO_HASH32,
        ),
        custody_bitfield=b"\x00\x00\x00",
    )

    alice.sub_proto.send_attestation_records((attestation, ))

    message = await msg_buffer.msg_queue.get()
    assert isinstance(message.command, AttestationRecords)
    assert message.payload == (ssz.encode(attestation), )
Exemple #10
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
Exemple #11
0
def get_genesis_beacon_state(*,
                             genesis_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,

        # Randomness and committees
        latest_randao_mixes=(ZERO_HASH32,) * 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=(
            (CrosslinkRecord(epoch=genesis_epoch, shard_block_root=ZERO_HASH32),) * shard_count
        ),
        latest_block_roots=(ZERO_HASH32,) * latest_block_roots_length,
        latest_index_roots=(ZERO_HASH32,) * latest_index_roots_length,
        latest_penalized_balances=(Gwei(0),) * latest_penalized_exit_length,
        latest_attestations=(),
        batched_block_roots=(),

        # Ethereum 1.0 chain data
        latest_eth1_data=latest_eth1_data,
        eth1_data_votes=(),
        deposit_index=len(genesis_validator_deposits),
    )

    # Process initial deposits
    for deposit in genesis_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,
            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,
    )
    genesis_active_index_root = hash_eth2(
        b''.join(
            [
                index.to_bytes(32, 'big')
                for index in active_validator_indices
            ]
        )
    )
    latest_index_roots = (genesis_active_index_root,) * latest_index_roots_length
    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
Exemple #12
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
def test_process_crosslinks(
        random,
        n_validators_state,
        config,
        slots_per_epoch,
        target_committee_size,
        shard_count,
        success_crosslink_in_cur_epoch,
        sample_attestation_data_params,
        sample_attestation_params):
    shard = 1
    crosslink_data_root = hash_eth2(b'crosslink_data_root')
    current_slot = config.SLOTS_PER_EPOCH * 2 - 1

    genesis_crosslinks = tuple([
        CrosslinkRecord(epoch=config.GENESIS_EPOCH, crosslink_data_root=ZERO_HASH32)
        for _ in range(shard_count)
    ])
    state = n_validators_state.copy(
        slot=current_slot,
        latest_crosslinks=genesis_crosslinks,
    )

    # Generate current epoch attestations
    cur_epoch_attestations = []
    for slot_in_cur_epoch in range(state.slot - config.SLOTS_PER_EPOCH, state.slot):
        if len(cur_epoch_attestations) > 0:
            break
        for committee, _shard in get_crosslink_committees_at_slot(
            state,
            slot_in_cur_epoch,
            CommitteeConfig(config),
        ):
            if _shard == shard:
                # Sample validators attesting to this shard.
                # Number of attesting validators sampled depends on `success_crosslink_in_cur_epoch`
                # if True, have >2/3 committee attest
                if success_crosslink_in_cur_epoch:
                    attesting_validators = random.sample(committee, (2 * len(committee) // 3 + 1))
                else:
                    attesting_validators = random.sample(committee, (2 * len(committee) // 3 - 1))
                # Generate the bitfield
                aggregation_bitfield = get_empty_bitfield(len(committee))
                for v_index in attesting_validators:
                    aggregation_bitfield = set_voted(
                        aggregation_bitfield, committee.index(v_index))
                # Generate the attestation
                cur_epoch_attestations.append(
                    Attestation(**sample_attestation_params).copy(
                        aggregation_bitfield=aggregation_bitfield,
                        data=AttestationData(**sample_attestation_data_params).copy(
                            slot=slot_in_cur_epoch,
                            shard=shard,
                            crosslink_data_root=crosslink_data_root,
                        ),
                    )
                )

    state = state.copy(
        latest_attestations=cur_epoch_attestations,
    )
    assert (state.latest_crosslinks[shard].epoch == config.GENESIS_EPOCH and
            state.latest_crosslinks[shard].crosslink_data_root == ZERO_HASH32)

    new_state = process_crosslinks(state, config)
    crosslink_record = new_state.latest_crosslinks[shard]
    if success_crosslink_in_cur_epoch:
        attestation = cur_epoch_attestations[0]
        assert (crosslink_record.epoch == slot_to_epoch(current_slot, slots_per_epoch) and
                crosslink_record.crosslink_data_root == attestation.data.crosslink_data_root and
                attestation.data.crosslink_data_root == crosslink_data_root)
    else:
        assert (crosslink_record.epoch == config.GENESIS_EPOCH and
                crosslink_record.crosslink_data_root == ZERO_HASH32)
Exemple #14
0
def test_defaults(sample_crosslink_record_params):
    crosslink = CrosslinkRecord(**sample_crosslink_record_params)
    assert crosslink.epoch == sample_crosslink_record_params['epoch']
    assert crosslink.crosslink_data_root == sample_crosslink_record_params['crosslink_data_root']
Exemple #15
0
def test_get_initial_beacon_state(
        privkeys, pubkeys, num_validators, genesis_epoch, genesis_slot,
        genesis_fork_version, genesis_start_shard, shard_count, seed_lookahead,
        latest_block_roots_length, latest_index_roots_length, epoch_length,
        max_deposit_amount, latest_penalized_exit_length,
        latest_randao_mixes_length, entry_exit_delay, sample_eth1_data_params):
    withdrawal_credentials = b'\x22' * 32
    randao_commitment = b'\x33' * 32
    custody_commitment = b'\x44' * 32
    fork = Fork(
        previous_version=genesis_fork_version,
        current_version=genesis_fork_version,
        epoch=genesis_epoch,
    )

    validator_count = 5

    initial_validator_deposits = (Deposit(
        branch=(b'\x11' * 32 for j in range(10)),
        index=i,
        deposit_data=DepositData(
            deposit_input=DepositInput(
                pubkey=pubkeys[i],
                withdrawal_credentials=withdrawal_credentials,
                randao_commitment=randao_commitment,
                custody_commitment=custody_commitment,
                proof_of_possession=sign_proof_of_possession(
                    deposit_input=DepositInput(
                        pubkey=pubkeys[i],
                        withdrawal_credentials=withdrawal_credentials,
                        randao_commitment=randao_commitment,
                        custody_commitment=custody_commitment,
                    ),
                    privkey=privkeys[i],
                    fork=fork,
                    slot=genesis_slot,
                    epoch_length=epoch_length,
                ),
            ),
            amount=max_deposit_amount,
            timestamp=0,
        ),
    ) for i in range(validator_count))
    genesis_time = 10
    latest_eth1_data = Eth1Data(**sample_eth1_data_params)

    state = get_initial_beacon_state(
        initial_validator_deposits=initial_validator_deposits,
        genesis_time=genesis_time,
        latest_eth1_data=latest_eth1_data,
        genesis_epoch=genesis_epoch,
        genesis_slot=genesis_slot,
        genesis_fork_version=genesis_fork_version,
        genesis_start_shard=genesis_start_shard,
        shard_count=shard_count,
        seed_lookahead=seed_lookahead,
        latest_block_roots_length=latest_block_roots_length,
        latest_index_roots_length=latest_index_roots_length,
        epoch_length=epoch_length,
        max_deposit_amount=max_deposit_amount,
        latest_penalized_exit_length=latest_penalized_exit_length,
        latest_randao_mixes_length=latest_randao_mixes_length,
        entry_exit_delay=entry_exit_delay,
    )

    # Misc
    assert state.slot == genesis_slot
    assert state.genesis_time == genesis_time
    assert state.fork.previous_version == genesis_fork_version
    assert state.fork.current_version == genesis_fork_version
    assert state.fork.epoch == genesis_epoch

    # Validator registry
    assert len(state.validator_registry) == validator_count
    assert len(state.validator_balances) == validator_count
    assert state.validator_registry_update_epoch == genesis_epoch
    assert state.validator_registry_exit_count == 0

    # Randomness and committees
    assert len(state.latest_randao_mixes) == latest_randao_mixes_length
    assert len(
        state.latest_vdf_outputs) == latest_randao_mixes_length // epoch_length

    # TODO: `persistent_committees`, `persistent_committee_reassignments` will be removed
    assert len(state.persistent_committees) == 0
    assert len(state.persistent_committee_reassignments) == 0
    assert state.previous_epoch_start_shard == genesis_start_shard
    assert state.current_epoch_start_shard == genesis_start_shard
    assert state.previous_calculation_epoch == genesis_epoch
    assert state.current_calculation_epoch == genesis_epoch
    assert state.previous_epoch_seed == ZERO_HASH32

    # Custody challenges
    assert len(state.custody_challenges) == 0

    # Finality
    assert state.previous_justified_epoch == genesis_epoch
    assert state.justified_epoch == genesis_epoch
    assert state.justification_bitfield == 0
    assert state.finalized_epoch == genesis_epoch

    # Recent state
    assert len(state.latest_crosslinks) == shard_count
    assert state.latest_crosslinks[0] == CrosslinkRecord(
        epoch=genesis_epoch,
        shard_block_root=ZERO_HASH32,
    )
    assert len(state.latest_block_roots) == latest_block_roots_length
    assert state.latest_block_roots[0] == ZERO_HASH32
    assert len(state.latest_penalized_balances) == latest_penalized_exit_length
    assert state.latest_penalized_balances[0] == Gwei(0)

    assert len(state.latest_attestations) == 0
    assert len(state.batched_block_roots) == 0

    # Ethereum 1.0 chain data
    assert state.latest_eth1_data == latest_eth1_data
    assert len(state.eth1_data_votes) == 0

    assert state.validator_registry[0].is_active(genesis_epoch)
Exemple #16
0
            validate_attestation_justified_block_root(
                attestation_data,
                justified_block_root
            )


@pytest.mark.parametrize(
    (
        'attestation_latest_crosslink,'
        'attestation_crosslink_data_root,'
        'state_latest_crosslink,'
        'is_valid,'
    ),
    [
        (
            CrosslinkRecord(0, b'\x11' * 32),
            b'\x33' * 32,
            CrosslinkRecord(0, b'\x22' * 32),
            False,
        ),
        (
            CrosslinkRecord(0, b'\x33' * 32),
            b'\x33' * 32,
            CrosslinkRecord(0, b'\x11' * 32),
            False,
        ),
        (
            CrosslinkRecord(0, b'\x11' * 32),
            b'\x33' * 32,
            CrosslinkRecord(0, b'\x33' * 32),
            True,
def test_defaults(sample_crosslink_record_params):
    crosslink = CrosslinkRecord(**sample_crosslink_record_params)
    assert crosslink.slot == sample_crosslink_record_params['slot']
    assert crosslink.shard_block_root == sample_crosslink_record_params['shard_block_root']
Exemple #18
0
def test_get_genesis_beacon_state(
        privkeys, pubkeys, num_validators, genesis_epoch, genesis_slot,
        genesis_fork_version, genesis_start_shard, shard_count,
        min_seed_lookahead, latest_block_roots_length,
        latest_active_index_roots_length, slots_per_epoch, max_deposit_amount,
        latest_slashed_exit_length, latest_randao_mixes_length,
        activation_exit_delay, sample_eth1_data_params):
    withdrawal_credentials = b'\x22' * 32
    fork = Fork(
        previous_version=genesis_fork_version,
        current_version=genesis_fork_version,
        epoch=genesis_epoch,
    )

    validator_count = 5

    genesis_validator_deposits = tuple(
        Deposit(
            branch=(b'\x11' * 32 for j in range(10)),
            index=i,
            deposit_data=DepositData(
                deposit_input=DepositInput(
                    pubkey=pubkeys[i],
                    withdrawal_credentials=withdrawal_credentials,
                    proof_of_possession=sign_proof_of_possession(
                        deposit_input=DepositInput(
                            pubkey=pubkeys[i],
                            withdrawal_credentials=withdrawal_credentials,
                        ),
                        privkey=privkeys[i],
                        fork=fork,
                        slot=genesis_slot,
                        slots_per_epoch=slots_per_epoch,
                    ),
                ),
                amount=max_deposit_amount,
                timestamp=0,
            ),
        ) for i in range(validator_count))
    genesis_time = 10
    latest_eth1_data = Eth1Data(**sample_eth1_data_params)

    state = get_genesis_beacon_state(
        genesis_validator_deposits=genesis_validator_deposits,
        genesis_time=genesis_time,
        latest_eth1_data=latest_eth1_data,
        genesis_epoch=genesis_epoch,
        genesis_slot=genesis_slot,
        genesis_fork_version=genesis_fork_version,
        genesis_start_shard=genesis_start_shard,
        shard_count=shard_count,
        min_seed_lookahead=min_seed_lookahead,
        latest_block_roots_length=latest_block_roots_length,
        latest_active_index_roots_length=latest_active_index_roots_length,
        slots_per_epoch=slots_per_epoch,
        max_deposit_amount=max_deposit_amount,
        latest_slashed_exit_length=latest_slashed_exit_length,
        latest_randao_mixes_length=latest_randao_mixes_length,
        activation_exit_delay=activation_exit_delay,
    )

    # Misc
    assert state.slot == genesis_slot
    assert state.genesis_time == genesis_time
    assert state.fork.previous_version == genesis_fork_version
    assert state.fork.current_version == genesis_fork_version
    assert state.fork.epoch == genesis_epoch

    # Validator registry
    assert len(state.validator_registry) == validator_count
    assert len(state.validator_balances) == validator_count
    assert state.validator_registry_update_epoch == genesis_epoch

    # Randomness and committees
    assert len(state.latest_randao_mixes) == latest_randao_mixes_length
    assert state.previous_shuffling_start_shard == genesis_start_shard
    assert state.current_shuffling_start_shard == genesis_start_shard
    assert state.previous_shuffling_epoch == genesis_epoch
    assert state.current_shuffling_epoch == genesis_epoch
    assert state.previous_shuffling_seed == ZERO_HASH32

    # Finality
    assert state.previous_justified_epoch == genesis_epoch
    assert state.justified_epoch == genesis_epoch
    assert state.justification_bitfield == 0
    assert state.finalized_epoch == genesis_epoch

    # Recent state
    assert len(state.latest_crosslinks) == shard_count
    assert state.latest_crosslinks[0] == CrosslinkRecord(
        epoch=genesis_epoch,
        crosslink_data_root=ZERO_HASH32,
    )
    assert len(state.latest_block_roots) == latest_block_roots_length
    assert state.latest_block_roots[0] == ZERO_HASH32
    assert len(state.latest_slashed_balances) == latest_slashed_exit_length
    assert state.latest_slashed_balances[0] == Gwei(0)

    assert len(state.latest_attestations) == 0
    assert len(state.batched_block_roots) == 0

    # Ethereum 1.0 chain data
    assert state.latest_eth1_data == latest_eth1_data
    assert len(state.eth1_data_votes) == 0
    assert state.deposit_index == len(genesis_validator_deposits)

    assert state.validator_registry[0].is_active(genesis_epoch)
Exemple #19
0
def test_get_genesis_beacon_state(
        num_validators, pubkeys, genesis_epoch, genesis_slot,
        genesis_fork_version, genesis_start_shard, shard_count,
        min_seed_lookahead, slots_per_historical_root,
        latest_active_index_roots_length, slots_per_epoch, max_deposit_amount,
        latest_slashed_exit_length, latest_randao_mixes_length,
        activation_exit_delay, config, keymap, deposit_contract_tree_depth):
    validator_count = 5

    genesis_validator_deposits, deposit_root = create_mock_genesis_validator_deposits_and_root(
        num_validators=validator_count,
        config=config,
        pubkeys=pubkeys,
        keymap=keymap,
    )

    genesis_eth1_data = Eth1Data(
        deposit_root=deposit_root,
        block_hash=ZERO_HASH32,
    )
    genesis_time = 10

    state = get_genesis_beacon_state(
        genesis_validator_deposits=genesis_validator_deposits,
        genesis_time=genesis_time,
        genesis_eth1_data=genesis_eth1_data,
        genesis_epoch=genesis_epoch,
        genesis_slot=genesis_slot,
        genesis_fork_version=genesis_fork_version,
        genesis_start_shard=genesis_start_shard,
        shard_count=shard_count,
        min_seed_lookahead=min_seed_lookahead,
        slots_per_historical_root=slots_per_historical_root,
        latest_active_index_roots_length=latest_active_index_roots_length,
        slots_per_epoch=slots_per_epoch,
        max_deposit_amount=max_deposit_amount,
        latest_slashed_exit_length=latest_slashed_exit_length,
        latest_randao_mixes_length=latest_randao_mixes_length,
        activation_exit_delay=activation_exit_delay,
        deposit_contract_tree_depth=deposit_contract_tree_depth,
    )

    # Misc
    assert state.slot == genesis_slot
    assert state.genesis_time == genesis_time
    assert state.fork.previous_version == genesis_fork_version.to_bytes(
        4, 'little')
    assert state.fork.current_version == genesis_fork_version.to_bytes(
        4, 'little')
    assert state.fork.epoch == genesis_epoch

    # Validator registry
    assert len(state.validator_registry) == validator_count
    assert len(state.validator_balances) == validator_count
    assert state.validator_registry_update_epoch == genesis_epoch

    # Randomness and committees
    assert len(state.latest_randao_mixes) == latest_randao_mixes_length
    assert state.previous_shuffling_start_shard == genesis_start_shard
    assert state.current_shuffling_start_shard == genesis_start_shard
    assert state.previous_shuffling_epoch == genesis_epoch
    assert state.current_shuffling_epoch == genesis_epoch
    assert state.previous_shuffling_seed == ZERO_HASH32

    # Finality
    assert len(state.previous_epoch_attestations) == 0
    assert len(state.current_epoch_attestations) == 0
    assert state.previous_justified_epoch == genesis_epoch
    assert state.justified_epoch == genesis_epoch
    assert state.justification_bitfield == 0
    assert state.finalized_epoch == genesis_epoch

    # Recent state
    assert len(state.latest_crosslinks) == shard_count
    assert state.latest_crosslinks[0] == CrosslinkRecord(
        epoch=genesis_epoch,
        crosslink_data_root=ZERO_HASH32,
    )
    assert len(state.latest_block_roots) == slots_per_historical_root
    assert state.latest_block_roots[0] == ZERO_HASH32
    assert len(state.latest_slashed_balances) == latest_slashed_exit_length
    assert state.latest_slashed_balances[0] == Gwei(0)

    assert len(state.historical_roots) == 0

    # Ethereum 1.0 chain data
    assert state.latest_eth1_data == genesis_eth1_data
    assert len(state.eth1_data_votes) == 0
    assert state.deposit_index == len(genesis_validator_deposits)

    assert state.validator_registry[0].is_active(genesis_epoch)
Exemple #20
0
def get_genesis_beacon_state(
        *, genesis_validator_deposits: Sequence[Deposit],
        genesis_time: Timestamp, genesis_eth1_data: Eth1Data,
        genesis_slot: Slot, genesis_epoch: Epoch, genesis_fork_version: int,
        genesis_start_shard: Shard, shard_count: int, min_seed_lookahead: int,
        slots_per_historical_root: int, latest_active_index_roots_length: int,
        slots_per_epoch: int, max_deposit_amount: Gwei,
        latest_slashed_exit_length: int, latest_randao_mixes_length: int,
        activation_exit_delay: int, deposit_contract_tree_depth: int,
        block_class: Type[BaseBeaconBlock]) -> BeaconState:
    state = BeaconState(
        # Misc
        slot=genesis_slot,
        genesis_time=genesis_time,
        fork=Fork(
            previous_version=genesis_fork_version.to_bytes(4, 'little'),
            current_version=genesis_fork_version.to_bytes(4, 'little'),
            epoch=genesis_epoch,
        ),

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

        # Randomness and committees
        latest_randao_mixes=(ZERO_HASH32, ) * latest_randao_mixes_length,
        previous_shuffling_start_shard=genesis_start_shard,
        current_shuffling_start_shard=genesis_start_shard,
        previous_shuffling_epoch=genesis_epoch,
        current_shuffling_epoch=genesis_epoch,
        previous_shuffling_seed=ZERO_HASH32,
        current_shuffling_seed=ZERO_HASH32,

        # Finality
        previous_epoch_attestations=(),
        current_epoch_attestations=(),
        previous_justified_epoch=genesis_epoch,
        current_justified_epoch=genesis_epoch,
        previous_justified_root=ZERO_HASH32,
        current_justified_root=ZERO_HASH32,
        justification_bitfield=0,
        finalized_epoch=genesis_epoch,
        finalized_root=ZERO_HASH32,

        # Recent state
        latest_crosslinks=((CrosslinkRecord(
            epoch=genesis_epoch, crosslink_data_root=ZERO_HASH32), ) *
                           shard_count),
        latest_block_roots=(ZERO_HASH32, ) * slots_per_historical_root,
        latest_state_roots=(ZERO_HASH32, ) * slots_per_historical_root,
        latest_active_index_roots=(ZERO_HASH32, ) *
        latest_active_index_roots_length,
        latest_slashed_balances=(Gwei(0), ) * latest_slashed_exit_length,
        latest_block_header=get_temporary_block_header(
            BeaconBlock.create_empty_block(genesis_slot), ),
        historical_roots=(),

        # Ethereum 1.0 chain data
        latest_eth1_data=genesis_eth1_data,
        eth1_data_votes=(),
        deposit_index=0,
    )

    # Process genesis deposits
    for deposit in genesis_validator_deposits:
        state = process_deposit(
            state=state,
            deposit=deposit,
            slots_per_epoch=slots_per_epoch,
            deposit_contract_tree_depth=deposit_contract_tree_depth,
        )

    # Process genesis 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,
                slots_per_epoch=slots_per_epoch,
                activation_exit_delay=activation_exit_delay,
            )

    # TODO: chanege to hash_tree_root
    active_validator_indices = get_active_validator_indices(
        state.validator_registry,
        genesis_epoch,
    )
    genesis_active_index_root = hash_eth2(b''.join(
        [index.to_bytes(32, 'little') for index in active_validator_indices]))
    latest_active_index_roots = (
        genesis_active_index_root, ) * latest_active_index_roots_length
    state = state.copy(latest_active_index_roots=latest_active_index_roots, )

    current_shuffling_seed = generate_seed(
        state=state,
        epoch=genesis_epoch,
        slots_per_epoch=slots_per_epoch,
        min_seed_lookahead=min_seed_lookahead,
        activation_exit_delay=activation_exit_delay,
        latest_active_index_roots_length=latest_active_index_roots_length,
        latest_randao_mixes_length=latest_randao_mixes_length,
    )
    state = state.copy(current_shuffling_seed=current_shuffling_seed, )

    return state
Exemple #21
0
def test_get_winning_root_and_participants(
        random, monkeypatch, target_committee_size, block_root_1_participants,
        block_root_2_participants, config, committee_config,
        n_validators_state, sample_attestation_data_params,
        sample_attestation_params):
    shard = 1
    committee = tuple([i for i in range(target_committee_size)])

    from eth2.beacon import committee_helpers

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

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

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

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

    state = n_validators_state.copy(previous_epoch_attestations=attestations, )
    effective_balances = {
        index: get_effective_balance(
            state.validator_balances,
            index,
            config.MAX_DEPOSIT_AMOUNT,
        )
        for index in range(len(state.validator_registry))
    }

    winning_root, attesting_validator_indices = get_winning_root_and_participants(
        state=state,
        shard=shard,
        effective_balances=effective_balances,
        committee_config=committee_config,
    )
    if len(attesting_validator_indices) == 0:
        assert len(block_root_1_participants) == 0 and len(
            block_root_2_participants) == 0
    else:
        if len(block_root_1_participants) == len(block_root_2_participants):
            if competing_block_roots[0] > competing_block_roots[1]:
                assert winning_root == competing_block_roots[0]
                assert set(attesting_validator_indices) == set(
                    block_root_1_participants)
            else:
                assert winning_root == competing_block_roots[1]
                assert set(attesting_validator_indices) == set(
                    block_root_2_participants)
        elif len(block_root_1_participants) < len(block_root_2_participants):
            assert winning_root == competing_block_roots[1]
            assert set(attesting_validator_indices) == set(
                block_root_2_participants)
        else:
            assert winning_root == competing_block_roots[0]
            assert set(attesting_validator_indices) == set(
                block_root_1_participants)
Exemple #22
0
def get_initial_beacon_state(*, initial_validator_deposits: Sequence[Deposit],
                             genesis_time: Timestamp,
                             latest_eth1_data: Eth1Data,
                             genesis_slot: SlotNumber,
                             genesis_fork_version: int,
                             genesis_start_shard: ShardNumber,
                             shard_count: int, latest_block_roots_length: int,
                             epoch_length: int, target_committee_size: int,
                             max_deposit: Ether,
                             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,
            slot=genesis_slot,
        ),

        # Validator registry
        validator_registry=(),
        validator_balances=(),
        validator_registry_update_slot=genesis_slot,
        validator_registry_exit_count=0,
        validator_registry_delta_chain_tip=ZERO_HASH32,

        # Randomness and committees
        latest_randao_mixes=tuple(ZERO_HASH32
                                  for _ in range(latest_randao_mixes_length)),
        latest_vdf_outputs=tuple(ZERO_HASH32
                                 for _ in range(latest_randao_mixes_length //
                                                epoch_length)),
        # TODO Remove `persistent_committees`, `persistent_committee_reassignments`
        persistent_committees=(),
        persistent_committee_reassignments=(),
        previous_epoch_start_shard=genesis_start_shard,
        current_epoch_start_shard=genesis_start_shard,
        previous_epoch_calculation_slot=genesis_slot,
        current_epoch_calculation_slot=genesis_slot,
        previous_epoch_randao_mix=ZERO_HASH32,
        current_epoch_randao_mix=ZERO_HASH32,

        # Custody challenges
        custody_challenges=(),

        # Finality
        previous_justified_slot=genesis_slot,
        justified_slot=genesis_slot,
        justification_bitfield=0,
        finalized_slot=genesis_slot,

        # Recent state
        latest_crosslinks=tuple([
            CrosslinkRecord(slot=genesis_slot, shard_block_root=ZERO_HASH32)
            for _ in range(shard_count)
        ]),
        latest_block_roots=tuple(ZERO_HASH32
                                 for _ in range(latest_block_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,
            custody_commitment=deposit.deposit_data.deposit_input.
            custody_commitment,
        )

    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,
        ) >= max_deposit * GWEI_PER_ETH
        if is_enough_effective_balance:
            state = activate_validator(
                state,
                validator_index,
                genesis=True,
                genesis_slot=genesis_slot,
                entry_exit_delay=entry_exit_delay,
            )

    return state