Skip to content

test_create_tx_collision_no_new_account_charge()

Documentation for tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_create_tx_collision_no_new_account_charge@26332146.

Generate fixtures for these test cases for Amsterdam with:

fill -v tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_create_tx_collision_no_new_account_charge --fork Amsterdam

Verify a creation-tx address collision charges no NEW_ACCOUNT.

Under EIP-2780 the created account's NEW_ACCOUNT is a top-frame charge, but on an address collision the target already exists pre-tx, the create path returns AddressCollision before the top frame is prepared, and no NEW_ACCOUNT is ever charged. The full forwarded gas is burned as execution (no initcode runs) and block state-gas is zero, so header gas_used equals the whole gas_limit.

Source code in tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
@pytest.mark.pre_alloc_mutable()
@pytest.mark.valid_from("EIP8037")
def test_create_tx_collision_no_new_account_charge(
    blockchain_test: BlockchainTestFiller,
    pre: Alloc,
    fork: Fork,
) -> None:
    """
    Verify a creation-tx address collision charges no NEW_ACCOUNT.

    Under EIP-2780 the created account's ``NEW_ACCOUNT`` is a top-frame
    charge, but on an address collision the target already exists
    pre-tx, the create path returns ``AddressCollision`` before the top
    frame is prepared, and no ``NEW_ACCOUNT`` is ever charged. The full
    forwarded gas is burned as execution (no initcode runs) and block
    state-gas is zero, so header ``gas_used`` equals the whole
    ``gas_limit``.
    """
    intrinsic_calc = fork.transaction_intrinsic_cost_calculator()

    init_code = Op.STOP
    intrinsic_execution = intrinsic_calc(
        calldata=bytes(init_code), contract_creation=True
    )
    gas_limit = intrinsic_execution + 1000

    sender = pre.fund_eoa()
    collision_target = compute_create_address(address=sender, nonce=0)
    pre[collision_target] = Account(nonce=1)

    # Collision burns the full forwarded gas as execution; state block is
    # zero (no NEW_ACCOUNT charged).
    expected_gas_used = gas_limit

    tx = Transaction(
        to=None,
        data=init_code,
        gas_limit=gas_limit,
        sender=sender,
    )

    blockchain_test(
        pre=pre,
        blocks=[
            Block(
                txs=[tx],
                header_verify=Header(gas_used=expected_gas_used),
            ),
        ],
        post={collision_target: Account(nonce=1)},
    )

Parametrized Test Cases

This test generates 1 parametrized test case across 1 fork.