Пример #1
0
def test_invalid_proposer_index_sig_from_proposer_index(spec, state):
    yield 'pre', state

    block = build_empty_block_for_next_slot(spec, state)

    # Set invalid proposer index but correct signature wrt proposer_index
    active_indices = spec.get_active_validator_indices(state, spec.get_current_epoch(state))
    active_indices = [i for i in active_indices if i != block.proposer_index]
    block.proposer_index = active_indices[0]  # invalid proposer index

    invalid_signed_block = sign_block(spec, state, block, block.proposer_index)

    expect_assertion_error(lambda: spec.state_transition(state, invalid_signed_block))

    yield 'blocks', [invalid_signed_block]
    yield 'post', None
def test_invalid_signature_bad_domain(spec, state):
    committee_indices = compute_committee_indices(spec, state)

    block = build_empty_block_for_next_slot(spec, state)
    block.body.sync_aggregate = spec.SyncAggregate(
        sync_committee_bits=[True] * len(committee_indices),
        sync_committee_signature=compute_aggregate_sync_committee_signature(
            spec,
            state,
            block.slot - 1,
            committee_indices,  # full committee signs
            block_root=block.parent_root,
            domain_type=spec.DOMAIN_BEACON_ATTESTER,  # Incorrect domain
        )
    )
    yield from run_sync_committee_processing(spec, state, block, expect_exception=True)
Пример #3
0
def test_on_attestation_future_epoch(spec, state):
    store = spec.get_forkchoice_store(state)
    time = store.time + 3 * spec.SECONDS_PER_SLOT
    spec.on_tick(store, time)

    block = build_empty_block_for_next_slot(spec, state)
    signed_block = state_transition_and_sign_block(spec, state, block)

    # store block in store
    spec.on_block(store, signed_block)

    # move state forward but not store
    next_epoch(spec, state)

    attestation = get_valid_attestation(spec, state, slot=state.slot, signed=True)
    run_on_attestation(spec, state, store, attestation, False)
Пример #4
0
def test_on_attestation_future_block(spec, state):
    store = spec.get_forkchoice_store(state)
    time = store.time + spec.SECONDS_PER_SLOT * 5
    spec.on_tick(store, time)

    block = build_empty_block_for_next_slot(spec, state)
    signed_block = state_transition_and_sign_block(spec, state, block)

    spec.on_block(store, signed_block)

    # attestation for slot immediately prior to the block being attested to
    attestation = get_valid_attestation(spec, state, slot=block.slot - 1, signed=False)
    attestation.data.beacon_block_root = block.hash_tree_root()
    sign_attestation(spec, state, attestation)

    run_on_attestation(spec, state, store, attestation, False)
Пример #5
0
def test_empty_epoch_transition(spec, state):
    pre_slot = state.slot
    yield 'pre', state

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

    state_transition_and_sign_block(spec, state, block)

    yield 'blocks', [block]
    yield 'post', state

    assert state.slot == block.slot
    for slot in range(pre_slot, state.slot):
        assert spec.get_block_root_at_slot(state, slot) == block.parent_root
Пример #6
0
def test_on_block_bad_parent_root(spec, state):
    # Initialization
    store = spec.get_genesis_store(state)
    time = 100
    spec.on_tick(store, time)

    # Fail receiving block of `GENESIS_SLOT + 1` slot
    block = build_empty_block_for_next_slot(spec, state)
    transition_unsigned_block(spec, state, block)
    block.state_root = state.hash_tree_root()

    block.parent_root = b'\x45' * 32

    signed_block = sign_block(spec, state, block)

    run_on_block(spec, store, signed_block, False)
Пример #7
0
def test_on_attestation_future_epoch(spec, state):
    store = spec.get_genesis_store(state)
    time = 3 * spec.SECONDS_PER_SLOT
    spec.on_tick(store, time)

    block = build_empty_block_for_next_slot(spec, state)
    state_transition_and_sign_block(spec, state, block)

    # store block in store
    spec.on_block(store, block)

    # move state forward but not store
    state.slot = block.slot + spec.SLOTS_PER_EPOCH

    attestation = get_valid_attestation(spec, state, slot=state.slot)
    run_on_attestation(spec, state, store, attestation, False)
Пример #8
0
def test_invalid_block_sig(spec, state):
    yield 'pre', state

    block = build_empty_block_for_next_slot(spec, state)
    invalid_signed_block = spec.SignedBeaconBlock(
        message=block,
        signature=bls_sign(message_hash=hash_tree_root(block),
                           privkey=123456,
                           domain=spec.get_domain(
                               state, spec.DOMAIN_BEACON_PROPOSER,
                               spec.compute_epoch_at_slot(block.slot))))
    expect_assertion_error(
        lambda: spec.state_transition(state, invalid_signed_block))

    yield 'blocks', [invalid_signed_block]
    yield 'post', None
Пример #9
0
def build_attestation_data(spec, state, slot, shard):
    assert state.slot >= slot

    if slot == state.slot:
        block_root = build_empty_block_for_next_slot(spec, state).parent_root
    else:
        block_root = spec.get_block_root_at_slot(state, slot)

    current_epoch_start_slot = spec.get_epoch_start_slot(
        spec.get_current_epoch(state))
    if slot < current_epoch_start_slot:
        epoch_boundary_root = spec.get_block_root(
            state, spec.get_previous_epoch(state))
    elif slot == current_epoch_start_slot:
        epoch_boundary_root = block_root
    else:
        epoch_boundary_root = spec.get_block_root(
            state, spec.get_current_epoch(state))

    if slot < current_epoch_start_slot:
        justified_epoch = state.previous_justified_epoch
        justified_block_root = state.previous_justified_root
    else:
        justified_epoch = state.current_justified_epoch
        justified_block_root = state.current_justified_root

    if spec.slot_to_epoch(slot) == spec.get_current_epoch(state):
        parent_crosslink = state.current_crosslinks[shard]
    else:
        parent_crosslink = state.previous_crosslinks[shard]

    return spec.AttestationData(
        beacon_block_root=block_root,
        source_epoch=justified_epoch,
        source_root=justified_block_root,
        target_epoch=spec.slot_to_epoch(slot),
        target_root=epoch_boundary_root,
        crosslink=spec.Crosslink(
            shard=shard,
            start_epoch=parent_crosslink.end_epoch,
            end_epoch=min(
                spec.slot_to_epoch(slot),
                parent_crosslink.end_epoch + spec.MAX_EPOCHS_PER_CROSSLINK),
            data_root=spec.ZERO_HASH,
            parent_root=hash_tree_root(parent_crosslink),
        ),
    )
Пример #10
0
def test_on_block_finalized_skip_slots_not_in_skip_chain(spec, state):
    """
    Test case was originally from https://github.com/ethereum/consensus-specs/pull/1579
    And then rewrote largely.
    """
    test_steps = []
    # Initialization
    store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state)
    yield 'anchor_state', state
    yield 'anchor_block', anchor_block
    current_time = state.slot * spec.config.SECONDS_PER_SLOT + store.genesis_time
    on_tick_and_append_step(spec, store, current_time, test_steps)
    assert store.time == current_time

    # Fill epoch 0 and the first slot of epoch 1
    state, store, _ = yield from apply_next_slots_with_attestations(
        spec, state, store, spec.SLOTS_PER_EPOCH, True, False, test_steps)

    # Skip the rest slots of epoch 1 and the first slot of epoch 2
    next_slots(spec, state, spec.SLOTS_PER_EPOCH)

    # Fill epoch 3 and 4
    for _ in range(2):
        state, store, _ = yield from apply_next_epoch_with_attestations(
            spec, state, store, True, True, test_steps=test_steps)

    # Now we get finalized epoch 2, where `compute_start_slot_at_epoch(2)` is a skipped slot
    assert state.finalized_checkpoint.epoch == store.finalized_checkpoint.epoch == 2
    assert store.finalized_checkpoint.root == spec.get_block_root(
        state, 1) == spec.get_block_root(state, 2)
    assert state.current_justified_checkpoint.epoch == store.justified_checkpoint.epoch == 3
    assert store.justified_checkpoint == state.current_justified_checkpoint

    # Now build a block after the block of the finalized **root**
    # Includes finalized block in chain, but does not include finalized skipped slots
    another_state = store.block_states[store.finalized_checkpoint.root].copy()
    assert another_state.slot == spec.compute_start_slot_at_epoch(
        store.finalized_checkpoint.epoch - 1)
    block = build_empty_block_for_next_slot(spec, another_state)
    signed_block = state_transition_and_sign_block(spec, another_state, block)
    yield from tick_and_add_block(spec,
                                  store,
                                  signed_block,
                                  test_steps,
                                  valid=False)

    yield 'steps', test_steps
Пример #11
0
def test_on_attestation_previous_epoch(spec, state):
    store = spec.get_genesis_store(state)
    spec.on_tick(store,
                 store.time + spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH)

    block = build_empty_block_for_next_slot(spec, state)
    state_transition_and_sign_block(spec, state, block)

    # store block in store
    spec.on_block(store, block)

    attestation = get_valid_attestation(spec, state, slot=block.slot)
    assert attestation.data.target.epoch == spec.GENESIS_EPOCH
    assert spec.compute_epoch_at_slot(
        spec.get_current_slot(store)) == spec.GENESIS_EPOCH + 1

    run_on_attestation(spec, state, store, attestation)
Пример #12
0
def test_invalid_signature_missing_participant(spec, state):
    committee_indices = compute_committee_indices(spec, state, state.current_sync_committee)
    rng = random.Random(2020)
    random_participant = rng.choice(committee_indices)

    block = build_empty_block_for_next_slot(spec, state)
    # Exclude one participant whose signature was included.
    block.body.sync_aggregate = spec.SyncAggregate(
        sync_committee_bits=[index != random_participant for index in committee_indices],
        sync_committee_signature=compute_aggregate_sync_committee_signature(
            spec,
            state,
            block.slot - 1,
            committee_indices,  # full committee signs
        )
    )
    yield from run_sync_committee_processing(spec, state, block, expect_exception=True)
Пример #13
0
def test_historical_batch(spec, 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(spec, state)
    signed_block = state_transition_and_sign_block(spec, state, block)

    yield 'blocks', [signed_block]
    yield 'post', state

    assert state.slot == block.slot
    assert spec.get_current_epoch(state) % (spec.SLOTS_PER_HISTORICAL_ROOT //
                                            spec.SLOTS_PER_EPOCH) == 0
    assert len(state.historical_roots) == pre_historical_roots_len + 1
Пример #14
0
def test_skipped_slots(spec, state):
    pre_slot = state.slot
    yield 'pre', state

    block = build_empty_block_for_next_slot(spec, state)
    block.slot += 3
    sign_block(spec, state, block)

    state_transition_and_sign_block(spec, state, block)

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

    assert state.slot == block.slot
    assert spec.get_randao_mix(state, spec.get_current_epoch(state)) != spec.ZERO_HASH
    for slot in range(pre_slot, state.slot):
        assert spec.get_block_root_at_slot(state, slot) == block.parent_root
Пример #15
0
def test_on_block_future_block(spec, state):
    test_steps = []
    # Initialization
    store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state)
    yield 'anchor_state', state
    yield 'anchor_block', anchor_block
    current_time = state.slot * spec.config.SECONDS_PER_SLOT + store.genesis_time
    on_tick_and_append_step(spec, store, current_time, test_steps)
    assert store.time == current_time

    # Do NOT tick time to `GENESIS_SLOT + 1` slot
    # Fail receiving block of `GENESIS_SLOT + 1` slot
    block = build_empty_block_for_next_slot(spec, state)
    signed_block = state_transition_and_sign_block(spec, state, block)
    yield from add_block(spec, store, signed_block, test_steps, valid=False)

    yield 'steps', test_steps
Пример #16
0
def test_empty_block_transition_large_validator_set(spec, state):
    pre_slot = state.slot
    pre_eth1_votes = len(state.eth1_data_votes)
    pre_mix = spec.get_randao_mix(state, spec.get_current_epoch(state))

    yield 'pre', state

    block = build_empty_block_for_next_slot(spec, state)

    signed_block = state_transition_and_sign_block(spec, state, block)

    yield 'blocks', [signed_block]
    yield 'post', state

    assert len(state.eth1_data_votes) == pre_eth1_votes + 1
    assert spec.get_block_root_at_slot(state, pre_slot) == signed_block.message.parent_root
    assert spec.get_randao_mix(state, spec.get_current_epoch(state)) != pre_mix
Пример #17
0
def test_empty_block_transition(spec, state):
    pre_slot = state.slot
    pre_eth1_votes = len(state.eth1_data_votes)

    yield 'pre', state

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

    state_transition_and_sign_block(spec, state, block)

    yield 'blocks', [block]
    yield 'post', state

    assert len(state.eth1_data_votes) == pre_eth1_votes + 1
    assert spec.get_block_root_at_slot(state, pre_slot) == block.parent_root
    assert spec.get_randao_mix(
        state, spec.get_current_epoch(state)) != spec.Bytes32()
Пример #18
0
def test_double_validator_exit_same_block(spec, state):
    validator_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1]

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

    # Same index tries to exit twice, but should only be able to do so once.
    signed_exits = prepare_signed_exits(spec, state, [validator_index, validator_index])
    yield 'pre', state

    # Add to state via block transition
    initiate_exit_block = build_empty_block_for_next_slot(spec, state)
    initiate_exit_block.body.voluntary_exits = signed_exits
    signed_initiate_exit_block = state_transition_and_sign_block(spec, state, initiate_exit_block, expect_fail=True)

    yield 'blocks', [signed_initiate_exit_block]
    yield 'post', None
Пример #19
0
def _build_block_for_next_slot_with_sync_participation(spec, state,
                                                       committee_indices,
                                                       committee_bits):
    block = build_empty_block_for_next_slot(spec, state)
    block.body.sync_aggregate = spec.SyncAggregate(
        sync_committee_bits=committee_bits,
        sync_committee_signature=compute_aggregate_sync_committee_signature(
            spec,
            state,
            block.slot - 1,
            [
                index
                for index, bit in zip(committee_indices, committee_bits) if bit
            ],
            block_root=block.parent_root,
        ))
    return block
Пример #20
0
def test_on_attestation_target_not_in_store(spec, state):
    store = spec.get_genesis_store(state)
    time = spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH
    spec.on_tick(store, time)

    # move to immediately before next epoch to make block new target
    transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH - 1)

    target_block = build_empty_block_for_next_slot(spec, state)
    state_transition_and_sign_block(spec, state, target_block)

    # do not add target block to store

    attestation = get_valid_attestation(spec, state, slot=target_block.slot)
    assert attestation.data.target.root == target_block.signing_root()

    run_on_attestation(spec, state, store, attestation, False)
Пример #21
0
def test_multiple_attester_slashings_partial_overlap(spec, state):
    if spec.MAX_ATTESTER_SLASHINGS < 2:
        return dump_skipping_message(
            "Skip test if config cannot handle multiple AttesterSlashings per block"
        )

    # copy for later balance lookups.
    pre_state = state.copy()

    full_indices = spec.get_active_validator_indices(
        state, spec.get_current_epoch(state))[:8]
    one_third_length = len(full_indices) // 3

    attester_slashing_1 = get_valid_attester_slashing_by_indices(
        spec,
        state,
        full_indices[:one_third_length * 2],
        signed_1=True,
        signed_2=True,
    )
    attester_slashing_2 = get_valid_attester_slashing_by_indices(
        spec,
        state,
        full_indices[one_third_length:],
        signed_1=True,
        signed_2=True,
    )
    attester_slashings = [attester_slashing_1, attester_slashing_2]

    assert not any(state.validators[i].slashed for i in full_indices)

    yield 'pre', state

    #
    # Add to state via block transition
    #
    block = build_empty_block_for_next_slot(spec, state)
    block.body.attester_slashings = attester_slashings

    signed_block = state_transition_and_sign_block(spec, state, block)

    yield 'blocks', [signed_block]
    yield 'post', state

    check_attester_slashing_effect(spec, pre_state, state, full_indices)
def test_on_attestation_target_block_not_in_store(spec, state):
    store = get_genesis_forkchoice_store(spec, state)
    time = store.time + spec.config.SECONDS_PER_SLOT * (spec.SLOTS_PER_EPOCH + 1)
    spec.on_tick(store, time)

    # move to immediately before next epoch to make block new target
    next_epoch = spec.get_current_epoch(state) + 1
    transition_to(spec, state, spec.compute_start_slot_at_epoch(next_epoch) - 1)

    target_block = build_empty_block_for_next_slot(spec, state)
    state_transition_and_sign_block(spec, state, target_block)

    # do not add target block to store

    attestation = get_valid_attestation(spec, state, slot=target_block.slot, signed=True)
    assert attestation.data.target.root == target_block.hash_tree_root()

    run_on_attestation(spec, state, store, attestation, False)
Пример #23
0
def test_basic(spec, state):
    # Initialization
    store = get_genesis_forkchoice_store(spec, state)
    time = 100
    spec.on_tick(store, time)
    assert store.time == time

    # On receiving a block of `GENESIS_SLOT + 1` slot
    block = build_empty_block_for_next_slot(spec, state)
    signed_block = state_transition_and_sign_block(spec, state, block)
    run_on_block(spec, store, signed_block)

    # On receiving a block of next epoch
    store.time = time + spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH
    block = build_empty_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
    signed_block = state_transition_and_sign_block(spec, state, block)

    run_on_block(spec, store, signed_block)
Пример #24
0
def test_on_attestation_invalid_attestation(spec, state):
    store = get_genesis_forkchoice_store(spec, state)
    time = store.time + 3 * spec.SECONDS_PER_SLOT
    spec.on_tick(store, time)

    block = build_empty_block_for_next_slot(spec, state)
    signed_block = state_transition_and_sign_block(spec, state, block)

    spec.on_block(store, signed_block)

    attestation = get_valid_attestation(spec,
                                        state,
                                        slot=block.slot,
                                        signed=True)
    # make invalid by using an invalid committee index
    attestation.data.index = spec.MAX_COMMITTEES_PER_SLOT * spec.SLOTS_PER_EPOCH

    run_on_attestation(spec, state, store, attestation, False)
Пример #25
0
def test_expected_deposit_in_block(spec, state):
    # Make the state expect a deposit, then don't provide it.
    state.eth1_data.deposit_count += 1
    yield 'pre', state

    block = build_empty_block_for_next_slot(spec, state)
    sign_block(spec, state, block)
    bad = False
    try:
        state_transition_and_sign_block(spec, state, block)
        bad = True
    except AssertionError:
        pass
    if bad:
        raise AssertionError("expected deposit was not enforced")

    yield 'blocks', [block]
    yield 'post', None
Пример #26
0
def test_proposer_self_slashing(spec, state):
    yield 'pre', state

    block = build_empty_block_for_next_slot(spec, state)
    assert not state.validators[block.proposer_index].slashed

    proposer_slashing = get_valid_proposer_slashing(
        spec, state, slashed_index=block.proposer_index, signed_1=True, signed_2=True)
    block.body.proposer_slashings.append(proposer_slashing)

    # The header is processed *before* the block body:
    # the proposer was not slashed before the body, thus the block is valid.
    signed_block = state_transition_and_sign_block(spec, state, block)
    # The proposer slashed themselves.
    assert state.validators[block.proposer_index].slashed

    yield 'blocks', [signed_block]
    yield 'post', state
def test_on_attestation_past_epoch(spec, state):
    store = get_genesis_forkchoice_store(spec, state)

    # move time forward 2 epochs
    time = store.time + 2 * spec.config.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH
    spec.on_tick(store, time)

    # create and store block from 3 epochs ago
    block = build_empty_block_for_next_slot(spec, state)
    signed_block = state_transition_and_sign_block(spec, state, block)
    spec.on_block(store, signed_block)

    # create attestation for past block
    attestation = get_valid_attestation(spec, state, slot=state.slot, signed=True)
    assert attestation.data.target.epoch == spec.GENESIS_EPOCH
    assert spec.compute_epoch_at_slot(spec.get_current_slot(store)) == spec.GENESIS_EPOCH + 2

    run_on_attestation(spec, state, store, attestation, False)
Пример #28
0
def test_invalid_signature_extra_participant(spec, state):
    committee_indices = compute_committee_indices(spec, state, state.current_sync_committee)
    rng = random.Random(3030)
    random_participant = rng.choice(committee_indices)

    block = build_empty_block_for_next_slot(spec, state)
    # Exclude one signature even though the block claims the entire committee participated.
    block.body.sync_aggregate = spec.SyncAggregate(
        sync_committee_bits=[True] * len(committee_indices),
        sync_committee_signature=compute_aggregate_sync_committee_signature(
            spec,
            state,
            block.slot - 1,
            [index for index in committee_indices if index != random_participant],
        )
    )

    yield from run_sync_committee_processing(spec, state, block, expect_exception=True)
Пример #29
0
def compute_sync_committee_signature(spec,
                                     state,
                                     slot,
                                     privkey,
                                     block_root=None,
                                     domain_type=None):
    if not domain_type:
        domain_type = spec.DOMAIN_SYNC_COMMITTEE
    domain = spec.get_domain(state, domain_type,
                             spec.compute_epoch_at_slot(slot))
    if block_root is None:
        if slot == state.slot:
            block_root = build_empty_block_for_next_slot(spec,
                                                         state).parent_root
        else:
            block_root = spec.get_block_root_at_slot(state, slot)
    signing_root = spec.compute_signing_root(block_root, domain)
    return bls.Sign(privkey, signing_root)
Пример #30
0
def test_double_same_proposer_slashings_same_block(spec, state):
    proposer_slashing = get_valid_proposer_slashing(spec,
                                                    state,
                                                    signed_1=True,
                                                    signed_2=True)
    slashed_index = proposer_slashing.signed_header_1.message.proposer_index
    assert not state.validators[slashed_index].slashed

    yield 'pre', state

    block = build_empty_block_for_next_slot(spec, state)
    block.body.proposer_slashings = [proposer_slashing, proposer_slashing]
    signed_block = state_transition_and_sign_block(spec,
                                                   state,
                                                   block,
                                                   expect_fail=True)

    yield 'blocks', [signed_block]
    yield 'post', None