예제 #1
0
def test_get_pow_block_at_terminal_total_difficulty(spec, state):
    for result in expected_results:
        (
            block_reached_ttd,
            block_parent_hash_is_empty,
            parent_reached_ttd,
            return_block
        ) = result
        pow_chain = prepare_random_pow_chain(spec, 2)
        pow_chain.head(-1).parent_hash = spec.Hash32()

        if block_reached_ttd:
            pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY
        else:
            pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY - 1

        if parent_reached_ttd:
            pow_chain.head(-1).total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY
        else:
            pow_chain.head(-1).total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY - 1

        if block_parent_hash_is_empty:
            pow_chain.head().parent_hash = spec.Hash32()

        pow_block = spec.get_pow_block_at_terminal_total_difficulty(pow_chain.to_dict())
        if return_block == IS_HEAD_BLOCK:
            assert pow_block == pow_chain.head()
        elif return_block == IS_HEAD_PARENT_BLOCK:
            assert pow_block == pow_chain.head(-1)
        elif return_block is None:
            assert pow_block is None
        else:
            raise Exception('Something is wrong')
예제 #2
0
def test_validate_merge_block_fail_after_terminal(spec, state):
    pow_chain = prepare_random_pow_chain(spec, 2)
    pow_chain.head(-1).total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY
    pow_chain.head(
    ).total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY + uint256(1)
    block = build_empty_block_for_next_slot(spec, state)
    block.body.execution_payload.parent_hash = pow_chain.head().block_hash
    run_validate_merge_block(spec, pow_chain, block, valid=False)
예제 #3
0
def test_validate_merge_block_fail_block_lookup(spec, state):
    pow_chain = prepare_random_pow_chain(spec, 2)
    pow_chain.head(
        -1
    ).total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY - uint256(1)
    pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY
    block = build_empty_block_for_next_slot(spec, state)
    run_validate_merge_block(spec, pow_chain, block, valid=False)
예제 #4
0
def test_validate_merge_block_fail_parent_hash_is_not_tbh(spec, state):
    pow_chain = prepare_random_pow_chain(spec, 2)
    # shouldn't fail if TTD check is reached
    pow_chain.head(
        -1
    ).total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY - uint256(1)
    pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY
    block = build_empty_block_for_next_slot(spec, state)
    block.body.execution_payload.parent_hash = pow_chain.head().block_hash
    run_validate_merge_block(spec, pow_chain, block, valid=False)
예제 #5
0
def test_validate_merge_block_tbh_override_success(spec, state):
    pow_chain = prepare_random_pow_chain(spec, 2)
    # should fail if TTD check is reached
    pow_chain.head(
        -1
    ).total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY - uint256(2)
    pow_chain.head(
    ).total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY - uint256(1)
    pow_chain.head().block_hash = TERMINAL_BLOCK_HASH
    block = build_empty_block_for_next_slot(spec, state)
    block.body.execution_payload.parent_hash = pow_chain.head().block_hash
    run_validate_merge_block(spec, pow_chain, block)
예제 #6
0
def test_prepare_execution_payload(spec, state):
    for result in prepare_execution_payload_expected_results:
        (
            is_merge_complete,
            is_terminal_block_hash_set,
            is_activation_epoch_reached,
            terminal_pow_block_is_none,
            result_payload_id,
        ) = result

        # 1. Handle `is_merge_complete`
        if is_merge_complete:
            state.latest_execution_payload_header = spec.ExecutionPayloadHeader(prev_randao=b'\x12' * 32)
        else:
            state.latest_execution_payload_header = spec.ExecutionPayloadHeader()

        # 2. `is_terminal_block_hash_set` and `is_activation_epoch_reached` require mocking configs in runtime
        config_overrides = {}
        _mock_terminal_block_hash = b'\x34' * 32
        if is_terminal_block_hash_set:
            config_overrides['TERMINAL_BLOCK_HASH'] = _mock_terminal_block_hash
        else:
            config_overrides['TERMINAL_BLOCK_HASH'] = spec.Hash32()

        # Default `TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH` is too big and too close to overflow
        _mock_terminal_block_hash_activation_epoch = 3
        config_overrides['TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH'] = _mock_terminal_block_hash_activation_epoch
        if is_activation_epoch_reached:
            state.slot = _mock_terminal_block_hash_activation_epoch * spec.SLOTS_PER_EPOCH
        else:
            state.slot = (_mock_terminal_block_hash_activation_epoch - 1) * spec.SLOTS_PER_EPOCH

        # Logic from `with_config_overrides`
        old_config = spec.config
        tmp_config = deepcopy(old_config._asdict())
        tmp_config.update(config_overrides)
        config_types = spec.Configuration.__annotations__
        test_config = {k: config_types[k](v) for k, v in tmp_config.items()}
        spec.config = spec.Configuration(**test_config)

        # 3. Handle `terminal_pow_block_is_none`
        pow_chain = prepare_random_pow_chain(spec, 2)
        if terminal_pow_block_is_none:
            pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY - 1
        else:
            if is_terminal_block_hash_set:
                pow_chain.head().block_hash = _mock_terminal_block_hash
            pow_chain.head().total_difficulty = spec.config.TERMINAL_TOTAL_DIFFICULTY

        # Dummy arguments
        finalized_block_hash = b'\x56' * 32
        safe_block_hash = b'\x58' * 32
        suggested_fee_recipient = b'\x78' * 20

        # Mock execution_engine
        class TestEngine(spec.NoopExecutionEngine):
            def notify_forkchoice_updated(self,
                                          head_block_hash,
                                          safe_block_hash,
                                          finalized_block_hash,
                                          payload_attributes) -> Optional[spec.PayloadId]:
                return SAMPLE_PAYLOAD_ID

        payload_id = spec.prepare_execution_payload(
            state=state,
            pow_chain=pow_chain.to_dict(),
            safe_block_hash=safe_block_hash,
            finalized_block_hash=finalized_block_hash,
            suggested_fee_recipient=suggested_fee_recipient,
            execution_engine=TestEngine(),
        )
        assert payload_id == result_payload_id

        # Restore config
        spec.config = old_config