Example #1
0
def fixture_sm_class(config, fork_choice_scoring, fork_choice_scoring_class):
    return SerenityStateMachine.configure(
        __name__="SerenityStateMachineForTesting",
        config=config,
        get_fork_choice_scoring=lambda self: fork_choice_scoring,
        fork_choice_scoring_class=fork_choice_scoring_class,
    )
Example #2
0
def execute_state_transtion(test_case, base_db):
    bls.use_noop_backend()
    dict_config = test_case['config']
    verify_signatures = test_case['verify_signatures']
    dict_initial_state = test_case['initial_state']
    dict_blocks = test_case['blocks']
    dict_expected_state = test_case['expected_state']

    # TODO: make it case by case
    assert verify_signatures is False

    # Set config
    config = generate_config_by_dict(dict_config)

    # Set Vector fields
    override_vector_lengths(config)

    # Set pre_state
    pre_state = from_formatted_dict(dict_initial_state, BeaconState)

    # Set blocks
    blocks = ()
    for dict_block in dict_blocks:
        block = from_formatted_dict(dict_block, SerenityBeaconBlock)
        blocks += (block, )

    sm_class = SerenityStateMachine.configure(
        __name__='SerenityStateMachineForTesting',
        config=config,
    )
    chaindb = BeaconChainDB(base_db, Eth2GenesisConfig(config))
    attestation_pool = AttestationPool()

    post_state = pre_state.copy()
    for block in blocks:
        sm = sm_class(chaindb, attestation_pool, None, post_state)
        post_state, _ = sm.import_block(block)

    # Use dict diff, easier to see the diff
    dict_post_state = to_formatted_dict(post_state, BeaconState)

    for key, value in dict_expected_state.items():
        if isinstance(value, list):
            value = tuple(value)
        assert dict_post_state[key] == value
Example #3
0
def fixture_sm_class(config):
    return SerenityStateMachine.configure(
        __name__='SerenityStateMachineForTesting',
        config=config,
    )
Example #4
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
Example #5
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
Example #6
0
def get_sm_class_of_config(config):
    return SerenityStateMachine.configure(
        __name__='SerenityStateMachineForTesting',
        config=config,
    )
Example #7
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
Example #8
0
def test_serenity_state_machine_class_well_defined(
        genesis_fork_choice_context):
    state_machine = SerenityStateMachine(
        chaindb=None, fork_choice_context=genesis_fork_choice_context)
    assert state_machine.get_block_class()