Ejemplo n.º 1
0
def test_get_state_by_slot(valid_chain, genesis_block, genesis_state, config,
                           keymap):
    # First, skip block and check if `get_state_by_slot` returns the expected state
    state_machine = valid_chain.get_state_machine(genesis_block.slot)
    state = valid_chain.get_head_state()
    block_skipped_slot = genesis_block.slot + 1
    block_skipped_state = state_machine.state_transition.apply_state_transition(
        state, future_slot=block_skipped_slot)
    valid_chain.chaindb.persist_state(block_skipped_state)
    with pytest.raises(StateNotFound):
        valid_chain.get_state_by_slot(block_skipped_slot)

    # Next, import proposed block and check if `get_state_by_slot` returns the expected state
    proposed_slot = block_skipped_slot + 1
    block = create_mock_block(
        state=block_skipped_state,
        config=config,
        state_machine=state_machine,
        signed_block_class=genesis_block.__class__,
        parent_block=genesis_block,
        keymap=keymap,
        slot=proposed_slot,
        attestations=(),
    )
    valid_chain.import_block(block)
    state = valid_chain.get_head_state()
    assert (valid_chain.get_state_by_slot(proposed_slot).hash_tree_root ==
            state.hash_tree_root)
Ejemplo n.º 2
0
def test_get_attestation_root(valid_chain, genesis_block, genesis_state,
                              config, keymap, min_attestation_inclusion_delay):
    state_machine = valid_chain.get_state_machine()
    attestations = create_mock_signed_attestations_at_slot(
        state=genesis_state,
        config=config,
        state_machine=state_machine,
        attestation_slot=genesis_block.slot,
        beacon_block_root=genesis_block.signing_root,
        keymap=keymap,
    )
    block = create_mock_block(
        state=genesis_state,
        config=config,
        state_machine=state_machine,
        block_class=genesis_block.__class__,
        parent_block=genesis_block,
        keymap=keymap,
        slot=genesis_state.slot + 1,
        attestations=attestations,
    )
    valid_chain.import_block(block)
    # Only one attestation in attestations, so just check that one
    a0 = attestations[0]
    assert valid_chain.get_attestation_by_root(a0.root) == a0
    assert valid_chain.attestation_exists(a0.root)
    fake_attestation = a0.copy(signature=b'\x78' * 96, )
    with pytest.raises(AttestationRootNotFound):
        valid_chain.get_attestation_by_root(fake_attestation.root)
    assert not valid_chain.attestation_exists(fake_attestation.root)
Ejemplo n.º 3
0
def test_per_slot_transition(
    chaindb,
    genesis_block,
    genesis_state,
    fixture_sm_class,
    config,
    state_slot,
    fork_choice_scoring,
    empty_attestation_pool,
    keymap,
):
    chaindb.persist_block(genesis_block, SerenityBeaconBlock,
                          fork_choice_scoring)
    chaindb.persist_state(genesis_state)

    state = genesis_state

    # Create a block
    block = create_mock_block(
        state=state,
        config=config,
        state_machine=fixture_sm_class(chaindb, empty_attestation_pool,
                                       genesis_block.slot),
        block_class=SerenityBeaconBlock,
        parent_block=genesis_block,
        keymap=keymap,
        slot=state_slot,
    )

    # Store in chaindb
    chaindb.persist_block(block, SerenityBeaconBlock, fork_choice_scoring)

    # Get state machine instance
    sm = fixture_sm_class(chaindb, empty_attestation_pool, block.slot)

    # Get state transition instance
    st = sm.state_transition_class(sm.config)

    updated_state = st.apply_state_transition(state,
                                              future_slot=state.slot + 1)

    # Ensure that slot gets increased by 1
    assert updated_state.slot == state.slot + 1

    # block_roots
    roots_index = (updated_state.slot -
                   1) % st.config.SLOTS_PER_HISTORICAL_ROOT
    assert updated_state.block_roots[roots_index] == block.parent_root

    # state_roots
    assert updated_state.state_roots[roots_index] == state.hash_tree_root

    # historical_roots
    if updated_state.slot % st.config.SLOTS_PER_HISTORICAL_ROOT == 0:
        historical_batch = HistoricalBatch(block_roots=state.block_roots,
                                           state_roots=state.state_roots)
        assert updated_state.historical_roots[
            -1] == historical_batch.hash_tree_root
    else:
        assert updated_state.historical_roots == state.historical_roots
Ejemplo n.º 4
0
def test_import_blocks(valid_chain, genesis_block, genesis_state, config,
                       keymap):
    state = genesis_state
    blocks = tuple()

    valid_chain_2 = copy.deepcopy(valid_chain)
    for i in range(3):
        block = create_mock_block(
            state=state,
            config=config,
            block_class=genesis_block.__class__,
            parent_block=genesis_block,
            keymap=keymap,
            slot=state.slot + 2,
        )

        valid_chain.import_block(block)
        state = valid_chain.get_state_machine(block).state

        assert block == valid_chain.get_canonical_block_by_slot(block.slot)
        assert block.root == valid_chain.get_canonical_block_root(block.slot)
        blocks += (block, )

    assert valid_chain.get_canonical_head(
    ) != valid_chain_2.get_canonical_head()

    for block in blocks:
        valid_chain_2.import_block(block)

    assert valid_chain.get_canonical_head(
    ) == valid_chain_2.get_canonical_head()
    assert (valid_chain.get_state_machine(
        blocks[-1]).state == valid_chain_2.get_state_machine(blocks[-1]).state)
Ejemplo n.º 5
0
def test_get_state_by_slot(valid_chain,
                           genesis_block,
                           genesis_state,
                           config,
                           keymap):
    # Fisrt, skip block and check if `get_state_by_slot` returns the expected state
    state_machine = valid_chain.get_state_machine(genesis_block.slot)
    state = state_machine.state
    block_skipped_slot = genesis_block.slot + 1
    block_skipped_state = state_machine.state_transition.apply_state_transition_without_block(
        state,
        block_skipped_slot,
    )
    with pytest.raises(StateSlotNotFound):
        valid_chain.get_state_by_slot(block_skipped_slot)
    valid_chain.chaindb.persist_state(block_skipped_state)
    assert valid_chain.get_state_by_slot(block_skipped_slot).root == block_skipped_state.root

    # Next, import proposed block and check if `get_state_by_slot` returns the expected state
    proposed_slot = block_skipped_slot + 1
    block = create_mock_block(
        state=block_skipped_state,
        config=config,
        state_machine=state_machine,
        block_class=genesis_block.__class__,
        parent_block=genesis_block,
        keymap=keymap,
        slot=proposed_slot,
        attestations=(),
    )
    valid_chain.import_block(block)
    state = valid_chain.get_state_machine().state
    assert valid_chain.get_state_by_slot(proposed_slot).root == state.root
Ejemplo n.º 6
0
def test_import_blocks(valid_chain, genesis_block, genesis_state, config, keymap):
    state = genesis_state
    blocks = (genesis_block,)
    valid_chain_2 = copy.deepcopy(valid_chain)
    for _ in range(3):
        block = create_mock_block(
            state=state,
            config=config,
            state_machine=valid_chain.get_state_machine(blocks[-1].slot),
            block_class=genesis_block.__class__,
            parent_block=blocks[-1],
            keymap=keymap,
            slot=state.slot + 2,
        )

        valid_chain.import_block(block)
        assert valid_chain.get_canonical_head() == block

        state = valid_chain.get_state_by_slot(block.slot)

        assert block == valid_chain.get_canonical_block_by_slot(block.slot)
        assert block.signing_root == valid_chain.get_canonical_block_root(block.slot)
        blocks += (block,)

    assert valid_chain.get_canonical_head() != valid_chain_2.get_canonical_head()

    for block in blocks[1:]:
        valid_chain_2.import_block(block)

    assert valid_chain.get_canonical_head() == valid_chain_2.get_canonical_head()
    assert valid_chain.get_state_by_slot(blocks[-1].slot).slot != 0
    assert valid_chain.get_state_by_slot(
        blocks[-1].slot
    ) == valid_chain_2.get_state_by_slot(blocks[-1].slot)
Ejemplo n.º 7
0
def test_per_slot_transition(base_db, genesis_block, genesis_state,
                             fixture_sm_class, config, state_slot, keymap):
    chaindb = BeaconChainDB(base_db)
    chaindb.persist_block(genesis_block, SerenityBeaconBlock)
    chaindb.persist_state(genesis_state)

    state = genesis_state

    # Create a block
    block = create_mock_block(
        state=state,
        config=config,
        state_machine=fixture_sm_class(
            chaindb,
            genesis_block,
        ),
        block_class=SerenityBeaconBlock,
        parent_block=genesis_block,
        keymap=keymap,
        slot=state_slot,
    )

    # Store in chaindb
    chaindb.persist_block(block, SerenityBeaconBlock)

    # Get state machine instance
    sm = fixture_sm_class(
        chaindb,
        block,
    )

    # Get state transition instance
    st = sm.state_transition_class(sm.config)

    # NOTE: we want to run both functions, however they are run independently
    # so we have two function calls
    updated_state = st.cache_state(state)
    updated_state = st.per_slot_transition(updated_state)

    # Ensure that slot gets increased by 1
    assert updated_state.slot == state.slot + 1

    # latest_block_roots
    latest_block_roots_index = (updated_state.slot -
                                1) % st.config.SLOTS_PER_HISTORICAL_ROOT
    assert updated_state.latest_block_roots[
        latest_block_roots_index] == block.previous_block_root

    # historical_roots
    if updated_state.slot % st.config.SLOTS_PER_HISTORICAL_ROOT == 0:
        historical_batch = HistoricalBatch(
            block_roots=state.latest_block_roots,
            state_roots=state.latest_state_roots,
            slots_per_historical_root=config.SLOTS_PER_HISTORICAL_ROOT,
        )
        assert updated_state.historical_roots[
            -1] == historical_batch.hash_tree_root
    else:
        assert updated_state.historical_roots == state.historical_roots
Ejemplo n.º 8
0
def test_per_slot_transition(base_db,
                             genesis_block,
                             genesis_state,
                             fixture_sm_class,
                             config,
                             state_slot,
                             keymap):
    chaindb = BeaconChainDB(base_db)
    chaindb.persist_block(genesis_block, SerenityBeaconBlock)
    chaindb.persist_state(genesis_state)

    state = genesis_state

    # Create a block
    block = create_mock_block(
        state=state,
        config=config,
        state_machine=fixture_sm_class(
            chaindb,
            genesis_block,
        ),
        block_class=SerenityBeaconBlock,
        parent_block=genesis_block,
        keymap=keymap,
        slot=state_slot,
    )

    # Store in chaindb
    chaindb.persist_block(block, SerenityBeaconBlock)

    # Get state machine instance
    sm = fixture_sm_class(
        chaindb,
        block,
    )

    # Get state transition instance
    st = sm.state_transition_class(sm.config)

    updated_state = st.per_slot_transition(state, block.parent_root)

    # Ensure that slot gets increased by 1
    assert updated_state.slot == state.slot + 1

    # latest_block_roots
    latest_block_roots_index = (updated_state.slot - 1) % st.config.SLOTS_PER_HISTORICAL_ROOT
    assert updated_state.latest_block_roots[latest_block_roots_index] == block.parent_root

    # historical_roots
    if updated_state.slot % st.config.SLOTS_PER_HISTORICAL_ROOT == 0:
        assert updated_state.historical_roots[-1] == get_merkle_root(
            updated_state.latest_block_roots
        )
    else:
        assert updated_state.historical_roots == state.historical_roots
Ejemplo n.º 9
0
def test_demo(base_db, validator_count, keymap, pubkeys, fork_choice_scoring):
    bls.use_noop_backend()
    slots_per_epoch = 8
    config = SERENITY_CONFIG._replace(
        SLOTS_PER_EPOCH=slots_per_epoch,
        GENESIS_EPOCH=slot_to_epoch(SERENITY_CONFIG.GENESIS_SLOT,
                                    slots_per_epoch),
        TARGET_COMMITTEE_SIZE=3,
        SHARD_COUNT=2,
        MIN_ATTESTATION_INCLUSION_DELAY=2,
    )
    override_vector_lengths(config)
    fixture_sm_class = SerenityStateMachine.configure(
        __name__='SerenityStateMachineForTesting',
        config=config,
    )

    genesis_slot = config.GENESIS_SLOT
    genesis_epoch = config.GENESIS_EPOCH
    chaindb = BeaconChainDB(base_db, config)
    attestation_pool = AttestationPool()

    # TODO(ralexstokes) clean up how the cache is populated
    for i in range(validator_count):
        pubkeys[i]

    genesis_state, genesis_block = create_mock_genesis(
        num_validators=validator_count,
        config=config,
        keymap=keymap,
        genesis_block_class=SerenityBeaconBlock,
    )
    for i in range(validator_count):
        assert genesis_state.validators[i].is_active(genesis_slot)

    chaindb.persist_block(genesis_block, SerenityBeaconBlock,
                          fork_choice_scoring)
    chaindb.persist_state(genesis_state)

    state = genesis_state
    block = genesis_block

    chain_length = 3 * config.SLOTS_PER_EPOCH
    blocks = (block, )

    attestations_map = {}  # Dict[Slot, Sequence[Attestation]]

    for current_slot in range(genesis_slot + 1,
                              genesis_slot + chain_length + 1):
        if current_slot > genesis_slot + config.MIN_ATTESTATION_INCLUSION_DELAY:
            attestations = attestations_map[
                current_slot - config.MIN_ATTESTATION_INCLUSION_DELAY]
        else:
            attestations = ()

        block = create_mock_block(
            state=state,
            config=config,
            state_machine=fixture_sm_class(
                chaindb,
                attestation_pool,
                blocks[-1].slot,
            ),
            block_class=SerenityBeaconBlock,
            parent_block=block,
            keymap=keymap,
            slot=current_slot,
            attestations=attestations,
        )

        # Get state machine instance
        sm = fixture_sm_class(
            chaindb,
            attestation_pool,
            blocks[-1].slot,
        )
        state, _ = sm.import_block(block)

        chaindb.persist_state(state)
        chaindb.persist_block(block, SerenityBeaconBlock, fork_choice_scoring)

        blocks += (block, )

        # Mock attestations
        attestation_slot = current_slot
        attestations = create_mock_signed_attestations_at_slot(
            state=state,
            config=config,
            state_machine=fixture_sm_class(
                chaindb,
                attestation_pool,
                block.slot,
            ),
            attestation_slot=attestation_slot,
            beacon_block_root=block.signing_root,
            keymap=keymap,
            voted_attesters_ratio=1.0,
        )
        attestations_map[attestation_slot] = attestations

    assert state.slot == chain_length + genesis_slot

    # Justification assertions
    assert state.current_justified_epoch == genesis_epoch
    assert state.finalized_epoch == genesis_epoch
Ejemplo n.º 10
0
def test_demo(base_db, num_validators, config, keymap, fixture_sm_class):
    genesis_slot = config.GENESIS_SLOT
    genesis_epoch = config.GENESIS_EPOCH
    chaindb = BeaconChainDB(base_db)

    genesis_state, genesis_block = create_mock_genesis(
        num_validators=num_validators,
        config=config,
        keymap=keymap,
        genesis_block_class=SerenityBeaconBlock,
    )
    for i in range(num_validators):
        assert genesis_state.validator_registry[i].is_active(genesis_slot)

    chaindb.persist_block(genesis_block, SerenityBeaconBlock)
    chaindb.persist_state(genesis_state)

    state = genesis_state
    block = genesis_block

    chain_length = 3 * config.SLOTS_PER_EPOCH
    blocks = (block, )

    attestations_map = {}  # Dict[Slot, Sequence[Attestation]]

    for current_slot in range(genesis_slot + 1,
                              genesis_slot + chain_length + 1):
        if current_slot > genesis_slot + config.MIN_ATTESTATION_INCLUSION_DELAY:
            attestations = attestations_map[
                current_slot - config.MIN_ATTESTATION_INCLUSION_DELAY]
        else:
            attestations = ()

        block = create_mock_block(
            state=state,
            config=config,
            state_machine=fixture_sm_class(
                chaindb,
                blocks[-1],
            ),
            block_class=SerenityBeaconBlock,
            parent_block=block,
            keymap=keymap,
            slot=current_slot,
            attestations=attestations,
        )

        # Get state machine instance
        sm = fixture_sm_class(
            chaindb,
            blocks[-1],
        )
        state, _ = sm.import_block(block)

        chaindb.persist_state(state)
        chaindb.persist_block(block, SerenityBeaconBlock)

        blocks += (block, )

        # Mock attestations
        attestation_slot = current_slot
        attestations = create_mock_signed_attestations_at_slot(
            state=state,
            config=config,
            state_machine=fixture_sm_class(
                chaindb,
                block,
            ),
            attestation_slot=attestation_slot,
            beacon_block_root=block.signed_root,
            keymap=keymap,
            voted_attesters_ratio=1.0,
        )
        attestations_map[attestation_slot] = attestations

    assert state.slot == chain_length + genesis_slot
    assert isinstance(sm.block, SerenityBeaconBlock)

    # Justification assertions
    assert state.current_justified_epoch == 2 + genesis_epoch
    assert state.finalized_epoch == 1 + genesis_epoch
Ejemplo n.º 11
0
def test_demo(base_db, validator_count, keymap, pubkeys, fork_choice_scoring):
    bls.use_noop_backend()
    config = MINIMAL_SERENITY_CONFIG
    override_lengths(config)
    fixture_sm_class = SerenityStateMachine.configure(
        __name__="SerenityStateMachineForTesting", config=config)

    genesis_slot = config.GENESIS_SLOT
    genesis_epoch = config.GENESIS_EPOCH
    chaindb = BeaconChainDB(base_db, config)

    genesis_state, genesis_block = create_mock_genesis(
        pubkeys=pubkeys[:validator_count],
        config=config,
        keymap=keymap,
        genesis_block_class=SerenityBeaconBlock,
    )
    for i in range(validator_count):
        assert genesis_state.validators[i].is_active(genesis_slot)

    chaindb.persist_block(
        SerenitySignedBeaconBlock.create(message=genesis_block),
        SerenitySignedBeaconBlock,
        fork_choice_scoring,
    )
    chaindb.persist_state(genesis_state)

    state = genesis_state
    block = SerenitySignedBeaconBlock.create(message=genesis_block)

    chain_length = 4 * config.SLOTS_PER_EPOCH
    blocks = (block, )

    attestations_map = {}  # Dict[Slot, Sequence[Attestation]]

    for current_slot in range(genesis_slot + 1,
                              genesis_slot + chain_length + 1):
        if current_slot > genesis_slot + config.MIN_ATTESTATION_INCLUSION_DELAY:
            attestations = attestations_map[
                current_slot - config.MIN_ATTESTATION_INCLUSION_DELAY]
        else:
            attestations = ()

        block = create_mock_block(
            state=state,
            config=config,
            state_machine=fixture_sm_class(chaindb),
            signed_block_class=SerenitySignedBeaconBlock,
            parent_block=block,
            keymap=keymap,
            slot=current_slot,
            attestations=attestations,
        )

        # Get state machine instance
        sm = fixture_sm_class(chaindb)
        state, _ = sm.import_block(block, state)

        chaindb.persist_state(state)
        chaindb.persist_block(block, SerenitySignedBeaconBlock,
                              fork_choice_scoring)

        blocks += (block, )

        # Mock attestations
        attestation_slot = current_slot
        attestations = create_mock_signed_attestations_at_slot(
            state=state,
            config=config,
            state_machine=fixture_sm_class(chaindb),
            attestation_slot=attestation_slot,
            beacon_block_root=block.signing_root,
            keymap=keymap,
            voted_attesters_ratio=1.0,
        )
        attestations_map[attestation_slot] = attestations

    assert state.slot == chain_length + genesis_slot

    # Justification assertions
    # NOTE: why are the number `2` or `3` used in the checks below?
    # Answer:
    # "We do not check any justification and finality during epochs 0 or 1. We do check for
    # justification and finality from epoch 2 onward."
    # [epoch 0]------[epoch 1]------>
    #
    # "In epoch 2, we justify the current epoch. This epoch is in fact justified but we do not
    # recognize it in the protocol due to an artifact of the construction of the genesis state
    # (using the `zero` value for `Checkpoint` type)."
    # [epoch 0]------[epoch 1]------[epoch 2]*------>
    # []*: checkpoint justified
    # []**: checkpoint finalized
    #
    # "In epoch 3, we have the previous justified checkpoint at the prior current justified
    # checkpoint (so `GENESIS_EPOCH + 2`) and we justify this current epoch. we check finality here
    # and see that we finalize the prior justified checkpoint at epoch 2."
    # [epoch 0]------[epoch 1]------[epoch 2]**------[epoch 3]*------>
    #
    # "Given the way we handle epoch processing (i.e. process a given epoch at the start of
    # the next epoch), we need to transition through `4 * SLOTS_PER_EPOCH` worth of slots to
    # include the processing of epoch 3."
    #
    # source: https://github.com/ethereum/trinity/pull/1214#issuecomment-546184080
    #
    # epoch | prev_justified_checkpoint | cur_justified_checkpoint | finalized_checkpoint
    # ------|---------------------------|--------------------------|---------------------
    # 0     | 0                         | 0                        | 0
    # 1     | 0                         | 0                        | 0
    # 2     | 0                         | 0                        | 0
    # 3     | 0                         | 2                        | 0
    # 4     | 2                         | 3                        | 2
    assert state.previous_justified_checkpoint.epoch == 2 + genesis_epoch
    assert state.current_justified_checkpoint.epoch == 3 + genesis_epoch
    assert state.finalized_checkpoint.epoch == 2 + genesis_epoch
Ejemplo n.º 12
0
def test_per_slot_transition(base_db, genesis_block, genesis_state,
                             fixture_sm_class, config, state_slot, keymap):
    chaindb = BeaconChainDB(base_db)
    chaindb.persist_block(genesis_block, SerenityBeaconBlock)
    chaindb.persist_state(genesis_state)

    state = genesis_state

    # Create a block
    block = create_mock_block(
        state=state,
        config=config,
        state_machine=fixture_sm_class(
            chaindb,
            genesis_block,
        ),
        block_class=SerenityBeaconBlock,
        parent_block=genesis_block,
        keymap=keymap,
        slot=state_slot,
    )

    # Store in chaindb
    chaindb.persist_block(block, SerenityBeaconBlock)

    # Get state machine instance
    sm = fixture_sm_class(
        chaindb,
        block,
    )

    # Get state transition instance
    st = sm.state_transition_class(sm.config)

    updated_state = st.per_slot_transition(state, block.parent_root)

    # Ensure that slot gets increased by 1
    assert updated_state.slot == state.slot + 1

    # Validator Registry
    # Tweaking the slot, so that we get the correct proposer index
    beacon_proposer_index = get_beacon_proposer_index(
        state,
        state.slot + 1,
        st.config.GENESIS_EPOCH,
        st.config.EPOCH_LENGTH,
        st.config.TARGET_COMMITTEE_SIZE,
        st.config.SHARD_COUNT,
    )
    for validator_index, _ in enumerate(updated_state.validator_registry):
        if validator_index != beacon_proposer_index:
            # Validator Record shouldn't change if not proposer
            assert (updated_state.validator_registry[validator_index] ==
                    state.validator_registry[validator_index])
        else:
            # randao layers of proposer's record should increase by 1
            assert (
                updated_state.validator_registry[validator_index].randao_layers
                == state.validator_registry[validator_index].randao_layers + 1)

    # latest_randao_mixes
    assert (
        updated_state.latest_randao_mixes[updated_state.slot %
                                          st.config.LATEST_RANDAO_MIXES_LENGTH]
        == state.latest_randao_mixes[(state.slot) %
                                     st.config.LATEST_RANDAO_MIXES_LENGTH])

    # latest_block_roots
    latest_block_roots_index = (updated_state.slot -
                                1) % st.config.LATEST_BLOCK_ROOTS_LENGTH
    assert updated_state.latest_block_roots[
        latest_block_roots_index] == block.parent_root

    # batched_block_roots
    if updated_state.slot % st.config.LATEST_BLOCK_ROOTS_LENGTH == 0:
        assert updated_state.batched_block_roots[-1] == get_merkle_root(
            updated_state.latest_block_roots)
    else:
        assert updated_state.batched_block_roots == state.batched_block_roots
Ejemplo n.º 13
0
def test_demo(base_db, keymap):
    slots_per_epoch = 8
    config = SERENITY_CONFIG._replace(
        SLOTS_PER_EPOCH=slots_per_epoch,
        GENESIS_EPOCH=slot_to_epoch(SERENITY_CONFIG.GENESIS_SLOT,
                                    slots_per_epoch),
        TARGET_COMMITTEE_SIZE=3,
        SHARD_COUNT=2,
        MIN_ATTESTATION_INCLUSION_DELAY=2,
    )
    fixture_sm_class = SerenityStateMachine.configure(
        __name__='SerenityStateMachineForTesting',
        config=config,
    )

    num_validators = 40

    genesis_slot = config.GENESIS_SLOT
    genesis_epoch = config.GENESIS_EPOCH
    chaindb = BeaconChainDB(base_db, config)

    genesis_state, genesis_block = create_mock_genesis(
        num_validators=num_validators,
        config=config,
        keymap=keymap,
        genesis_block_class=SerenityBeaconBlock,
    )
    for i in range(num_validators):
        assert genesis_state.validator_registry[i].is_active(genesis_slot)

    chaindb.persist_block(genesis_block, SerenityBeaconBlock)
    chaindb.persist_state(genesis_state)

    state = genesis_state
    block = genesis_block

    chain_length = 3 * config.SLOTS_PER_EPOCH
    blocks = (block, )

    attestations_map = {}  # Dict[Slot, Sequence[Attestation]]

    for current_slot in range(genesis_slot + 1,
                              genesis_slot + chain_length + 1):
        if current_slot > genesis_slot + config.MIN_ATTESTATION_INCLUSION_DELAY:
            attestations = attestations_map[
                current_slot - config.MIN_ATTESTATION_INCLUSION_DELAY]
        else:
            attestations = ()

        block = create_mock_block(
            state=state,
            config=config,
            state_machine=fixture_sm_class(
                chaindb,
                blocks[-1],
            ),
            block_class=SerenityBeaconBlock,
            parent_block=block,
            keymap=keymap,
            slot=current_slot,
            attestations=attestations,
        )

        # Get state machine instance
        sm = fixture_sm_class(
            chaindb,
            blocks[-1],
        )
        state, _ = sm.import_block(block)

        chaindb.persist_state(state)
        chaindb.persist_block(block, SerenityBeaconBlock)

        blocks += (block, )

        # Mock attestations
        attestation_slot = current_slot
        attestations = create_mock_signed_attestations_at_slot(
            state=state,
            config=config,
            state_machine=fixture_sm_class(
                chaindb,
                block,
            ),
            attestation_slot=attestation_slot,
            beacon_block_root=block.signing_root,
            keymap=keymap,
            voted_attesters_ratio=1.0,
        )
        attestations_map[attestation_slot] = attestations

    assert state.slot == chain_length + genesis_slot
    assert isinstance(sm.block, SerenityBeaconBlock)

    # Justification assertions
    assert state.current_justified_epoch == 2 + genesis_epoch
    assert state.finalized_epoch == 1 + genesis_epoch
Ejemplo n.º 14
0
def test_demo(base_db,
              num_validators,
              config,
              keymap,
              fixture_sm_class):
    chaindb = BeaconChainDB(base_db)

    genesis_state, genesis_block = create_mock_genesis(
        num_validators=num_validators,
        config=config,
        keymap=keymap,
        genesis_block_class=SerenityBeaconBlock,
    )
    for i in range(num_validators):
        assert genesis_state.validator_registry[i].is_active(0)

    chaindb.persist_block(genesis_block, SerenityBeaconBlock)
    chaindb.persist_state(genesis_state)

    state = genesis_state

    current_slot = 1
    chain_length = 3 * config.EPOCH_LENGTH
    attestations = ()
    for current_slot in range(chain_length):
        # two epochs
        block = create_mock_block(
            state=state,
            config=config,
            block_class=SerenityBeaconBlock,
            parent_block=genesis_block,
            keymap=keymap,
            slot=current_slot,
            attestations=attestations,
        )
        block = block.copy(
            body=block.body.copy(
                attestations=attestations,
            )
        )

        # Get state machine instance
        sm = fixture_sm_class(
            chaindb,
            block,
            parent_block_class=SerenityBeaconBlock,
        )
        state, _ = sm.import_block(block)

        # TODO: move to chain level?
        block = block.copy(
            state_root=state.root,
        )

        chaindb.persist_state(state)
        chaindb.persist_block(block, SerenityBeaconBlock)

        if current_slot > config.MIN_ATTESTATION_INCLUSION_DELAY:
            attestation_slot = current_slot - config.MIN_ATTESTATION_INCLUSION_DELAY
            attestations = create_mock_signed_attestations_at_slot(
                state,
                config,
                attestation_slot,
                keymap,
                1.0,
            )
        else:
            attestations = ()

    assert state.slot == chain_length - 1
    assert isinstance(sm.block, SerenityBeaconBlock)