Exemple #1
0
def test_finality_rule_2(spec, state):
    # get past first two epochs that finality does not run on
    next_epoch(spec, state)
    apply_empty_block(spec, state)
    next_epoch(spec, state)
    apply_empty_block(spec, state)

    yield 'pre', state

    blocks = []
    for epoch in range(3):
        if epoch == 0:
            prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False)
            check_finality(spec, state, prev_state, True, False, False)
        elif epoch == 1:
            prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, False)
            check_finality(spec, state, prev_state, False, True, False)
        elif epoch == 2:
            prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, True)
            # finalized by rule 2
            check_finality(spec, state, prev_state, True, False, True)
            assert state.finalized_checkpoint == prev_state.previous_justified_checkpoint

        blocks += new_blocks

    yield 'blocks', blocks
    yield 'post', state
def test_finality_rule_3(spec, state):
    """
    Test scenario described here
    https://github.com/ethereum/eth2.0-specs/issues/611#issuecomment-463612892
    """
    # get past first two epochs that finality does not run on
    next_epoch(spec, state)
    apply_empty_block(spec, state)
    next_epoch(spec, state)
    apply_empty_block(spec, state)

    yield 'pre', state

    blocks = []
    prev_state, new_blocks, state = next_epoch_with_attestations(
        spec, state, True, False)
    blocks += new_blocks
    check_finality(spec, state, prev_state, True, False, False)

    # In epoch N, JE is set to N, prev JE is set to N-1
    prev_state, new_blocks, state = next_epoch_with_attestations(
        spec, state, True, False)
    blocks += new_blocks
    check_finality(spec, state, prev_state, True, True, True)

    # In epoch N+1, JE is N, prev JE is N-1, and not enough messages get in to do anything
    prev_state, new_blocks, state = next_epoch_with_attestations(
        spec, state, False, False)
    blocks += new_blocks
    check_finality(spec, state, prev_state, False, True, False)

    # In epoch N+2, JE is N, prev JE is N, and enough messages from the previous epoch get in to justify N+1.
    # N+1 now becomes the JE. Not enough messages from epoch N+2 itself get in to justify N+2
    prev_state, new_blocks, state = next_epoch_with_attestations(
        spec, state, False, True)
    blocks += new_blocks
    # rule 2
    check_finality(spec, state, prev_state, True, False, True)

    # In epoch N+3, LJE is N+1, prev LJE is N, and enough messages get in to justify epochs N+2 and N+3.
    prev_state, new_blocks, state = next_epoch_with_attestations(
        spec, state, True, True)
    blocks += new_blocks
    # rule 3
    check_finality(spec, state, prev_state, True, True, True)
    assert state.finalized_checkpoint == prev_state.current_justified_checkpoint

    yield 'blocks', blocks
    yield 'post', state
Exemple #3
0
def apply_next_epoch_with_attestations(spec, state, store):
    _, new_blocks, post_state = next_epoch_with_attestations(
        spec, state, True, False)
    for block in new_blocks:
        block_root = signing_root(block)
        store.blocks[block_root] = block
        store.block_states[block_root] = post_state
        last_block = block
    spec.on_tick(store, store.time + state.slot * spec.SECONDS_PER_SLOT)
    return post_state, store, last_block
Exemple #4
0
def test_finality_no_updates_at_genesis(spec, state):
    assert spec.get_current_epoch(state) == spec.GENESIS_EPOCH

    yield 'pre', state

    blocks = []
    for epoch in range(2):
        prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False)
        blocks += new_blocks

        # justification/finalization skipped at GENESIS_EPOCH
        if epoch == 0:
            check_finality(spec, state, prev_state, False, False, False)
        # justification/finalization skipped at GENESIS_EPOCH + 1
        elif epoch == 1:
            check_finality(spec, state, prev_state, False, False, False)

    yield 'blocks', blocks
    yield 'post', state
Exemple #5
0
def test_finality_rule_4(spec, state):
    # get past first two epochs that finality does not run on
    next_epoch(spec, state)
    apply_empty_block(spec, state)
    next_epoch(spec, state)
    apply_empty_block(spec, state)

    yield 'pre', state

    blocks = []
    for epoch in range(2):
        prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False)
        blocks += new_blocks

        if epoch == 0:
            check_finality(spec, state, prev_state, True, False, False)
        elif epoch == 1:
            # rule 4 of finality
            check_finality(spec, state, prev_state, True, True, True)
            assert state.finalized_checkpoint == prev_state.current_justified_checkpoint

    yield 'blocks', blocks
    yield 'post', state
Exemple #6
0
def test_filtered_block_tree(spec, state):
    # Initialization
    genesis_state_root = state.hash_tree_root()
    store = spec.get_genesis_store(state)
    genesis_block = spec.BeaconBlock(state_root=genesis_state_root)

    # transition state past initial couple of epochs
    next_epoch(spec, state)
    next_epoch(spec, state)

    assert spec.get_head(store) == spec.hash_tree_root(genesis_block)

    # fill in attestations for entire epoch, justifying the recent epoch
    prev_state, signed_blocks, state = next_epoch_with_attestations(
        spec, state, True, False)
    attestations = [
        attestation for signed_block in signed_blocks
        for attestation in signed_block.message.body.attestations
    ]
    assert state.current_justified_checkpoint.epoch > prev_state.current_justified_checkpoint.epoch

    # tick time forward and add blocks and attestations to store
    current_time = state.slot * spec.SECONDS_PER_SLOT + store.genesis_time
    spec.on_tick(store, current_time)
    for signed_block in signed_blocks:
        spec.on_block(store, signed_block)
    for attestation in attestations:
        spec.on_attestation(store, attestation)

    assert store.justified_checkpoint == state.current_justified_checkpoint

    # the last block in the branch should be the head
    expected_head_root = spec.hash_tree_root(signed_blocks[-1].message)
    assert spec.get_head(store) == expected_head_root

    #
    # create branch containing the justified block but not containing enough on
    # chain votes to justify that block
    #

    # build a chain without attestations off of previous justified block
    non_viable_state = store.block_states[
        store.justified_checkpoint.root].copy()

    # ensure that next wave of votes are for future epoch
    next_epoch(spec, non_viable_state)
    next_epoch(spec, non_viable_state)
    next_epoch(spec, non_viable_state)
    assert spec.get_current_epoch(
        non_viable_state) > store.justified_checkpoint.epoch

    # create rogue block that will be attested to in this non-viable branch
    rogue_block = build_empty_block_for_next_slot(spec, non_viable_state)
    signed_rogue_block = state_transition_and_sign_block(
        spec, non_viable_state, rogue_block)

    # create an epoch's worth of attestations for the rogue block
    next_epoch(spec, non_viable_state)
    attestations = []
    for i in range(spec.SLOTS_PER_EPOCH):
        slot = rogue_block.slot + i
        for index in range(
                spec.get_committee_count_at_slot(non_viable_state, slot)):
            attestation = get_valid_attestation(spec, non_viable_state,
                                                rogue_block.slot + i, index)
            attestations.append(attestation)

    # tick time forward to be able to include up to the latest attestation
    current_time = (attestations[-1].data.slot +
                    1) * spec.SECONDS_PER_SLOT + store.genesis_time
    spec.on_tick(store, current_time)

    # include rogue block and associated attestations in the store
    spec.on_block(store, signed_rogue_block)
    for attestation in attestations:
        spec.on_attestation(store, attestation)

    # ensure that get_head still returns the head from the previous branch
    assert spec.get_head(store) == expected_head_root