Skip to content

Commit 9089fa5

Browse files
committed
fix(tests): 8037 strengthen review-flagged test assertions and parametrize
1 parent e0e103b commit 9089fa5

3 files changed

Lines changed: 91 additions & 20 deletions

File tree

tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_block_2d_gas_accounting.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
Storage,
2424
Transaction,
2525
TransactionException,
26+
TransactionReceipt,
2627
)
2728

2829
from .spec import ref_spec_8037
@@ -593,15 +594,36 @@ def test_receipt_cumulative_differs_from_header_gas_used(
593594
tx_regular, tx_state = sstore_tx_gas(fork)
594595
num_txs = 3
595596

596-
txs, post = sstore_txs(pre, fork, num_txs)
597+
gas_limit_cap = fork.transaction_gas_limit_cap()
598+
assert gas_limit_cap is not None
599+
tx_gas_limit = gas_limit_cap + fork.sstore_state_gas()
600+
per_tx_gas_used = tx_regular + tx_state
601+
602+
txs: list[Transaction] = []
603+
post: dict = {}
604+
for i in range(num_txs):
605+
storage = Storage()
606+
contract = pre.deploy_contract(
607+
code=Op.SSTORE(storage.store_next(1), 1) + Op.STOP,
608+
)
609+
txs.append(
610+
Transaction(
611+
to=contract,
612+
gas_limit=tx_gas_limit,
613+
sender=pre.fund_eoa(),
614+
expected_receipt=TransactionReceipt(
615+
cumulative_gas_used=(i + 1) * per_tx_gas_used,
616+
),
617+
)
618+
)
619+
post[contract] = Account(storage=storage)
597620

598621
block_regular = num_txs * tx_regular
599622
block_state = num_txs * tx_state
600623
header_gas_used = max(block_regular, block_state)
601-
receipt_cumulative = num_txs * (tx_regular + tx_state)
602624

603625
assert block_state > block_regular
604-
assert header_gas_used < receipt_cumulative
626+
assert header_gas_used < num_txs * per_tx_gas_used
605627

606628
blockchain_test(
607629
pre=pre,

tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_call.py

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,41 +1393,59 @@ def test_callcode_value_no_new_account_state_gas(
13931393
sender=pre.fund_eoa(),
13941394
)
13951395

1396-
post = {contract: Account(storage=storage)}
1396+
post = {
1397+
contract: Account(storage=storage),
1398+
target: Account.NONEXISTENT,
1399+
}
13971400
state_test(pre=pre, post=post, tx=tx)
13981401

13991402

1403+
@pytest.mark.with_all_create_opcodes()
14001404
@pytest.mark.valid_from("EIP8037")
14011405
def test_create_oog_during_state_gas_charge(
14021406
state_test: StateTestFiller,
14031407
pre: Alloc,
14041408
fork: Fork,
1409+
create_opcode: Op,
14051410
) -> None:
14061411
"""
14071412
Verify the parent reservoir is refunded when a child's CREATE
1408-
OOGs while charging account-creation state gas.
1413+
OOGs while charging account-creation state gas. The grandchild
1414+
SSTORE is forwarded only its regular stipend, so it succeeds
1415+
only if the refund landed in the reservoir (not in `gas_left`).
14091416
"""
14101417
gas_limit_cap = fork.transaction_gas_limit_cap()
14111418
assert gas_limit_cap is not None
1419+
gas_costs = fork.gas_costs()
14121420
sstore_state_gas = fork.sstore_state_gas()
14131421

14141422
init_code = Op.STOP
1423+
inner_create_call = (
1424+
create_opcode(value=0, offset=31, size=1, salt=0)
1425+
if create_opcode == Op.CREATE2
1426+
else create_opcode(value=0, offset=31, size=1)
1427+
)
14151428

14161429
inner = pre.deploy_contract(
14171430
code=(
14181431
Op.MSTORE(
14191432
0,
14201433
int.from_bytes(bytes(init_code), "big") << 248,
14211434
)
1422-
+ Op.POP(Op.CREATE(0, 31, 1))
1435+
+ Op.POP(inner_create_call)
14231436
),
14241437
)
14251438

1426-
storage = Storage()
1439+
grandchild = pre.deploy_contract(code=Op.SSTORE(0, 1))
1440+
1441+
push_cost = 2 * gas_costs.GAS_VERY_LOW
1442+
sstore_regular = gas_costs.GAS_COLD_STORAGE_WRITE
1443+
grandchild_stipend = push_cost + sstore_regular
1444+
14271445
parent = pre.deploy_contract(
14281446
code=(
14291447
Op.POP(Op.CALL(gas=20_000, address=inner))
1430-
+ Op.SSTORE(storage.store_next(1), 1)
1448+
+ Op.POP(Op.CALL(gas=grandchild_stipend, address=grandchild))
14311449
),
14321450
)
14331451

@@ -1437,8 +1455,11 @@ def test_create_oog_during_state_gas_charge(
14371455
sender=pre.fund_eoa(),
14381456
)
14391457

1440-
post = {parent: Account(storage=storage)}
1441-
state_test(pre=pre, post=post, tx=tx)
1458+
state_test(
1459+
pre=pre,
1460+
post={grandchild: Account(storage={0: 1})},
1461+
tx=tx,
1462+
)
14421463

14431464

14441465
@pytest.mark.valid_from("EIP8037")
@@ -1477,16 +1498,26 @@ def test_call_new_account_no_regular_account_creation_cost(
14771498
state_test(pre=pre, post={target: Account(balance=1)}, tx=tx)
14781499

14791500

1501+
@pytest.mark.parametrize(
1502+
"call_opcode",
1503+
[
1504+
pytest.param(Op.CALL, id="call"),
1505+
pytest.param(Op.DELEGATECALL, id="delegatecall"),
1506+
],
1507+
)
14801508
@pytest.mark.valid_from("EIP8037")
14811509
def test_child_failure_refunds_state_gas_to_reservoir_not_gas_left(
14821510
state_test: StateTestFiller,
14831511
pre: Alloc,
14841512
fork: Fork,
1513+
call_opcode: Op,
14851514
) -> None:
14861515
"""
14871516
Verify state gas from a failing child is restored to the
14881517
reservoir (not regular gas), so a grandchild SSTORE can draw
1489-
from it under a tight regular stipend.
1518+
from it under a tight regular stipend. Parametrized across CALL
1519+
(grandchild writes to its own storage) and DELEGATECALL
1520+
(grandchild writes to the parent's storage via shared context).
14901521
"""
14911522
gas_limit_cap = fork.transaction_gas_limit_cap()
14921523
assert gas_limit_cap is not None
@@ -1506,8 +1537,8 @@ def test_child_failure_refunds_state_gas_to_reservoir_not_gas_left(
15061537

15071538
parent = pre.deploy_contract(
15081539
code=(
1509-
Op.POP(Op.CALL(gas=Op.GAS, address=child))
1510-
+ Op.POP(Op.CALL(gas=grandchild_stipend, address=grandchild))
1540+
Op.POP(call_opcode(gas=Op.GAS, address=child))
1541+
+ Op.POP(call_opcode(gas=grandchild_stipend, address=grandchild))
15111542
),
15121543
)
15131544

@@ -1517,8 +1548,12 @@ def test_child_failure_refunds_state_gas_to_reservoir_not_gas_left(
15171548
sender=pre.fund_eoa(),
15181549
)
15191550

1520-
state_test(
1521-
pre=pre,
1522-
post={grandchild: Account(storage={0: 1})},
1523-
tx=tx,
1524-
)
1551+
# DELEGATECALL executes the callee in the caller's storage
1552+
# context, so grandchild's SSTORE lands on `parent` instead of
1553+
# `grandchild`.
1554+
if call_opcode == Op.DELEGATECALL:
1555+
post: dict = {parent: Account(storage={0: 1})}
1556+
else:
1557+
post = {grandchild: Account(storage={0: 1})}
1558+
1559+
state_test(pre=pre, post=post, tx=tx)

tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1930,10 +1930,24 @@ def test_nested_create_fail_parent_revert_state_gas(
19301930
sender=pre.fund_eoa(),
19311931
)
19321932

1933+
inner_address = compute_create_address(
1934+
address=factory,
1935+
nonce=1,
1936+
salt=0,
1937+
initcode=bytes(init_code),
1938+
opcode=create_opcode,
1939+
)
1940+
19331941
if parent_reverts:
1934-
post = {factory: Account(nonce=1)}
1942+
post = {
1943+
factory: Account(nonce=1),
1944+
inner_address: Account.NONEXISTENT,
1945+
}
19351946
else:
1936-
post = {factory: Account(nonce=2)}
1947+
post = {
1948+
factory: Account(nonce=2),
1949+
inner_address: Account.NONEXISTENT,
1950+
}
19371951

19381952
blockchain_test(
19391953
pre=pre,

0 commit comments

Comments
 (0)