Skip to content

test_extcodehash_empty_account_variants()

Documentation for tests/constantinople/eip1052_extcodehash/test_extcodehash.py::test_extcodehash_empty_account_variants@ffe48572.

Generate fixtures for these test cases for Bogota with:

fill -v tests/constantinople/eip1052_extcodehash/test_extcodehash.py::test_extcodehash_empty_account_variants --fork Bogota

Test EXTCODEHASH/EXTCODESIZE/EXTCODECOPY for empty-account variants.

Source code in tests/constantinople/eip1052_extcodehash/test_extcodehash.py
@pytest.mark.ported_from(
    [
        "https://github.com/ethereum/tests/blob/v13.3/src/GeneralStateTestsFiller/stExtCodeHash/extcodehashEmpty_ParisFiller.yml",  # noqa: E501
    ],
    pr=["https://github.com/ethereum/execution-specs/pull/2237"],
)
@pytest.mark.pre_alloc_mutable
@pytest.mark.parametrize(
    "account,call_before,expected_hash,expected_size,expected_copy",
    [
        pytest.param(
            Account(nonce=1),
            False,
            keccak256(b""),
            0,
            0,
            id="nonce-only",
        ),
        pytest.param(
            Account(balance=1),
            False,
            keccak256(b""),
            0,
            0,
            id="balance-only",
        ),
        pytest.param(
            Account(
                balance=10,
                storage={0x00: 0x01000000, 0xFFFFFFF: 0xFFFFFFFF},
            ),
            False,
            keccak256(b""),
            0,
            0,
            id="balance-storage",
        ),
        pytest.param(
            Account(code=Op.STOP),
            False,
            keccak256(bytes(Op.STOP)),
            1,
            0,
            id="single-byte-code",
        ),
        pytest.param(
            Account(balance=100, code=Op.PUSH2(0x60A7) + Op.SELFDESTRUCT),
            True,
            keccak256(bytes(Op.PUSH2(0x60A7) + Op.SELFDESTRUCT)),
            4,
            bytes(Op.PUSH2(0x60A7) + Op.SELFDESTRUCT).ljust(32, b"\0"),
            id="selfdestruct",
        ),
    ],
)
def test_extcodehash_empty_account_variants(
    state_test: StateTestFiller,
    pre: Alloc,
    account: Account,
    call_before: bool,
    expected_hash: bytes,
    expected_size: int,
    expected_copy: int | bytes,
) -> None:
    """
    Test EXTCODEHASH/EXTCODESIZE/EXTCODECOPY for empty-account variants.
    """
    storage = Storage()
    target_address = pre.nonexistent_account()
    pre[target_address] = account

    code = Op.JUMPDEST + (
        Op.CALL(gas=Op.GAS, address=target_address, value=0)
        if call_before
        else Op.NOOP
    )

    code += (
        Op.SSTORE(
            storage.store_next(expected_size),
            Op.EXTCODESIZE(target_address),
        )
        + Op.SSTORE(
            storage.store_next(expected_hash),
            Op.EXTCODEHASH(target_address),
        )
        + Op.EXTCODECOPY(target_address, 0, 0, 32)
        + Op.SSTORE(
            storage.store_next(expected_copy),
            Op.MLOAD(0),
        )
    )

    code_address = pre.deploy_contract(
        code, balance=10**18, storage=storage.canary()
    )

    tx = Transaction(sender=pre.fund_eoa(), to=code_address, value=1)

    state_test(
        pre=pre,
        post={
            code_address: Account(storage=storage),
        },
        tx=tx,
    )

Parametrized Test Cases

This test generates 5 parametrized test cases across 11 forks.