Skip to content

Commit 657d6ef

Browse files
committed
feat(spec,test): Update CPSB as per EIP updates for bal-devnet-7
1 parent 1777143 commit 657d6ef

13 files changed

Lines changed: 81 additions & 72 deletions

File tree

packages/testing/src/execution_testing/cli/pytest_commands/plugins/shared/transaction_fixtures.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ def type_3_default_transaction(sender: EOA) -> Transaction:
9191

9292

9393
@pytest.fixture
94-
def type_4_default_transaction(sender: EOA, pre: Alloc) -> Transaction:
94+
def type_4_default_transaction(
95+
sender: EOA, pre: Alloc, fork: Fork
96+
) -> Transaction:
9597
"""Type 4 (set code) default transaction introduced in Prague fork."""
9698
# Create authorized accounts with funds
9799
auth_signer1 = pre.fund_eoa(amount=10**18)
@@ -101,12 +103,16 @@ def type_4_default_transaction(sender: EOA, pre: Alloc) -> Transaction:
101103
target1 = pre.deploy_contract(Op.SSTORE(0, 1))
102104
target2 = pre.deploy_contract(Op.SSTORE(0, 1))
103105

106+
# Recipient may be a nonexistent account (e.g., EIP-7708 transfer
107+
# log tests), so cover one NEW_ACCOUNT state charge. NEW_ACCOUNT
108+
# is the legacy 25_000 pre-EIP-8037 and scales with cpsb on
109+
# Amsterdam, keeping this budget CPSB-agnostic.
104110
return Transaction(
105111
ty=4,
106112
sender=sender,
107113
max_fee_per_gas=10**10,
108114
max_priority_fee_per_gas=10**9,
109-
gas_limit=500_000,
115+
gas_limit=500_000 + fork.gas_costs().NEW_ACCOUNT,
110116
data=b"\x00" * 200,
111117
access_list=[
112118
AccessList(address=0x4567, storage_keys=[1000, 2000, 3000]),

packages/testing/src/execution_testing/forks/forks/eips/amsterdam/eip_8037.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def cost_per_state_byte(cls) -> int:
2828
"""
2929
Return the fixed cost per state byte for EIP-8037.
3030
"""
31-
return 1174
31+
return 1530
3232

3333
@classmethod
3434
def sstore_state_gas(cls) -> int:

src/ethereum/forks/amsterdam/vm/gas.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from .exceptions import OutOfGasError
2727

2828
# EIP-8037 state gas accounting constants
29-
COST_PER_STATE_BYTE = Uint(1174)
29+
COST_PER_STATE_BYTE = Uint(1530)
3030

3131
STATE_BYTES_PER_NEW_ACCOUNT = Uint(120)
3232
STATE_BYTES_PER_STORAGE_SET = Uint(64)

tests/amsterdam/eip7708_eth_transfer_logs/test_burn_logs.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def test_selfdestruct_to_self_same_tx(
125125
sender=sender,
126126
to=factory,
127127
value=contract_balance,
128-
gas_limit=200_000,
128+
gas_limit=300_000,
129129
expected_receipt=TransactionReceipt(logs=expected_logs),
130130
)
131131

@@ -189,7 +189,7 @@ def test_selfdestruct_to_different_address_same_tx(
189189
sender=sender,
190190
to=factory,
191191
value=contract_balance,
192-
gas_limit=200_000,
192+
gas_limit=300_000,
193193
expected_receipt=TransactionReceipt(logs=expected_logs),
194194
)
195195

@@ -507,7 +507,7 @@ def test_finalization_burn_logs(
507507
to=None,
508508
value=0,
509509
data=factory_code,
510-
gas_limit=1_000_000,
510+
gas_limit=2_000_000,
511511
expected_receipt=TransactionReceipt(
512512
logs=execution_logs + finalization_logs
513513
),

tests/amsterdam/eip7708_eth_transfer_logs/test_fork_transition.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
Alloc,
1212
Block,
1313
BlockchainTestFiller,
14+
Fork,
1415
Op,
1516
Transaction,
1617
TransactionReceipt,
@@ -35,6 +36,7 @@
3536
def test_burn_log_at_fork_transition(
3637
blockchain_test: BlockchainTestFiller,
3738
pre: Alloc,
39+
fork: Fork,
3840
same_tx: bool,
3941
to_self: bool,
4042
) -> None:
@@ -117,14 +119,21 @@ def test_burn_log_at_fork_transition(
117119
beneficiary: Account(balance=contract_balance * 3),
118120
}
119121

122+
# Same-tx CREATE+SELFDESTRUCT requires NEW_ACCOUNT state gas, which
123+
# scales with cpsb on Amsterdam. NEW_ACCOUNT is the legacy 25_000
124+
# pre-EIP-8037, so the bump is harmless on the pre-transition block.
125+
# `fork` is a TransitionFork here; resolve to the post-transition
126+
# fork (timestamp 15_001) where the larger NEW_ACCOUNT applies.
127+
post_fork = fork.fork_at(timestamp=15_001)
128+
gas_limit = 200_000 + post_fork.gas_costs().NEW_ACCOUNT
120129
blocks = [
121130
Block(
122131
timestamp=ts,
123132
txs=[
124133
Transaction(
125134
to=targets[i],
126135
sender=sender,
127-
gas_limit=200_000,
136+
gas_limit=gas_limit,
128137
expected_receipt=TransactionReceipt(logs=expected_logs[i]),
129138
)
130139
],

tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_eip7002.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,10 @@ def test_bal_7002_clean_sweep(
197197
fee=Spec7002.get_fee(0),
198198
)
199199

200-
gas_limit = 200_000
201-
if fork.is_eip_enabled(8037):
202-
gas_limit = 500_000
200+
# Predeploy sweep performs first-time SSTOREs for queue, count, and
201+
# tail slots. `sstore_state_gas()` is 0 pre-EIP-8037 and scales with
202+
# cpsb on Amsterdam, keeping this budget CPSB-agnostic.
203+
gas_limit = 200_000 + 5 * fork.sstore_state_gas()
203204

204205
# Transaction to system contract
205206
tx = Transaction(
@@ -300,9 +301,10 @@ def test_bal_7002_partial_sweep(
300301
fee = Spec7002.get_fee(0)
301302
senders = [pre.fund_eoa() for _ in range(num_requests)]
302303

303-
gas_limit = 200_000
304-
if fork.is_eip_enabled(8037):
305-
gas_limit = 500_000
304+
# Predeploy sweep performs first-time SSTOREs for queue, count, and
305+
# tail slots. `sstore_state_gas()` is 0 pre-EIP-8037 and scales with
306+
# cpsb on Amsterdam, keeping this budget CPSB-agnostic.
307+
gas_limit = 200_000 + 5 * fork.sstore_state_gas()
306308

307309
# Block 1: 20 withdrawal requests
308310
withdrawal_requests = [
@@ -481,9 +483,10 @@ def test_bal_7002_no_withdrawal_requests(
481483

482484
value = 10
483485

484-
gas_limit = 200_000
485-
if fork.is_eip_enabled(8037):
486-
gas_limit = 500_000
486+
# Predeploy sweep performs first-time SSTOREs for queue, count, and
487+
# tail slots. `sstore_state_gas()` is 0 pre-EIP-8037 and scales with
488+
# cpsb on Amsterdam, keeping this budget CPSB-agnostic.
489+
gas_limit = 200_000 + 5 * fork.sstore_state_gas()
487490

488491
tx = Transaction(
489492
sender=alice,

tests/amsterdam/eip7928_block_level_access_lists/test_block_access_lists_opcodes.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1989,10 +1989,14 @@ def test_bal_create_oog_code_deposit(
19891989
access_list=[],
19901990
)
19911991

1992+
# CREATE charges NEW_ACCOUNT (scales with cpsb under EIP-8037) plus
1993+
# base; the 500_000 buffer is enough for init code + a single SSTORE
1994+
# but well short of the 10_000-byte deposit. Including NEW_ACCOUNT
1995+
# keeps the budget CPSB-agnostic.
19921996
tx = Transaction(
19931997
sender=alice,
19941998
to=factory,
1995-
gas_limit=intrinsic_gas + 500_000, # insufficient for deposit
1999+
gas_limit=(intrinsic_gas + 500_000 + fork.gas_costs().NEW_ACCOUNT),
19962000
)
19972001

19982002
# BAL expectations:
@@ -2571,6 +2575,7 @@ def test_bal_call_revert_insufficient_funds(
25712575
def test_bal_create_selfdestruct_to_self_with_call(
25722576
pre: Alloc,
25732577
blockchain_test: BlockchainTestFiller,
2578+
fork: Fork,
25742579
) -> None:
25752580
"""
25762581
Test BAL with init code that CALLs Oracle, writes storage, then
@@ -2598,9 +2603,12 @@ def test_bal_create_selfdestruct_to_self_with_call(
25982603
# 1. Calls Oracle (which writes to its slot 0x01)
25992604
# 2. Writes 0x42 to own slot 0x01
26002605
# 3. Selfdestructs to self
2606+
#
2607+
# Forward enough gas for Oracle's first-time SSTORE
2608+
# (regular base + state gas, CPSB-agnostic).
2609+
oracle_call_gas = 100_000 + fork.sstore_state_gas()
26012610
initcode_runtime = (
2602-
# CALL(gas, Oracle, value=0, ...)
2603-
Op.CALL(100_000, oracle, 0, 0, 0, 0, 0)
2611+
Op.CALL(oracle_call_gas, oracle, 0, 0, 0, 0, 0)
26042612
+ Op.POP
26052613
# Write to own storage slot 0x01
26062614
+ Op.SSTORE(0x01, 0x42)
@@ -2661,10 +2669,18 @@ def test_bal_create_selfdestruct_to_self_with_call(
26612669
opcode=Op.CREATE2,
26622670
)
26632671

2672+
# CREATE2 + 3 first-time SSTOREs (factory slot 0, oracle slot 1,
2673+
# ephemeral slot 1 in the created contract). NEW_ACCOUNT and
2674+
# `sstore_state_gas()` are 0 pre-EIP-8037 and scale with cpsb on
2675+
# Amsterdam, keeping this budget CPSB-agnostic.
2676+
gas_limit = (
2677+
1_000_000 + fork.gas_costs().NEW_ACCOUNT + 3 * fork.sstore_state_gas()
2678+
)
2679+
26642680
tx = Transaction(
26652681
sender=alice,
26662682
to=factory,
2667-
gas_limit=1_000_000,
2683+
gas_limit=gas_limit,
26682684
)
26692685

26702686
block = Block(

tests/amsterdam/eip8037_state_creation_gas_cost_increase/spec.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class Spec:
4141

4242
# TODO: replace with dynamic cost_per_state_byte(gas_limit) once
4343
# non-default block gas limits are supported in the test framework.
44-
COST_PER_STATE_BYTE = 1174 # at 100M–120M gas limit
44+
COST_PER_STATE_BYTE = 1530 # at 150M reference block gas limit
4545

4646
# State bytes per operation
4747
STATE_BYTES_PER_NEW_ACCOUNT = 120

tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_call.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1606,14 +1606,17 @@ def test_child_failure_refunds_state_gas_to_reservoir_not_gas_left(
16061606
),
16071607
)
16081608

1609-
# Empirical per-tx cumulative. Pinning this catches a mutation
1610-
# that correctly restores the reservoir but also double-refunds
1611-
# to regular gas (or otherwise leaks extra gas to the sender),
1612-
# which the storage probe alone cannot discriminate.
1613-
expected_cumulative = {
1614-
Op.CALL: 111_399,
1615-
Op.DELEGATECALL: 111_393,
1609+
# Empirical per-tx cumulative, decomposed into a CPSB-independent
1610+
# regular base plus the grandchild's surviving SSTORE state gas.
1611+
# Pinning this catches a mutation that correctly restores the
1612+
# reservoir but also double-refunds to regular gas (or otherwise
1613+
# leaks extra gas to the sender), which the storage probe alone
1614+
# cannot discriminate.
1615+
regular_base = {
1616+
Op.CALL: 36_263,
1617+
Op.DELEGATECALL: 36_257,
16161618
}[call_opcode]
1619+
expected_cumulative = regular_base + sstore_state_gas
16171620

16181621
tx = Transaction(
16191622
to=parent,

tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ def test_create2_child_spill_not_double_charged(
183183

184184
tx = Transaction(
185185
to=factory,
186-
gas_limit=700_000,
186+
gas_limit=1_000_000,
187187
sender=pre.fund_eoa(),
188188
)
189189

@@ -2425,6 +2425,7 @@ def test_inner_create_fail_refunds_in_creation_tx(
24252425
def test_create_collision_burned_gas_counted_in_block_regular(
24262426
blockchain_test: BlockchainTestFiller,
24272427
pre: Alloc,
2428+
fork: Fork,
24282429
create_opcode: Op,
24292430
) -> None:
24302431
"""
@@ -2453,7 +2454,7 @@ def test_create_collision_burned_gas_counted_in_block_regular(
24532454
pre.deploy_contract(code=Op.STOP, address=collision_target)
24542455

24552456
# Fixed-size budget so the forwarded create_message_gas is
2456-
# deterministic and the empirical baseline below is reproducible.
2457+
# deterministic and the baseline below is reproducible.
24572458
gas_limit = 250_000
24582459

24592460
tx = Transaction(
@@ -2462,11 +2463,14 @@ def test_create_collision_burned_gas_counted_in_block_regular(
24622463
sender=pre.fund_eoa(),
24632464
)
24642465

2465-
# Empirical baseline: block_state_gas is zero for this tx, so
2466-
# header.gas_used equals the regular-gas total. A mutation that
2467-
# drops the burned create_message_gas from regular accounting
2468-
# would reduce this value.
2469-
baseline_gas_used = 107887
2466+
# CPSB-agnostic baseline: block_state_gas is zero for this tx, so
2467+
# header.gas_used equals the regular-gas total. The forwarded
2468+
# create_message_gas is `(gas_limit - NEW_ACCOUNT) * 63 // 64`,
2469+
# plus a CPSB-independent constant covering intrinsic + factory
2470+
# opcodes. A mutation that drops the burned create_message_gas
2471+
# from regular accounting would reduce this value.
2472+
new_account = fork.gas_costs().NEW_ACCOUNT
2473+
baseline_gas_used = (gas_limit - new_account) * 63 // 64 + 472
24702474

24712475
blockchain_test(
24722476
pre=pre,

0 commit comments

Comments
 (0)