Skip to content

test_genesis_hash_available()

Documentation for tests/frontier/opcodes/test_blockhash.py::test_genesis_hash_available@88e9fb8f.

Generate fixtures for these test cases for Osaka with:

fill -v tests/frontier/opcodes/test_blockhash.py::test_genesis_hash_available --fork Osaka

Verify BLOCKHASH returns genesis and block 1 hashes.

Regression test: Blockchain test infrastructure must populate block hashes before execution. Without this, BLOCKHASH returns 0, breaking dynamic address computations like BLOCKHASH(0) | TIMESTAMP.

Tests both genesis (block 0) and first executed block (block 1) hash insertion by calling the contract in block 2.

Bug context: revm blockchaintest runner wasn't inserting block_hashes, causing failures in tests with BLOCKHASH-derived addresses.

Source code in tests/frontier/opcodes/test_blockhash.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
@pytest.mark.valid_from("Frontier")
def test_genesis_hash_available(blockchain_test: BlockchainTestFiller, pre: Alloc) -> None:
    """
    Verify BLOCKHASH returns genesis and block 1 hashes.

    Regression test: Blockchain test infrastructure must populate block hashes
    before execution. Without this, BLOCKHASH returns 0, breaking dynamic
    address computations like BLOCKHASH(0) | TIMESTAMP.

    Tests both genesis (block 0) and first executed block (block 1) hash
    insertion by calling the contract in block 2.

    Bug context: revm blockchaintest runner wasn't inserting block_hashes,
    causing failures in tests with BLOCKHASH-derived addresses.
    """
    storage = Storage()

    # Store ISZERO(BLOCKHASH(0)) and ISZERO(BLOCKHASH(1))
    # Both should be 0 (false) if hashes exist
    code = Op.SSTORE(storage.store_next(0), Op.ISZERO(Op.BLOCKHASH(0))) + Op.SSTORE(
        storage.store_next(0), Op.ISZERO(Op.BLOCKHASH(1))
    )

    contract = pre.deploy_contract(code=code)
    sender = pre.fund_eoa()

    blocks = [
        Block(
            txs=[
                Transaction(
                    sender=sender,
                    to=contract,
                    gas_limit=100_000,
                    protected=False,
                )
            ]
        ),
        Block(
            txs=[
                Transaction(
                    sender=sender,
                    to=contract,
                    gas_limit=100_000,
                    protected=False,
                )
            ]
        ),
    ]

    post = {
        contract: Account(
            storage={
                0: 0,  # ISZERO(BLOCKHASH(0)) = 0 (genesis hash exists)
                1: 0,  # ISZERO(BLOCKHASH(1)) = 0 (block 1 hash exists)
            }
        )
    }

    blockchain_test(pre=pre, post=post, blocks=blocks)

Parametrized Test Cases

This test case is only parametrized by fork.

Test ID (Abbreviated)
...fork_Frontier-blockchain_test
...fork_Homestead-blockchain_test
...fork_Byzantium-blockchain_test
...fork_Constantinople-blockchain_test
...fork_ConstantinopleFix-blockchain_test
...fork_Istanbul-blockchain_test
...fork_Berlin-blockchain_test
...fork_London-blockchain_test
...fork_Paris-blockchain_test
...fork_Shanghai-blockchain_test
...fork_Cancun-blockchain_test
...fork_Prague-blockchain_test
...fork_Osaka-blockchain_test