Пример #1
0
def create_beacon_block_with_shard_transition(
        spec, state, store, shard, shard_blocks_buffer, is_checking_pending_shard_blocks=True):
    beacon_block = build_empty_block(spec, state, slot=state.slot + 1)
    committee_index = get_committee_index_of_shard(spec, state, state.slot, shard)
    has_shard_committee = committee_index is not None  # has committee of `shard` at this slot

    beacon_block = build_empty_block(spec, state, slot=state.slot + 1)

    # If next slot has committee of `shard`, add `shard_transtion` to the proposing beacon block
    if has_shard_committee and len(shard_blocks_buffer) > 0:
        # Sanity check `get_pending_shard_blocks`
        # Assert that the pending shard blocks set in the store equal to shard_blocks_buffer
        if is_checking_pending_shard_blocks:
            check_pending_shard_blocks(spec, store, shard, shard_blocks_buffer)
        # Use temporary next state to get ShardTransition of shard block
        shard_transitions = get_shard_transitions(spec, state, shard_block_dict={shard: shard_blocks_buffer})
        shard_transition = shard_transitions[shard]
        attestation = get_valid_on_time_attestation(
            spec,
            state,
            index=committee_index,
            shard_transition=shard_transition,
            signed=True,
        )
        assert attestation.data.shard == shard
        beacon_block.body.attestations = [attestation]
        beacon_block.body.shard_transitions = shard_transitions

        # Clear buffer
        shard_blocks_buffer.clear()

    return beacon_block
Пример #2
0
def test_attestation(spec, state):
    state.slot = spec.SLOTS_PER_EPOCH

    yield 'pre', state

    attestation = get_valid_attestation(spec, state, signed=True)

    # Add to state via block transition
    pre_current_attestations_len = len(state.current_epoch_attestations)
    attestation_block = build_empty_block(
        spec, state, state.slot + 1 + spec.MIN_ATTESTATION_INCLUSION_DELAY)
    attestation_block.body.attestations.append(attestation)
    signed_attestation_block = state_transition_and_sign_block(
        spec, 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(spec, state,
                                    state.slot + spec.SLOTS_PER_EPOCH)
    signed_epoch_block = state_transition_and_sign_block(
        spec, state, epoch_block)

    yield 'blocks', [signed_attestation_block, signed_epoch_block]
    yield 'post', state

    assert len(state.current_epoch_attestations) == 0
    assert spec.hash_tree_root(
        state.previous_epoch_attestations) == pre_current_attestations_root
Пример #3
0
def test_ex_ante_sandwich_without_attestations(spec, state):
    """
    Simple Sandwich test with boost and no attestations.
    Obejcts:
        Block A - slot N
        Block B (parent A) - slot N+1
        Block C (parent A) - slot N+2
        Block D (parent B) - slot N+3
    Steps:
        Block A received at N — A is head
        Block C received at N+2 — C is head
        Block B received at N+2 — C is head (with boost)
        Block D received at N+3 — D is head (with boost)
    """
    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

    # On receiving block A at slot `N`
    yield from _apply_base_block_a(spec, state, store, test_steps)
    state_a = state.copy()

    # Block B at slot `N + 1`, parent is A
    state_b = state_a.copy()
    block = build_empty_block(spec, state_a, slot=state_a.slot + 1)
    signed_block_b = state_transition_and_sign_block(spec, state_b, block)

    # Block C at slot `N + 2`, parent is A
    state_c = state_a.copy()
    block = build_empty_block(spec, state_c, slot=state_a.slot + 2)
    signed_block_c = state_transition_and_sign_block(spec, state_c, block)

    # Block D at slot `N + 3`, parent is B
    state_d = state_b.copy()
    block = build_empty_block(spec, state_d, slot=state_a.slot + 3)
    signed_block_d = state_transition_and_sign_block(spec, state_d, block)

    # Block C received at N+2 — C is head
    time = state_c.slot * spec.config.SECONDS_PER_SLOT + store.genesis_time
    on_tick_and_append_step(spec, store, time, test_steps)
    yield from add_block(spec, store, signed_block_c, test_steps)
    assert spec.get_head(store) == signed_block_c.message.hash_tree_root()

    # Block B received at N+2 — C is head, it has proposer score boost
    yield from add_block(spec, store, signed_block_b, test_steps)
    assert spec.get_head(store) == signed_block_c.message.hash_tree_root()

    # Block D received at N+3 - D is head, it has proposer score boost
    time = state_d.slot * spec.config.SECONDS_PER_SLOT + store.genesis_time
    on_tick_and_append_step(spec, store, time, test_steps)
    yield from add_block(spec, store, signed_block_d, test_steps)
    assert spec.get_head(store) == signed_block_d.message.hash_tree_root()

    yield 'steps', test_steps
Пример #4
0
def test_custody_slashing(spec, state):
    # NOTE: this test is only for full crosslink (minimal config), not for mainnet
    if not is_full_crosslink(spec, state):
        # skip
        return

    state = transition_to_valid_shard_slot(spec, state)

    # Build shard block
    shard = 0
    committee_index = get_committee_index_of_shard(spec, state, state.slot,
                                                   shard)
    # Create slashable shard block body
    validator_index = spec.get_beacon_committee(state, state.slot,
                                                committee_index)[0]
    custody_secret = get_custody_secret(spec, state, validator_index)
    slashable_body = get_custody_slashable_test_vector(spec,
                                                       custody_secret,
                                                       length=100,
                                                       slashable=True)
    shard_block = build_shard_block(spec,
                                    state,
                                    shard,
                                    body=slashable_body,
                                    slot=state.slot,
                                    signed=True)
    shard_block_dict: Dict[spec.Shard, Sequence[spec.SignedShardBlock]] = {
        shard: [shard_block]
    }
    shard_transitions = get_shard_transitions(spec, state, shard_block_dict)

    attestation = get_valid_on_time_attestation(
        spec,
        state,
        index=committee_index,
        shard_transition=shard_transitions[shard],
        signed=True,
    )
    block = build_empty_block(spec, state, slot=state.slot + 1)
    block.body.attestations = [attestation]
    block.body.shard_transitions = shard_transitions

    _, _, _ = run_beacon_block(spec, state, block)

    transition_to(
        spec, state, state.slot + spec.SLOTS_PER_EPOCH *
        (spec.EPOCHS_PER_CUSTODY_PERIOD - 1))

    block = build_empty_block(spec, state, slot=state.slot + 1)
    custody_slashing = get_valid_custody_slashing(spec, state, attestation,
                                                  shard_transitions[shard],
                                                  custody_secret,
                                                  slashable_body)
    block.body.custody_slashings = [custody_slashing]

    yield from run_beacon_block(spec, state, block)
Пример #5
0
def test_custody_slashing(spec, state):
    transition_to_valid_shard_slot(spec, state)

    # Build shard block
    shard = 0
    committee_index = get_committee_index_of_shard(spec, state, state.slot,
                                                   shard)
    # Create slashable shard block body
    validator_index = spec.get_beacon_committee(state, state.slot,
                                                committee_index)[0]
    custody_secret = spec.get_custody_secret(
        state,
        validator_index,
        privkeys[validator_index],
        spec.get_current_epoch(state),
    )
    slashable_body = get_custody_slashable_test_vector(spec,
                                                       custody_secret,
                                                       length=100,
                                                       slashable=True)
    shard_block = build_shard_block(spec,
                                    state,
                                    shard,
                                    body=slashable_body,
                                    slot=state.slot,
                                    signed=True)
    shard_block_dict: Dict[spec.Shard, Sequence[spec.SignedShardBlock]] = {
        shard: [shard_block]
    }
    shard_transitions = get_shard_transitions(spec, state, shard_block_dict)

    attestation = get_valid_on_time_attestation(
        spec,
        state,
        index=committee_index,
        shard_transition=shard_transitions[shard],
        signed=True,
    )
    block = build_empty_block(spec, state, slot=state.slot + 1)
    block.body.attestations = [attestation]
    block.body.shard_transitions = shard_transitions

    _, _, _ = run_beacon_block(spec, state, block)

    transition_to(
        spec, state, state.slot + spec.SLOTS_PER_EPOCH *
        (spec.EPOCHS_PER_CUSTODY_PERIOD - 1))

    block = build_empty_block(spec, state, slot=state.slot + 1)
    custody_slashing = get_valid_custody_slashing(spec, state, attestation,
                                                  shard_transitions[shard],
                                                  custody_secret,
                                                  slashable_body)
    block.body.custody_slashings = [custody_slashing]

    yield from run_beacon_block(spec, state, block)
Пример #6
0
def test_attestation(spec, state):
    next_epoch(spec, state)

    yield 'pre', state

    attestation_block = build_empty_block(
        spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)

    index = 0
    # if spec.fork == SHARDING:
    #     TODO add shard data to block to vote on

    attestation = get_valid_attestation(spec,
                                        state,
                                        index=index,
                                        signed=True,
                                        on_time=True)

    if not is_post_altair(spec):
        pre_current_attestations_len = len(state.current_epoch_attestations)

    # Add to state via block transition
    attestation_block.body.attestations.append(attestation)
    signed_attestation_block = state_transition_and_sign_block(
        spec, state, attestation_block)

    if not is_post_altair(spec):
        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)
    else:
        pre_current_epoch_participation_root = spec.hash_tree_root(
            state.current_epoch_participation)

    epoch_block = build_empty_block(spec, state,
                                    state.slot + spec.SLOTS_PER_EPOCH)
    signed_epoch_block = state_transition_and_sign_block(
        spec, state, epoch_block)

    yield 'blocks', [signed_attestation_block, signed_epoch_block]
    yield 'post', state

    if not is_post_altair(spec):
        assert len(state.current_epoch_attestations) == 0
        assert spec.hash_tree_root(
            state.previous_epoch_attestations) == pre_current_attestations_root
    else:
        for index in range(len(state.validators)):
            assert state.current_epoch_participation[
                index] == spec.ParticipationFlags(0b0000_0000)
        assert spec.hash_tree_root(state.previous_epoch_participation
                                   ) == pre_current_epoch_participation_root
Пример #7
0
def test_inactivity_scores_full_participation_leaking(spec, state):
    randomize_inactivity_scores(spec, state, rng=Random(5252))
    assert len(set(state.inactivity_scores)) > 1

    # Only set full participation for previous epoch to remain in leak
    set_full_participation_previous_epoch(spec, state)

    previous_inactivity_scores = state.inactivity_scores.copy()

    yield 'pre', state

    # Block transition to next epoch
    block = build_empty_block(spec,
                              state,
                              slot=state.slot + spec.SLOTS_PER_EPOCH)
    signed_block = state_transition_and_sign_block(spec, state, block)

    assert spec.is_in_inactivity_leak(state)

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

    # Full particiaption during a leak so all scores should decrease by 1
    for pre, post in zip(previous_inactivity_scores, state.inactivity_scores):
        assert post == pre - 1
Пример #8
0
def test_early_derived_secret_reveal(spec, state):
    transition_to_valid_shard_slot(spec, state)
    block = build_empty_block(spec, state, slot=state.slot + 1)
    early_derived_secret_reveal = get_valid_early_derived_secret_reveal(spec, state)
    block.body.early_derived_secret_reveals = [early_derived_secret_reveal]

    yield from run_beacon_block(spec, state, block)
Пример #9
0
def test_eth1_data_votes_no_consensus(spec, state):
    if spec.EPOCHS_PER_ETH1_VOTING_PERIOD > 2:
        return dump_skipping_message(
            "Skip test if config with longer `EPOCHS_PER_ETH1_VOTING_PERIOD` for saving time."
            " Minimal config suffice to cover the target-of-test.")

    voting_period_slots = spec.EPOCHS_PER_ETH1_VOTING_PERIOD * spec.SLOTS_PER_EPOCH

    pre_eth1_hash = state.eth1_data.block_hash

    offset_block = build_empty_block(spec, state, slot=voting_period_slots - 1)
    state_transition_and_sign_block(spec, state, offset_block)
    yield 'pre', state

    a = b'\xaa' * 32
    b = b'\xbb' * 32

    blocks = []

    for i in range(0, voting_period_slots):
        block = build_empty_block_for_next_slot(spec, state)
        # wait for precisely 50% for A, then start voting B for other 50%
        block.body.eth1_data.block_hash = b if i * 2 >= voting_period_slots else a
        signed_block = state_transition_and_sign_block(spec, state, block)
        blocks.append(signed_block)

    assert len(state.eth1_data_votes) == voting_period_slots
    assert state.eth1_data.block_hash == pre_eth1_hash

    yield 'blocks', blocks
    yield 'post', state
Пример #10
0
def test_voluntary_exit(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.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH

    signed_exits = prepare_signed_exits(spec, state, [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)

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

    # Process within epoch transition
    exit_block = build_empty_block(spec, state,
                                   state.slot + spec.SLOTS_PER_EPOCH)
    signed_exit_block = state_transition_and_sign_block(
        spec, state, exit_block)

    yield 'blocks', [signed_initiate_exit_block, signed_exit_block]
    yield 'post', state

    assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH
Пример #11
0
def test_eth1_data_votes_no_consensus(spec, state):
    voting_period_slots = spec.EPOCHS_PER_ETH1_VOTING_PERIOD * spec.SLOTS_PER_EPOCH

    pre_eth1_hash = state.eth1_data.block_hash

    offset_block = build_empty_block(spec, state, slot=voting_period_slots - 1)
    state_transition_and_sign_block(spec, state, offset_block)
    yield 'pre', state

    a = b'\xaa' * 32
    b = b'\xbb' * 32

    blocks = []

    for i in range(0, voting_period_slots):
        block = build_empty_block_for_next_slot(spec, state)
        # wait for precisely 50% for A, then start voting B for other 50%
        block.body.eth1_data.block_hash = b if i * 2 >= voting_period_slots else a
        signed_block = state_transition_and_sign_block(spec, state, block)
        blocks.append(signed_block)

    assert len(state.eth1_data_votes) == voting_period_slots
    assert state.eth1_data.block_hash == pre_eth1_hash

    yield 'blocks', blocks
    yield 'post', state
Пример #12
0
def test_eth1_data_votes_no_consensus(spec, state):
    # Don't run when it will take very, very long to simulate. Minimal configuration suffices.
    if spec.SLOTS_PER_ETH1_VOTING_PERIOD > 16:
        return

    pre_eth1_hash = state.eth1_data.block_hash

    offset_block = build_empty_block(spec,
                                     state,
                                     slot=spec.SLOTS_PER_ETH1_VOTING_PERIOD -
                                     1)
    state_transition_and_sign_block(spec, state, offset_block)
    yield 'pre', state

    a = b'\xaa' * 32
    b = b'\xbb' * 32

    blocks = []

    for i in range(0, spec.SLOTS_PER_ETH1_VOTING_PERIOD):
        block = build_empty_block_for_next_slot(spec, state)
        # wait for precisely 50% for A, then start voting B for other 50%
        block.body.eth1_data.block_hash = b if i * 2 >= spec.SLOTS_PER_ETH1_VOTING_PERIOD else a
        signed_block = state_transition_and_sign_block(spec, state, block)
        blocks.append(signed_block)

    assert len(state.eth1_data_votes) == spec.SLOTS_PER_ETH1_VOTING_PERIOD
    assert state.eth1_data.block_hash == pre_eth1_hash

    yield 'blocks', blocks
    yield 'post', state
Пример #13
0
def test_with_shard_transition_with_custody_challenge_and_response(spec, state):
    transition_to_valid_shard_slot(spec, state)

    # build shard block
    shard = 0
    committee_index = get_committee_index_of_shard(spec, state, state.slot, shard)
    body = get_sample_shard_block_body(spec)
    shard_block = build_shard_block(spec, state, shard, body=body, slot=state.slot, signed=True)
    shard_block_dict: Dict[spec.Shard, Sequence[spec.SignedShardBlock]] = {shard: [shard_block]}
    shard_transitions = get_shard_transitions(spec, state, shard_block_dict)
    attestation = get_valid_on_time_attestation(
        spec, state, index=committee_index,
        shard_transition=shard_transitions[shard], signed=True,
    )

    block = build_empty_block(spec, state, slot=state.slot + 1)
    block.body.attestations = [attestation]
    block.body.shard_transitions = shard_transitions

    # CustodyChunkChallenge operation
    challenge = get_valid_chunk_challenge(spec, state, attestation, shard_transitions[shard])
    block.body.chunk_challenges = [challenge]
    # CustodyChunkResponse operation
    chunk_challenge_index = state.custody_chunk_challenge_index
    custody_response = get_valid_custody_chunk_response(
        spec, state, challenge, chunk_challenge_index, block_length_or_custody_data=body)
    block.body.chunk_challenge_responses = [custody_response]

    yield from run_beacon_block(spec, state, block)
Пример #14
0
def test_custody_key_reveal(spec, state):
    transition_to_valid_shard_slot(spec, state)
    transition_to(spec, state, state.slot + spec.EPOCHS_PER_CUSTODY_PERIOD * spec.SLOTS_PER_EPOCH)

    block = build_empty_block(spec, state, slot=state.slot + 1)
    custody_key_reveal = get_valid_custody_key_reveal(spec, state)
    block.body.custody_key_reveals = [custody_key_reveal]

    yield from run_beacon_block(spec, state, block)
Пример #15
0
def test_same_slot_block_transition(spec, state):
    # Same slot on top of pre-state, but move out of slot 0 first.
    spec.process_slots(state, state.slot + 1)

    block = build_empty_block(spec, state, slot=state.slot)

    yield 'pre', state

    signed_block = state_transition_and_sign_block(spec, state, block)

    yield 'blocks', [signed_block]
    yield 'post', state
Пример #16
0
def test_prev_slot_block_transition(spec, state):
    # Go to clean slot
    spec.process_slots(state, state.slot + 1)
    # Make a block for it
    block = build_empty_block(spec, state, slot=state.slot, signed=True)
    # Transition to next slot, above block will not be invalid on top of new state.
    spec.process_slots(state, state.slot + 1)

    yield 'pre', state
    expect_assertion_error(
        lambda: state_transition_and_sign_block(spec, state, block))
    yield 'blocks', [block]
    yield 'post', None
def test_compute_new_state_root(spec, state):
    pre_state = state.copy()
    post_state = state.copy()
    block = build_empty_block(spec, state, state.slot + 1)
    state_root = spec.compute_new_state_root(state, block)

    assert state_root != pre_state.hash_tree_root()
    assert state == pre_state

    # dumb verification
    spec.process_slots(post_state, block.slot)
    spec.process_block(post_state, block)
    assert state_root == post_state.hash_tree_root()
Пример #18
0
def run_beacon_block_with_shard_blocks(spec,
                                       state,
                                       shard_blocks,
                                       target_len_offset_slot,
                                       committee_index,
                                       valid=True):
    shard_transitions = build_shard_transitions_till_slot(
        spec,
        state,
        shard_blocks,
        on_time_slot=state.slot + target_len_offset_slot)
    attestations = [
        build_attestation_with_shard_transition(
            spec,
            state,
            on_time_slot=state.slot + target_len_offset_slot,
            index=committee_index,
            shard_transition=shard_transitions[shard],
        ) for shard in shard_blocks.keys()
    ]

    # Propose beacon block at slot `x + 1`
    beacon_block = build_empty_block(spec,
                                     state,
                                     slot=state.slot + target_len_offset_slot)
    beacon_block.body.attestations = attestations
    beacon_block.body.shard_transitions = shard_transitions

    pre_shard_states = state.shard_states.copy()
    yield 'pre', state.copy()
    yield 'block', beacon_block
    state_transition_and_sign_block(spec, state, beacon_block)
    if valid:
        yield 'post', state
    else:
        yield 'post', None
        return

    for shard in range(spec.get_active_shard_count(state)):
        post_shard_state = state.shard_states[shard]
        if shard in shard_blocks:
            # Shard state has been changed to state_transition result
            assert post_shard_state == shard_transitions[shard].shard_states[
                len(shard_transitions[shard].shard_states) - 1]
            assert beacon_block.slot == shard_transitions[shard].shard_states[
                0].slot + target_len_offset_slot
            assert post_shard_state.slot == state.slot - 1
            if len(shard_blocks[shard]) == 0:
                # `latest_block_root` is the same
                assert post_shard_state.latest_block_root == pre_shard_states[
                    shard].latest_block_root
Пример #19
0
def test_empty_epoch_transition_large_validator_set(spec, state):
    pre_slot = state.slot
    yield 'pre', state

    block = build_empty_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH)

    signed_block = state_transition_and_sign_block(spec, state, block)

    yield 'blocks', [signed_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
Пример #20
0
def test_get_block_signature(spec, state):
    privkey = privkeys[0]
    pubkey = pubkeys[0]
    block = build_empty_block(spec, state)
    domain = spec.get_domain(state, spec.DOMAIN_BEACON_PROPOSER, spec.compute_epoch_at_slot(block.slot))
    run_get_signature_test(
        spec=spec,
        state=state,
        obj=block,
        domain=domain,
        get_signature_fn=spec.get_block_signature,
        privkey=privkey,
        pubkey=pubkey,
    )
Пример #21
0
def run_beacon_block_with_shard_blocks(spec, state, target_len_offset_slot, committee_index, shard, valid=True):
    transition_to(spec, state, state.slot + target_len_offset_slot)

    body = get_sample_shard_block_body(spec, is_max=True)
    shard_block = build_shard_block(spec, state, shard, body=body, slot=state.slot, signed=True)
    shard_block_dict: Dict[spec.Shard, Sequence[spec.SignedShardBlock]] = {shard: [shard_block]}

    shard_transitions = get_shard_transitions(spec, state, shard_block_dict)
    attestations = [
        get_valid_on_time_attestation(
            spec,
            state,
            index=committee_index,
            shard_transition=shard_transitions[shard],
            signed=True,
        )
        for shard in shard_block_dict.keys()
    ]

    beacon_block = build_empty_block(spec, state, slot=state.slot + 1)
    beacon_block.body.attestations = attestations
    beacon_block.body.shard_transitions = shard_transitions

    pre_gasprice = state.shard_states[shard].gasprice
    pre_shard_states = state.shard_states.copy()
    yield 'pre', state.copy()

    if not valid:
        state_transition_and_sign_block(spec, state, beacon_block, expect_fail=True)
        yield 'block', beacon_block
        yield 'post', None
        return

    signed_beacon_block = state_transition_and_sign_block(spec, state, beacon_block)
    yield 'block', signed_beacon_block
    yield 'post', state

    for shard in range(spec.get_active_shard_count(state)):
        post_shard_state = state.shard_states[shard]
        if shard in shard_block_dict:
            # Shard state has been changed to state_transition result
            assert post_shard_state == shard_transitions[shard].shard_states[
                len(shard_transitions[shard].shard_states) - 1
            ]
            assert post_shard_state.slot == state.slot - 1
            if len((shard_block_dict[shard])) == 0:
                # `latest_block_root` is the same
                assert post_shard_state.latest_block_root == pre_shard_states[shard].latest_block_root
            if target_len_offset_slot == 1 and len(shard_block_dict[shard]) > 0:
                assert post_shard_state.gasprice > pre_gasprice
Пример #22
0
def test_attestation(spec, state):
    next_epoch(spec, state)

    yield 'pre', state

    attestation_block = build_empty_block(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)

    index = 0
    if spec.fork == PHASE1:
        shard = spec.compute_shard_from_committee_index(state, index, state.slot)
        shard_transition = get_shard_transition_of_committee(spec, state, index)
        attestation_block.body.shard_transitions[shard] = shard_transition
    else:
        shard_transition = None

    attestation = get_valid_attestation(
        spec, state, shard_transition=shard_transition, index=index, signed=True, on_time=True
    )

    # Add to state via block transition
    pre_current_attestations_len = len(state.current_epoch_attestations)
    attestation_block.body.attestations.append(attestation)
    signed_attestation_block = state_transition_and_sign_block(spec, 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(spec, state, state.slot + spec.SLOTS_PER_EPOCH)
    signed_epoch_block = state_transition_and_sign_block(spec, state, epoch_block)

    yield 'blocks', [signed_attestation_block, signed_epoch_block]
    yield 'post', state

    assert len(state.current_epoch_attestations) == 0
    assert spec.hash_tree_root(state.previous_epoch_attestations) == pre_current_attestations_root
Пример #23
0
def test_skipped_slots(spec, state):
    pre_slot = state.slot
    yield 'pre', state

    block = build_empty_block(spec, state, state.slot + 4)

    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_randao_mix(state, spec.get_current_epoch(state)) != spec.Bytes32()
    for slot in range(pre_slot, state.slot):
        assert spec.get_block_root_at_slot(state, slot) == block.parent_root
Пример #24
0
def _state_transition_and_sign_block_at_slot(spec, state):
    """
    Cribbed from ``transition_unsigned_block`` helper
    where the early parts of the state transition have already
    been applied to ``state``.

    Used to produce a block during an irregular state transition.
    """
    block = build_empty_block(spec, state)

    assert state.latest_block_header.slot < block.slot
    assert state.slot == block.slot
    spec.process_block(state, block)
    block.state_root = state.hash_tree_root()
    return sign_block(spec, state, block)
Пример #25
0
def apply_shard_and_beacon(spec, state, store, shard_store,
                           shard_blocks_buffer):
    store.time = store.time + spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH

    shard = shard_store.shard
    committee_index = get_committee_index_of_shard(spec, state, state.slot,
                                                   shard)
    has_shard_committee = committee_index is not None  # has committee of `shard` at this slot

    beacon_block = build_empty_block(spec, state, slot=state.slot + 1)

    # If next slot has committee of `shard`, add `shard_transtion` to the proposing beacon block
    if has_shard_committee and len(shard_blocks_buffer) > 0:
        # Sanity check `get_pending_shard_blocks` function
        check_pending_shard_blocks(spec, store, shard_store,
                                   shard_blocks_buffer)
        # Use temporary next state to get ShardTransition of shard block
        shard_transitions = get_shard_transitions(
            spec,
            state,
            shard_block_dict={shard: shard_blocks_buffer},
        )
        shard_transition = shard_transitions[shard]
        attestation = get_valid_on_time_attestation(
            spec,
            state,
            index=committee_index,
            shard_transition=shard_transition,
            signed=False,
        )
        assert attestation.data.shard == shard
        beacon_block.body.attestations = [attestation]
        beacon_block.body.shard_transitions = shard_transitions

        # Clear buffer
        shard_blocks_buffer.clear()

    signed_beacon_block = state_transition_and_sign_block(
        spec, state, beacon_block)  # transition!
    add_block_to_store(spec, store, signed_beacon_block)
    assert spec.get_head(store) == beacon_block.hash_tree_root()

    # On shard block at transitioned `state.slot`
    if is_in_offset_sets(spec, state, shard):
        # The created shard block would be appended to `shard_blocks_buffer`
        apply_shard_block(spec, store, shard_store, state, shard_blocks_buffer)

    return has_shard_committee
Пример #26
0
def test_on_block_finalized_skip_slots(spec, state):
    # Initialization
    store = get_genesis_forkchoice_store(spec, state)
    time = 100
    spec.on_tick(store, time)

    store.finalized_checkpoint = spec.Checkpoint(
        epoch=store.finalized_checkpoint.epoch + 2,
        root=store.finalized_checkpoint.root
    )

    # Build block that includes the skipped slots up to finality in chain
    block = build_empty_block(spec, state, spec.compute_start_slot_at_epoch(store.finalized_checkpoint.epoch) + 2)
    signed_block = state_transition_and_sign_block(spec, state, block)
    spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT)
    run_on_block(spec, store, signed_block)
Пример #27
0
def test_prev_slot_block_transition(spec, state):
    # Go to clean slot
    spec.process_slots(state, state.slot + 1)
    # Make a block for it
    block = build_empty_block(spec, state, slot=state.slot)
    proposer_index = spec.get_beacon_proposer_index(state)
    # Transition to next slot, above block will not be invalid on top of new state.
    spec.process_slots(state, state.slot + 1)

    yield 'pre', state
    # State is beyond block slot, but the block can still be realistic when invalid.
    # Try the transition, and update the state root to where it is halted. Then sign with the supposed proposer.
    expect_assertion_error(lambda: transition_unsigned_block(spec, state, block))
    block.state_root = state.hash_tree_root()
    signed_block = sign_block(spec, state, block, proposer_index=proposer_index)
    yield 'blocks', [signed_block]
    yield 'post', None
Пример #28
0
def test_inactivity_scores(spec, state):
    for _ in range(spec.MIN_EPOCHS_TO_INACTIVITY_PENALTY + 2):
        next_epoch_via_block(spec, state)

    assert spec.is_in_inactivity_leak(state)
    previous_inactivity_scores = state.inactivity_scores.copy()

    yield 'pre', state

    # Block transition to next epoch
    block = build_empty_block(spec, state, slot=state.slot + spec.SLOTS_PER_EPOCH)
    signed_block = state_transition_and_sign_block(spec, state, block)

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

    for pre, post in zip(previous_inactivity_scores, state.inactivity_scores):
        assert post == pre + spec.INACTIVITY_SCORE_BIAS
Пример #29
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)
Пример #30
0
def test_eth1_data_votes_consensus(spec, state):
    # Don't run when it will take very, very long to simulate. Minimal configuration suffices.
    if spec.SLOTS_PER_ETH1_VOTING_PERIOD > 16:
        return

    offset_block = build_empty_block(spec,
                                     state,
                                     slot=spec.SLOTS_PER_ETH1_VOTING_PERIOD -
                                     1)
    sign_block(spec, state, offset_block)
    state_transition_and_sign_block(spec, state, offset_block)
    yield 'pre', state

    a = b'\xaa' * 32
    b = b'\xbb' * 32
    c = b'\xcc' * 32

    blocks = []

    for i in range(0, spec.SLOTS_PER_ETH1_VOTING_PERIOD):
        block = build_empty_block_for_next_slot(spec, state)
        # wait for over 50% for A, then start voting B
        block.body.eth1_data.block_hash = b if i * 2 > spec.SLOTS_PER_ETH1_VOTING_PERIOD else a
        sign_block(spec, state, block)
        state_transition_and_sign_block(spec, state, block)
        blocks.append(block)

    assert len(state.eth1_data_votes) == spec.SLOTS_PER_ETH1_VOTING_PERIOD
    assert state.eth1_data.block_hash == a

    # transition to next eth1 voting period
    block = build_empty_block_for_next_slot(spec, state)
    block.body.eth1_data.block_hash = c
    sign_block(spec, state, block)
    state_transition_and_sign_block(spec, state, block)
    blocks.append(block)

    yield 'blocks', blocks
    yield 'post', state

    assert state.eth1_data.block_hash == a
    assert state.slot % spec.SLOTS_PER_ETH1_VOTING_PERIOD == 0
    assert len(state.eth1_data_votes) == 1
    assert state.eth1_data_votes[0].block_hash == c