Skip to content

test_create_suicide_during_transaction_create()

Documentation for tests/frontier/create/test_create_suicide_during_init.py::test_create_suicide_during_transaction_create@2867859a.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/frontier/create/test_create_suicide_during_init.py::test_create_suicide_during_transaction_create --fork Amsterdam

Contract init code calls suicide then measures different metrics.

Source code in tests/frontier/create/test_create_suicide_during_init.py
 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
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
@pytest.mark.ported_from(
    [
        "https://github.com/ethereum/tests/blob/v13.3/src/GeneralStateTestsFiller/stCreateTest/CREATE_ContractSuicideDuringInit_ThenStoreThenReturnFiller.json",
        "https://github.com/ethereum/tests/blob/v13.3/src/GeneralStateTestsFiller/stCreateTest/CREATE_ContractSuicideDuringInit_WithValueFiller.json",
        "https://github.com/ethereum/tests/blob/v13.3/src/GeneralStateTestsFiller/stCreateTest/CREATE_ContractSuicideDuringInit_WithValueToItselfFiller.json",
        "https://github.com/ethereum/tests/blob/v13.3/src/GeneralStateTestsFiller/stCreateTest/CREATE_ContractSuicideDuringInitFiller.json",
    ],
    pr=["https://github.com/ethereum/execution-spec-tests/pull/1871"],
    coverage_missed_reason="Tip to coinbase, og test contains empty account.",
)
@pytest.mark.valid_from("Frontier")
@pytest.mark.with_all_create_opcodes
@pytest.mark.parametrize("transaction_create", [False, True])
@pytest.mark.parametrize(
    "operation",
    [Operation.SUICIDE, Operation.SUICIDE_TO_ITSELF],
)
@pytest.mark.filter_combinations(
    lambda create_opcode, transaction_create, **_: (
        create_opcode == Op.CREATE or not transaction_create
    ),
    reason="transaction_create only valid with CREATE",
)
@pytest.mark.eels_base_coverage
def test_create_suicide_during_transaction_create(
    state_test: StateTestFiller,
    fork: Fork,
    pre: Alloc,
    create_opcode: Op,
    operation: Operation,
    transaction_create: bool,
) -> None:
    """Contract init code calls suicide then measures different metrics."""
    sender = pre.fund_eoa()
    contract_deploy = pre.deploy_contract(
        code=Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE)
        + create_opcode(size=Op.CALLDATASIZE(), value=Op.CALLVALUE())
    )
    contract_success = pre.deploy_contract(code=Op.SSTORE(1, 1))
    self_destruct_destination = pre.deploy_contract(code=Op.STOP)
    contract_after_suicide = pre.deploy_contract(code=Op.SSTORE(1, 1))

    contract_initcode = Initcode(
        initcode_prefix=Op.CALL(
            address=contract_success, gas=Op.SUB(Op.GAS, 100_000)
        )
        + Op.SELFDESTRUCT(
            Op.ADDRESS
            if operation == Operation.SUICIDE_TO_ITSELF
            else self_destruct_destination
        )
        + Op.CALL(address=contract_after_suicide, gas=Op.SUB(Op.GAS, 100_000)),
        deploy_code=Op.SSTORE(0, 1),
    )

    expected_create_address = compute_create_address(
        address=sender if transaction_create else contract_deploy,
        nonce=0 if transaction_create else 1,
        initcode=contract_initcode,
        opcode=create_opcode,
    )

    tx_value = 100
    tx = Transaction(
        to=None if transaction_create else contract_deploy,
        data=contract_initcode,
        value=tx_value,
        sender=sender,
        protected=fork.supports_protected_txs(),
    )

    # per EIP-8246
    selfdestruct_to_self_preserves_balance = (
        fork.is_eip_enabled(8246) and operation == Operation.SUICIDE_TO_ITSELF
    )
    post = {
        contract_success: Account(storage={1: 1}),
        self_destruct_destination: Account(
            balance=0 if operation == Operation.SUICIDE_TO_ITSELF else tx_value
        ),
        contract_deploy: Account(storage={0: 0}),
        contract_after_suicide: Account(
            storage={1: 0}
        ),  # suicide eats all gas
        expected_create_address: (
            Account(balance=tx_value, nonce=0, code=b"", storage={})
            if selfdestruct_to_self_preserves_balance
            else Account.NONEXISTENT
        ),
    }
    state_test(env=Environment(), pre=pre, post=post, tx=tx)

Parametrized Test Cases

This test generates 6 parametrized test cases across 16 forks.