Skip to content

test_inner_create_succeeds_code_deposit_state_gas()

Documentation for tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py::test_inner_create_succeeds_code_deposit_state_gas@c74f1a67.

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_inner_create_succeeds_code_deposit_state_gas --fork Amsterdam

Verify state gas accumulation and top-level failure refund in a creation tx whose initcode runs a successful inner CREATE.

Source code in tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
@pytest.mark.parametrize(
    "outer_outcome",
    [
        pytest.param("succeeds", id="outer_succeeds"),
        pytest.param("reverts", id="outer_reverts"),
        pytest.param("halts", id="outer_halts"),
    ],
)
@pytest.mark.with_all_create_opcodes()
@pytest.mark.valid_from("EIP8037")
def test_inner_create_succeeds_code_deposit_state_gas(
    blockchain_test: BlockchainTestFiller,
    pre: Alloc,
    fork: Fork,
    create_opcode: Op,
    outer_outcome: str,
) -> None:
    """
    Verify state gas accumulation and top-level failure refund in a
    creation tx whose initcode runs a successful inner CREATE.
    """
    gas_costs = fork.gas_costs()
    outer_state_gas = fork.create_state_gas(code_size=0)
    inner_code_deposit = fork.code_deposit_state_gas(code_size=1)
    inner_state_gas = gas_costs.NEW_ACCOUNT + inner_code_deposit

    deploy_code = Op.STOP
    inner_initcode = Op.MSTORE(
        0,
        int.from_bytes(bytes(deploy_code), "big") << 248,
    ) + Op.RETURN(31, 1)
    inner_bytes = bytes(inner_initcode)

    setup = Op.MSTORE(
        0,
        int.from_bytes(inner_bytes, "big") << (256 - 8 * len(inner_bytes)),
    )
    if create_opcode == Op.CREATE2:
        inner_create = Op.POP(Op.CREATE2(0, 0, len(inner_bytes), 0))
    else:
        inner_create = Op.POP(Op.CREATE(0, 0, len(inner_bytes)))

    if outer_outcome == "succeeds":
        termination = Op.RETURN(0, 0)
    elif outer_outcome == "reverts":
        termination = Op.REVERT(0, 0)
    else:
        termination = Op.INVALID

    initcode = setup + inner_create + termination

    sender = pre.fund_eoa()
    intrinsic_calc = fork.transaction_intrinsic_cost_calculator()
    intrinsic_total = intrinsic_calc(
        calldata=bytes(initcode), contract_creation=True
    )

    if outer_outcome == "halts":
        initcode_gas = initcode.regular_cost(fork)
    else:
        initcode_gas = initcode.gas_cost(fork)
    gas_limit = intrinsic_total + initcode_gas + inner_code_deposit + 1000

    create_address = compute_create_address(address=sender, nonce=0)

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

    if outer_outcome == "succeeds":
        post: dict = {create_address: Account(code=b"")}
        block = Block(
            txs=[tx],
            header_verify=Header(gas_used=outer_state_gas + inner_state_gas),
        )
    else:
        post = {create_address: Account.NONEXISTENT}
        block = Block(txs=[tx])

    blockchain_test(pre=pre, blocks=[block], post=post)

Parametrized Test Cases

This test generates 6 parametrized test cases across 1 fork.