@@ -1363,9 +1363,12 @@ def test_create_tx_header_gas_used(
13631363 intrinsic_cost = fork .transaction_intrinsic_cost_calculator ()
13641364 # Regular-only creation intrinsic; STOP initcode deploys empty
13651365 # code (zero deposit) and the pre-existing target adds no state
1366- # gas, so the regular intrinsic dominates.
1366+ # gas, so the regular intrinsic dominates. Block regular gas
1367+ # excludes any calldata-floor top-up, so use the raw intrinsic.
13671368 expected_gas_used = intrinsic_cost (
1368- calldata = bytes (initcode ), contract_creation = True
1369+ calldata = bytes (initcode ),
1370+ contract_creation = True ,
1371+ return_cost_deducted_prior_execution = True ,
13691372 )
13701373 else :
13711374 # For a minimal CREATE tx deploying Op.STOP (1 byte),
@@ -2162,27 +2165,38 @@ def test_failed_create_tx_refills_top_frame_new_account(
21622165
21632166 * REVERT preserves ``gas_left`` and ``refill_frame_state_gas`` returns
21642167 the spilled ``NEW_ACCOUNT`` to it, so the state block nets to zero
2165- and the sender pays only ``intrinsic_regular + revert_regular``.
2168+ and the sender pays only the regular consumption (pinned to the
2169+ calldata floor).
21662170 * HALT (INVALID) refills the spilled ``NEW_ACCOUNT`` to ``gas_left``
21672171 and then burns all of it, so the sender pays the full ``gas_limit``.
21682172 """
21692173 gas_costs = fork .gas_costs ()
21702174 intrinsic_calc = fork .transaction_intrinsic_cost_calculator ()
21712175
21722176 intrinsic_regular = intrinsic_calc (
2173- calldata = bytes (init_code ), contract_creation = True
2177+ calldata = bytes (init_code ),
2178+ contract_creation = True ,
2179+ return_cost_deducted_prior_execution = True ,
21742180 )
21752181 # gas_limit must cover the top-frame NEW_ACCOUNT so the initcode runs.
21762182 gas_limit = intrinsic_regular + gas_costs .NEW_ACCOUNT + 1000
21772183
21782184 if init_code == Op .INVALID :
21792185 # Exceptional halt burns all gas_left (the refilled NEW_ACCOUNT
21802186 # included).
2181- expected_gas_used = gas_limit
2187+ expected_header_gas = expected_receipt_gas = gas_limit
21822188 else :
21832189 # REVERT refills the spilled NEW_ACCOUNT, netting the state block
2184- # to zero, so only the regular consumption is billed.
2185- expected_gas_used = intrinsic_regular + init_code .regular_cost (fork )
2190+ # to zero, so only the regular consumption is billed. The tiny
2191+ # initcode pins the receipt to the calldata floor, which block
2192+ # regular gas excludes.
2193+ expected_header_gas = intrinsic_regular + init_code .regular_cost (fork )
2194+ expected_receipt_gas = max (
2195+ expected_header_gas ,
2196+ fork .transaction_data_floor_cost_calculator ()(
2197+ data = init_code , contract_creation = True
2198+ ),
2199+ )
21862200
21872201 sender = pre .fund_eoa ()
21882202 created = compute_create_address (address = sender , nonce = 0 )
@@ -2193,15 +2207,15 @@ def test_failed_create_tx_refills_top_frame_new_account(
21932207 gas_limit = gas_limit ,
21942208 sender = sender ,
21952209 expected_receipt = TransactionReceipt (
2196- cumulative_gas_used = expected_gas_used ,
2210+ cumulative_gas_used = expected_receipt_gas ,
21972211 ),
21982212 )
21992213
22002214 state_test (
22012215 pre = pre ,
22022216 post = {created : Account .NONEXISTENT },
22032217 tx = tx ,
2204- blockchain_test_header_verify = Header (gas_used = expected_gas_used ),
2218+ blockchain_test_header_verify = Header (gas_used = expected_header_gas ),
22052219 )
22062220
22072221
@@ -2271,11 +2285,12 @@ def test_create_tx_collision_refunds_reservoir(
22712285 address collision when `gas_limit > TX_MAX_GAS_LIMIT`.
22722286
22732287 EIP-8037 splits `gas_limit` into the capped regular budget and a
2274- state-gas reservoir. On collision the inner regular gas is burnt
2275- and `intrinsic_state_gas` is refunded; the reservoir must also
2276- be refunded to the sender. `header.gas_used` is fixed at the
2277- regular cap regardless of reservoir handling, so the sender's
2278- post-balance is the primary discriminating assertion.
2288+ state-gas reservoir seeded with the create component. On collision
2289+ the inner regular gas is burnt and the alive target is never
2290+ charged; the full reservoir must be returned to the sender.
2291+ `header.gas_used` is fixed at the regular cap regardless of
2292+ reservoir handling, so the sender's post-balance is the primary
2293+ discriminating assertion.
22792294 """
22802295 gas_limit_cap = fork .transaction_gas_limit_cap ()
22812296 assert gas_limit_cap is not None
@@ -2900,7 +2915,7 @@ def test_create_collision_burned_gas_counted_in_block_regular(
29002915 )
29012916
29022917 # CPSB-agnostic baseline: block_state_gas is zero for this tx (the
2903- # collision refunds the NEW_ACCOUNT state charge ), so header.gas_used
2918+ # existent collision target is not charged ), so header.gas_used
29042919 # equals the regular-gas total. Decompose the parent + inner frame
29052920 # accounting from fork APIs so the baseline tracks future cost
29062921 # changes automatically.
@@ -2922,23 +2937,21 @@ def test_create_collision_burned_gas_counted_in_block_regular(
29222937 )
29232938 # MSTORE writes the initcode at memory[0:32] (one word).
29242939 memory_expansion = fork .memory_expansion_gas_calculator ()(new_bytes = 32 )
2925- # gas_left at the moment NEW_ACCOUNT spills into the regular pool
2926- # (reservoir is empty for tx_gas_limit < TX_MAX_GAS_LIMIT) .
2927- gas_at_create_after_state = (
2940+ # gas_left at the CREATE split. The collision target is existent, so no
2941+ # account-creation charge is applied before the 63/64 split .
2942+ gas_at_create = (
29282943 gas_limit
29292944 - intrinsic
29302945 - factory_pre_create
29312946 - memory_expansion
29322947 - create_base
2933- - new_account
29342948 )
29352949 # Inner burns 63/64 of the available gas on collision; the parent
2936- # retains 1/64. The state-spill of NEW_ACCOUNT is refunded back to
2937- # gas_left on collision (nets zero). Post-CREATE consumes from the
2938- # retained pool. A mutation that drops the burned forwarded gas
2939- # from regular accounting would reduce this baseline.
2940- retained = gas_at_create_after_state // 64
2941- baseline_gas_used = gas_limit - retained - new_account + post_create_static
2950+ # retains 1/64. Post-CREATE consumes from the retained pool. A
2951+ # mutation that drops the burned forwarded gas from regular
2952+ # accounting would reduce this baseline.
2953+ retained = gas_at_create // 64
2954+ baseline_gas_used = gas_limit - retained + post_create_static
29422955
29432956 blockchain_test (
29442957 pre = pre ,
0 commit comments