def run_process_registry_updates(state, valid=True):
    """
    Run ``process_crosslinks``, yielding:
      - pre-state ('pre')
      - post-state ('post').
    If ``valid == False``, run expecting ``AssertionError``
    """
    # transition state to slot before state transition
    slot = state.slot + (spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH) - 1
    block = build_empty_block_for_next_slot(state)
    block.slot = slot
    sign_block(state, block)
    state_transition(state, block)

    # cache state before epoch transition
    spec.cache_state(state)

    # process components of epoch transition before registry update
    spec.process_justification_and_finalization(state)
    spec.process_crosslinks(state)
    spec.process_rewards_and_penalties(state)

    yield 'pre', state
    process_registry_updates(state)
    yield 'post', state
Exemplo n.º 2
0
def next_epoch_with_attestations(state, fill_cur_epoch, fill_prev_epoch):
    post_state = deepcopy(state)
    blocks = []
    for _ in range(spec.SLOTS_PER_EPOCH):
        block = build_empty_block_for_next_slot(post_state)
        if fill_cur_epoch:
            slot_to_attest = post_state.slot - spec.MIN_ATTESTATION_INCLUSION_DELAY + 1
            if slot_to_attest >= get_epoch_start_slot(
                    get_current_epoch(post_state)):
                cur_attestation = get_valid_attestation(
                    post_state, slot_to_attest)
                fill_aggregate_attestation(post_state, cur_attestation)
                block.body.attestations.append(cur_attestation)

        if fill_prev_epoch:
            slot_to_attest = post_state.slot - spec.SLOTS_PER_EPOCH + 1
            prev_attestation = get_valid_attestation(post_state,
                                                     slot_to_attest)
            fill_aggregate_attestation(post_state, prev_attestation)
            block.body.attestations.append(prev_attestation)

        state_transition(post_state, block)
        blocks.append(block)

    return state, blocks, post_state
Exemplo n.º 3
0
def test_attester_slashing(state):
    test_state = deepcopy(state)
    attester_slashing = get_valid_attester_slashing(state)
    validator_index = attester_slashing.attestation_1.custody_bit_0_indices[0]

    #
    # Add to state via block transition
    #
    block = build_empty_block_for_next_slot(test_state)
    block.body.attester_slashings.append(attester_slashing)
    state_transition(test_state, block)

    assert not state.validator_registry[validator_index].slashed

    slashed_validator = test_state.validator_registry[validator_index]
    assert slashed_validator.slashed
    assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH
    assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH
    # lost whistleblower reward
    assert get_balance(test_state, validator_index) < get_balance(
        state, validator_index)

    proposer_index = get_beacon_proposer_index(test_state)
    # gained whistleblower reward
    assert (get_balance(test_state, proposer_index) > get_balance(
        state, proposer_index))

    return state, [block], test_state
Exemplo n.º 4
0
def test_attestation(state):
    state.slot = spec.SLOTS_PER_EPOCH
    test_state = deepcopy(state)
    attestation = get_valid_attestation(state)

    #
    # Add to state via block transition
    #
    attestation_block = build_empty_block_for_next_slot(test_state)
    attestation_block.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
    attestation_block.body.attestations.append(attestation)
    state_transition(test_state, attestation_block)

    assert len(test_state.current_epoch_attestations) == len(
        state.current_epoch_attestations) + 1

    #
    # Epoch transition should move to previous_epoch_attestations
    #
    pre_current_epoch_attestations = deepcopy(
        test_state.current_epoch_attestations)

    epoch_block = build_empty_block_for_next_slot(test_state)
    epoch_block.slot += spec.SLOTS_PER_EPOCH
    state_transition(test_state, epoch_block)

    assert len(test_state.current_epoch_attestations) == 0
    assert test_state.previous_epoch_attestations == pre_current_epoch_attestations

    return state, [attestation_block, epoch_block], test_state
Exemplo n.º 5
0
def test_transfer(state):
    # overwrite default 0 to test
    spec.MAX_TRANSFERS = 1

    sender_index = get_active_validator_indices(state, get_current_epoch(state))[-1]
    amount = get_balance(state, sender_index)

    transfer = get_valid_transfer(state, state.slot + 1, sender_index, amount, signed=True)
    recipient_index = transfer.recipient
    pre_transfer_recipient_balance = get_balance(state, recipient_index)

    # un-activate so validator can transfer
    state.validator_registry[sender_index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH

    yield 'pre', state

    # Add to state via block transition
    block = build_empty_block_for_next_slot(state)
    block.body.transfers.append(transfer)
    sign_block(state, block)

    yield 'blocks', [block], [spec.BeaconBlock]

    state_transition(state, block)
    yield 'post', state

    sender_balance = get_balance(state, sender_index)
    recipient_balance = get_balance(state, recipient_index)
    assert sender_balance == 0
    assert recipient_balance == pre_transfer_recipient_balance + amount
Exemplo n.º 6
0
def test_proposer_slashing(state):
    # copy for later balance lookups.
    pre_state = deepcopy(state)
    proposer_slashing = get_valid_proposer_slashing(state, signed_1=True, signed_2=True)
    validator_index = proposer_slashing.proposer_index

    assert not state.validator_registry[validator_index].slashed

    yield 'pre', state

    #
    # Add to state via block transition
    #
    block = build_empty_block_for_next_slot(state)
    block.body.proposer_slashings.append(proposer_slashing)
    sign_block(state, block)
    yield 'blocks', [block], [spec.BeaconBlock]

    state_transition(state, block)
    yield 'post', state

    # check if slashed
    slashed_validator = state.validator_registry[validator_index]
    assert slashed_validator.slashed
    assert slashed_validator.exit_epoch < spec.FAR_FUTURE_EPOCH
    assert slashed_validator.withdrawable_epoch < spec.FAR_FUTURE_EPOCH
    # lost whistleblower reward
    assert get_balance(state, validator_index) < get_balance(pre_state, validator_index)
Exemplo n.º 7
0
def test_attestation(state):
    state.slot = spec.SLOTS_PER_EPOCH

    yield 'pre', state

    attestation = get_valid_attestation(state, signed=True)

    # Add to state via block transition
    pre_current_attestations_len = len(state.current_epoch_attestations)
    attestation_block = build_empty_block_for_next_slot(state)
    attestation_block.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
    attestation_block.body.attestations.append(attestation)
    sign_block(state, attestation_block)
    state_transition(state, attestation_block)

    assert len(state.current_epoch_attestations) == pre_current_attestations_len + 1

    # Epoch transition should move to previous_epoch_attestations
    pre_current_attestations_root = spec.hash_tree_root(state.current_epoch_attestations)

    epoch_block = build_empty_block_for_next_slot(state)
    epoch_block.slot += spec.SLOTS_PER_EPOCH
    sign_block(state, epoch_block)
    state_transition(state, epoch_block)

    yield 'blocks', [attestation_block, epoch_block], [spec.BeaconBlock]
    yield 'post', state

    assert len(state.current_epoch_attestations) == 0
    assert spec.hash_tree_root(state.previous_epoch_attestations) == pre_current_attestations_root
Exemplo n.º 8
0
def add_attestation_to_state(state, attestation, slot):
    block = build_empty_block_for_next_slot(state)
    block.slot = slot
    block.body.attestations.append(attestation)
    state_transition_to(state, block.slot)
    sign_block(state, block)
    state_transition(state, block)
Exemplo n.º 9
0
def next_slot(state):
    """
    Transition to the next slot via an empty block.
    Return the empty block that triggered the transition.
    """
    block = build_empty_block_for_next_slot(state)
    state_transition(state, block)
    return block
Exemplo n.º 10
0
def apply_empty_block(state):
    """
    Transition via an empty block (on current slot, assuming no block has been applied yet).
    :return: the empty block that triggered the transition.
    """
    block = build_empty_block(state, signed=True)
    state_transition(state, block)
    return block
def test_success_prevous_epoch(state):
    attestation = get_valid_attestation(state)
    block = build_empty_block_for_next_slot(state)
    block.slot = state.slot + spec.SLOTS_PER_EPOCH
    state_transition(state, block)

    pre_state, post_state = run_attestation_processing(state, attestation)

    return pre_state, attestation, post_state
Exemplo n.º 12
0
def next_epoch(state):
    """
    Transition to the start slot of the next epoch via an empty block.
    Return the empty block that triggered the transition.
    """
    block = build_empty_block_for_next_slot(state)
    block.slot += spec.SLOTS_PER_EPOCH - (state.slot % spec.SLOTS_PER_EPOCH)
    state_transition(state, block)
    return block
Exemplo n.º 13
0
def test_after_epoch_slots(state):
    attestation = get_valid_attestation(state)
    block = build_empty_block_for_next_slot(state)
    # increment past latest inclusion slot
    block.slot = state.slot + spec.SLOTS_PER_EPOCH + 1
    state_transition(state, block)

    pre_state, post_state = run_attestation_processing(state, attestation, False)

    return pre_state, attestation, post_state
Exemplo n.º 14
0
def test_empty_block_transition(state):
    test_state = deepcopy(state)

    block = build_empty_block_for_next_slot(test_state)
    state_transition(test_state, block)

    assert len(test_state.eth1_data_votes) == len(state.eth1_data_votes) + 1
    assert get_block_root_at_slot(test_state,
                                  state.slot) == block.previous_block_root

    return state, [block], test_state
Exemplo n.º 15
0
def test_skipped_slots(state):
    test_state = deepcopy(state)
    block = build_empty_block_for_next_slot(test_state)
    block.slot += 3

    state_transition(test_state, block)

    assert test_state.slot == block.slot
    for slot in range(state.slot, test_state.slot):
        assert get_block_root_at_slot(test_state,
                                      slot) == block.previous_block_root

    return state, [block], test_state
Exemplo n.º 16
0
def test_empty_epoch_transition(state):
    test_state = deepcopy(state)
    block = build_empty_block_for_next_slot(test_state)
    block.slot += spec.SLOTS_PER_EPOCH

    state_transition(test_state, block)

    assert test_state.slot == block.slot
    for slot in range(state.slot, test_state.slot):
        assert get_block_root_at_slot(test_state,
                                      slot) == block.previous_block_root

    return state, [block], test_state
Exemplo n.º 17
0
def test_empty_epoch_transition_not_finalizing(state):
    test_state = deepcopy(state)
    block = build_empty_block_for_next_slot(test_state)
    block.slot += spec.SLOTS_PER_EPOCH * 5

    state_transition(test_state, block)

    assert test_state.slot == block.slot
    assert test_state.finalized_epoch < get_current_epoch(test_state) - 4
    for index in range(len(test_state.validator_registry)):
        assert get_balance(test_state, index) < get_balance(state, index)

    return state, [block], test_state
Exemplo n.º 18
0
def test_empty_block_transition(state):
    pre_slot = state.slot
    pre_eth1_votes = len(state.eth1_data_votes)

    yield 'pre', state

    block = build_empty_block_for_next_slot(state, signed=True)
    yield 'blocks', [block], [spec.BeaconBlock]

    state_transition(state, block)
    yield 'post', state

    assert len(state.eth1_data_votes) == pre_eth1_votes + 1
    assert get_block_root_at_slot(state, pre_slot) == block.previous_block_root
Exemplo n.º 19
0
def run_process_crosslinks(state, valid=True):
    # transition state to slot before state transition
    slot = state.slot + (spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH) - 1
    block = build_empty_block_for_next_slot(state)
    block.slot = slot
    state_transition(state, block)

    # cache state before epoch transition
    cache_state(state)

    post_state = deepcopy(state)
    process_crosslinks(post_state)

    return state, post_state
Exemplo n.º 20
0
def test_historical_batch(state):
    state.slot += spec.SLOTS_PER_HISTORICAL_ROOT - (state.slot % spec.SLOTS_PER_HISTORICAL_ROOT) - 1
    pre_historical_roots_len = len(state.historical_roots)

    yield 'pre', state

    block = build_empty_block_for_next_slot(state, signed=True)
    state_transition(state, block)

    yield 'blocks', [block], [spec.BeaconBlock]
    yield 'post', state

    assert state.slot == block.slot
    assert get_current_epoch(state) % (spec.SLOTS_PER_HISTORICAL_ROOT // spec.SLOTS_PER_EPOCH) == 0
    assert len(state.historical_roots) == pre_historical_roots_len + 1
Exemplo n.º 21
0
def test_empty_epoch_transition(state):
    pre_slot = state.slot
    yield 'pre', state

    block = build_empty_block_for_next_slot(state)
    block.slot += spec.SLOTS_PER_EPOCH
    sign_block(state, block)
    yield 'blocks', [block], [spec.BeaconBlock]

    state_transition(state, block)
    yield 'post', state

    assert state.slot == block.slot
    for slot in range(pre_slot, state.slot):
        assert get_block_root_at_slot(state, slot) == block.previous_block_root
Exemplo n.º 22
0
def test_transfer(state):
    # overwrite default 0 to test
    spec.MAX_TRANSFERS = 1

    pre_state = deepcopy(state)
    current_epoch = get_current_epoch(pre_state)
    sender_index = get_active_validator_indices(pre_state, current_epoch)[-1]
    recipient_index = get_active_validator_indices(pre_state, current_epoch)[0]
    transfer_pubkey = pubkeys[-1]
    transfer_privkey = privkeys[-1]
    amount = get_balance(pre_state, sender_index)
    pre_transfer_recipient_balance = get_balance(pre_state, recipient_index)
    transfer = Transfer(
        sender=sender_index,
        recipient=recipient_index,
        amount=amount,
        fee=0,
        slot=pre_state.slot + 1,
        pubkey=transfer_pubkey,
    )
    transfer.signature = bls.sign(message_hash=signing_root(transfer),
                                  privkey=transfer_privkey,
                                  domain=get_domain(
                                      state=pre_state,
                                      domain_type=spec.DOMAIN_TRANSFER,
                                  ))

    # ensure withdrawal_credentials reproducable
    pre_state.validator_registry[sender_index].withdrawal_credentials = (
        spec.BLS_WITHDRAWAL_PREFIX_BYTE + hash(transfer_pubkey)[1:])
    # un-activate so validator can transfer
    pre_state.validator_registry[
        sender_index].activation_eligibility_epoch = spec.FAR_FUTURE_EPOCH

    post_state = deepcopy(pre_state)
    #
    # Add to state via block transition
    #
    block = build_empty_block_for_next_slot(post_state)
    block.body.transfers.append(transfer)
    state_transition(post_state, block)

    sender_balance = get_balance(post_state, sender_index)
    recipient_balance = get_balance(post_state, recipient_index)
    assert sender_balance == 0
    assert recipient_balance == pre_transfer_recipient_balance + amount

    return pre_state, [block], post_state
Exemplo n.º 23
0
def test_historical_batch(state):
    state.slot += spec.SLOTS_PER_HISTORICAL_ROOT - (
        state.slot % spec.SLOTS_PER_HISTORICAL_ROOT) - 1

    post_state = deepcopy(state)

    block = build_empty_block_for_next_slot(post_state)

    state_transition(post_state, block)

    assert post_state.slot == block.slot
    assert get_current_epoch(post_state) % (spec.SLOTS_PER_HISTORICAL_ROOT //
                                            spec.SLOTS_PER_EPOCH) == 0
    assert len(post_state.historical_roots) == len(state.historical_roots) + 1

    return state, [block], post_state
Exemplo n.º 24
0
def test_voluntary_exit(state):
    pre_state = deepcopy(state)
    validator_index = get_active_validator_indices(
        pre_state, get_current_epoch(pre_state))[-1]

    # move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
    pre_state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

    post_state = deepcopy(pre_state)

    voluntary_exit = VoluntaryExit(
        epoch=get_current_epoch(pre_state),
        validator_index=validator_index,
    )
    voluntary_exit.signature = bls.sign(
        message_hash=signing_root(voluntary_exit),
        privkey=privkeys[validator_index],
        domain=get_domain(
            state=pre_state,
            domain_type=spec.DOMAIN_VOLUNTARY_EXIT,
        ))

    #
    # Add to state via block transition
    #
    initiate_exit_block = build_empty_block_for_next_slot(post_state)
    initiate_exit_block.body.voluntary_exits.append(voluntary_exit)
    state_transition(post_state, initiate_exit_block)

    assert post_state.validator_registry[
        validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH

    #
    # Process within epoch transition
    #
    exit_block = build_empty_block_for_next_slot(post_state)
    exit_block.slot += spec.SLOTS_PER_EPOCH
    state_transition(post_state, exit_block)

    assert post_state.validator_registry[
        validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH

    return pre_state, [initiate_exit_block, exit_block], post_state
Exemplo n.º 25
0
def test_voluntary_exit(state):
    validator_index = get_active_validator_indices(
        state,
        get_current_epoch(state)
    )[-1]

    # move state forward PERSISTENT_COMMITTEE_PERIOD epochs to allow for exit
    state.slot += spec.PERSISTENT_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

    yield 'pre', state

    voluntary_exit = VoluntaryExit(
        epoch=get_current_epoch(state),
        validator_index=validator_index,
    )
    voluntary_exit.signature = bls_sign(
        message_hash=signing_root(voluntary_exit),
        privkey=privkeys[validator_index],
        domain=get_domain(
            state=state,
            domain_type=spec.DOMAIN_VOLUNTARY_EXIT,
        )
    )

    # Add to state via block transition
    initiate_exit_block = build_empty_block_for_next_slot(state)
    initiate_exit_block.body.voluntary_exits.append(voluntary_exit)
    sign_block(state, initiate_exit_block)
    state_transition(state, initiate_exit_block)

    assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH

    # Process within epoch transition
    exit_block = build_empty_block_for_next_slot(state)
    exit_block.slot += spec.SLOTS_PER_EPOCH
    sign_block(state, exit_block)
    state_transition(state, exit_block)

    yield 'blocks', [initiate_exit_block, exit_block], [spec.BeaconBlock]
    yield 'post', state

    assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
Exemplo n.º 26
0
def test_balance_driven_status_transitions(state):
    current_epoch = get_current_epoch(state)
    validator_index = get_active_validator_indices(state, current_epoch)[-1]

    assert state.validator_registry[validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH

    # set validator balance to below ejection threshold
    state.validator_registry[validator_index].effective_balance = spec.EJECTION_BALANCE

    yield 'pre', state

    # trigger epoch transition
    block = build_empty_block_for_next_slot(state)
    block.slot += spec.SLOTS_PER_EPOCH
    sign_block(state, block)
    state_transition(state, block)

    yield 'blocks', [block], [spec.BeaconBlock]
    yield 'post', state

    assert state.validator_registry[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
Exemplo n.º 27
0
def run_process_crosslinks(state, valid=True):
    """
    Run ``process_crosslinks``, yielding:
      - pre-state ('pre')
      - post-state ('post').
    If ``valid == False``, run expecting ``AssertionError``
    """
    # transition state to slot before state transition
    slot = state.slot + (spec.SLOTS_PER_EPOCH -
                         state.slot % spec.SLOTS_PER_EPOCH) - 1
    block = build_empty_block_for_next_slot(state)
    block.slot = slot
    sign_block(state, block)
    state_transition(state, block)

    # cache state before epoch transition
    cache_state(state)

    yield 'pre', state
    process_crosslinks(state)
    yield 'post', state
Exemplo n.º 28
0
def test_deposit_top_up(state):
    pre_state = deepcopy(state)
    test_deposit_data_leaves = [ZERO_HASH] * len(pre_state.validator_registry)

    validator_index = 0
    amount = spec.MAX_EFFECTIVE_BALANCE // 4
    pubkey = pubkeys[validator_index]
    privkey = privkeys[validator_index]
    deposit_data = build_deposit_data(pre_state, pubkey, privkey, amount)

    merkle_index = len(test_deposit_data_leaves)
    item = deposit_data.hash_tree_root()
    test_deposit_data_leaves.append(item)
    tree = calc_merkle_tree_from_leaves(tuple(test_deposit_data_leaves))
    root = get_merkle_root((tuple(test_deposit_data_leaves)))
    proof = list(get_merkle_proof(tree, item_index=merkle_index))
    assert verify_merkle_branch(item, proof, spec.DEPOSIT_CONTRACT_TREE_DEPTH,
                                merkle_index, root)

    deposit = Deposit(
        proof=list(proof),
        index=merkle_index,
        data=deposit_data,
    )

    pre_state.latest_eth1_data.deposit_root = root
    pre_state.latest_eth1_data.deposit_count = len(test_deposit_data_leaves)
    block = build_empty_block_for_next_slot(pre_state)
    block.body.deposits.append(deposit)

    pre_balance = get_balance(pre_state, validator_index)
    post_state = deepcopy(pre_state)
    state_transition(post_state, block)
    assert len(post_state.validator_registry) == len(
        pre_state.validator_registry)
    assert len(post_state.balances) == len(pre_state.balances)
    assert get_balance(post_state, validator_index) == pre_balance + amount

    return pre_state, [block], post_state
Exemplo n.º 29
0
def test_eth1_data_votes(state):
    post_state = deepcopy(state)

    expected_votes = 0
    assert len(state.eth1_data_votes) == expected_votes

    blocks = []
    for _ in range(spec.SLOTS_PER_ETH1_VOTING_PERIOD - 1):
        block = build_empty_block_for_next_slot(post_state)
        state_transition(post_state, block)
        expected_votes += 1
        assert len(post_state.eth1_data_votes) == expected_votes
        blocks.append(block)

    block = build_empty_block_for_next_slot(post_state)
    state_transition(post_state, block)
    blocks.append(block)

    assert post_state.slot % spec.SLOTS_PER_ETH1_VOTING_PERIOD == 0
    assert len(post_state.eth1_data_votes) == 1

    return state, blocks, post_state
Exemplo n.º 30
0
def test_balance_driven_status_transitions(state):
    current_epoch = get_current_epoch(state)
    validator_index = get_active_validator_indices(state, current_epoch)[-1]

    assert state.validator_registry[
        validator_index].exit_epoch == spec.FAR_FUTURE_EPOCH

    # set validator balance to below ejection threshold
    state.validator_registry[
        validator_index].effective_balance = spec.EJECTION_BALANCE

    post_state = deepcopy(state)
    #
    # trigger epoch transition
    #
    block = build_empty_block_for_next_slot(post_state)
    block.slot += spec.SLOTS_PER_EPOCH
    state_transition(post_state, block)

    assert post_state.validator_registry[
        validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH

    return state, [block], post_state