Skip to content

Commit 2548b06

Browse files
committed
feat(spec): update EIP-8037 state byte sizes (NEW_ACCOUNT 112->120, STORAGE_SET 32->64)
1 parent eb80b43 commit 2548b06

6 files changed

Lines changed: 30 additions & 26 deletions

File tree

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

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def cost_per_state_byte(cls) -> int:
3333
@classmethod
3434
def sstore_state_gas(cls) -> int:
3535
"""Return state gas for a zero-to-nonzero SSTORE (EIP-8037)."""
36-
STATE_BYTES_PER_STORAGE_SET = 32 # noqa: N806
36+
STATE_BYTES_PER_STORAGE_SET = 64 # noqa: N806
3737
return STATE_BYTES_PER_STORAGE_SET * cls.cost_per_state_byte()
3838

3939
@classmethod
@@ -58,8 +58,8 @@ def gas_costs(cls) -> GasCosts:
5858
cpsb = cls.cost_per_state_byte()
5959
parent = super(EIP8037, cls).gas_costs()
6060
# EIP-8037 state byte sizes (EELS amsterdam/vm/gas.py)
61-
STATE_BYTES_PER_STORAGE_SET = 32 # noqa: N806
62-
STATE_BYTES_PER_NEW_ACCOUNT = 112 # noqa: N806
61+
STATE_BYTES_PER_STORAGE_SET = 64 # noqa: N806
62+
STATE_BYTES_PER_NEW_ACCOUNT = 120 # noqa: N806
6363
STATE_BYTES_PER_AUTH_BASE = 23 # noqa: N806
6464
# EIP-8037 regular gas base costs
6565
PER_AUTH_BASE_COST = 7_500 # noqa: N806
@@ -258,7 +258,7 @@ def transaction_intrinsic_state_gas(
258258
- Auth: (NEW_ACCOUNT + AUTH_BASE) * cpsb
259259
"""
260260
cpsb = cls.cost_per_state_byte()
261-
STATE_BYTES_PER_NEW_ACCOUNT = 112 # noqa: N806
261+
STATE_BYTES_PER_NEW_ACCOUNT = 120 # noqa: N806
262262
STATE_BYTES_PER_AUTH_BASE = 23 # noqa: N806
263263
state_gas = 0
264264
if contract_creation:
@@ -278,7 +278,7 @@ def _calculate_sstore_gas(
278278
Calculate updated SSTORE gas cost.
279279
280280
For 0->nonzero: regular (UPDATE - COLD_SLOAD) + state
281-
(32 * cpsb).
281+
(STATE_BYTES_PER_STORAGE_SET * cpsb).
282282
For nonzero->different nonzero: regular
283283
(UPDATE - COLD_SLOAD).
284284
Otherwise: WARM_SLOAD.
@@ -324,7 +324,7 @@ def _calculate_sstore_state_gas(
324324
and current_value != new_value
325325
and original_value == 0
326326
):
327-
return 32 * cpsb
327+
return 64 * cpsb
328328
return 0
329329

330330
@classmethod
@@ -368,9 +368,9 @@ def _calculate_sstore_state_refund(
368368
"""
369369
Calculate SSTORE state gas refund.
370370
371-
Return the state-gas portion (`32 * cpsb`) when a slot that
372-
was originally empty is restored back to zero within the
373-
transaction; otherwise return 0.
371+
Return the state-gas portion (`STATE_BYTES_PER_STORAGE_SET *
372+
cpsb`) when a slot that was originally empty is restored back
373+
to zero within the transaction; otherwise return 0.
374374
"""
375375
del gas_costs
376376
metadata = opcode.metadata
@@ -384,7 +384,7 @@ def _calculate_sstore_state_refund(
384384
if current_value != new_value:
385385
if original_value == new_value:
386386
if original_value == 0:
387-
return 32 * cpsb
387+
return 64 * cpsb
388388
return 0
389389

390390
@classmethod
@@ -394,8 +394,9 @@ def _calculate_selfdestruct_state_refund(
394394
"""
395395
Calculate SELFDESTRUCT state gas refund.
396396
397-
Account creation: 112 × cost_per_state_byte
398-
Created storage slots: 32 × cost_per_state_byte per non-zero slot
397+
Account creation: STATE_BYTES_PER_NEW_ACCOUNT × cost_per_state_byte
398+
Created storage slots: STATE_BYTES_PER_STORAGE_SET ×
399+
cost_per_state_byte per non-zero slot
399400
Code deposit: len(code) × cost_per_state_byte
400401
"""
401402
del gas_costs
@@ -411,9 +412,9 @@ def _calculate_selfdestruct_state_refund(
411412
]
412413
state_refund = 0
413414
if self_destructed_account:
414-
state_refund = 112 * cpsb
415+
state_refund = 120 * cpsb
415416
state_refund += (
416-
32 * cpsb * self_destructed_account_storage_slot_count
417+
64 * cpsb * self_destructed_account_storage_slot_count
417418
)
418419
state_refund += cpsb * self_destructed_account_code_deposit
419420
return state_refund

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
# EIP-8037 state gas accounting constants
2929
COST_PER_STATE_BYTE = Uint(1174)
3030

31-
STATE_BYTES_PER_NEW_ACCOUNT = Uint(112)
32-
STATE_BYTES_PER_STORAGE_SET = Uint(32)
31+
STATE_BYTES_PER_NEW_ACCOUNT = Uint(120)
32+
STATE_BYTES_PER_STORAGE_SET = Uint(64)
3333
STATE_BYTES_PER_AUTH_BASE = Uint(23)
3434

3535
PER_AUTH_BASE_COST = Uint(7500)

tests/amsterdam/eip8037_state_creation_gas_cost_increase/spec.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ class Spec:
4444
COST_PER_STATE_BYTE = 1174 # at 100M–120M gas limit
4545

4646
# State bytes per operation
47-
STATE_BYTES_PER_NEW_ACCOUNT = 112
48-
STATE_BYTES_PER_STORAGE_SET = 32
47+
STATE_BYTES_PER_NEW_ACCOUNT = 120
48+
STATE_BYTES_PER_STORAGE_SET = 64
4949
STATE_BYTES_PER_AUTH_BASE = 23
5050

5151
# Regular gas constants (EIP-8037 replaces old combined costs)

tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_call.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def test_delegatecall_child_spill_not_double_charged(
121121

122122
tx = Transaction(
123123
to=caller,
124-
gas_limit=500_000,
124+
gas_limit=700_000,
125125
sender=pre.fund_eoa(),
126126
)
127127

@@ -1611,8 +1611,8 @@ def test_child_failure_refunds_state_gas_to_reservoir_not_gas_left(
16111611
# to regular gas (or otherwise leaks extra gas to the sender),
16121612
# which the storage probe alone cannot discriminate.
16131613
expected_cumulative = {
1614-
Op.CALL: 73_831,
1615-
Op.DELEGATECALL: 73_825,
1614+
Op.CALL: 111_399,
1615+
Op.DELEGATECALL: 111_393,
16161616
}[call_opcode]
16171617

16181618
tx = Transaction(

tests/amsterdam/eip8037_state_creation_gas_cost_increase/test_state_gas_create.py

Lines changed: 2 additions & 2 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=500_000,
186+
gas_limit=700_000,
187187
sender=pre.fund_eoa(),
188188
)
189189

@@ -2466,7 +2466,7 @@ def test_create_collision_burned_gas_counted_in_block_regular(
24662466
# header.gas_used equals the regular-gas total. A mutation that
24672467
# drops the burned create_message_gas from regular accounting
24682468
# would reduce this value.
2469-
baseline_gas_used = 117132
2469+
baseline_gas_used = 107887
24702470

24712471
blockchain_test(
24722472
pre=pre,

tests/common/precompile_fixtures.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,12 @@ def tx_gas_limit(fork: Fork, input_data: bytes, precompile_gas: int) -> int:
183183
fork.transaction_intrinsic_cost_calculator()
184184
)
185185
memory_expansion_gas_calculator = fork.memory_expansion_gas_calculator()
186-
extra_gas = 100_000
187-
if fork.is_eip_enabled(8037):
188-
extra_gas = 200_000
186+
# `call_contract_code` performs up to 3 SSTOREs (succeeds-flag,
187+
# output-length, output-hash) per call. Pre-EIP-8037 each SSTORE
188+
# fits comfortably in the 100_000 budget; under EIP-8037 each
189+
# SSTORE additionally consumes `fork.sstore_state_gas()` of state
190+
# gas, so size the budget against the actual per-fork cost.
191+
extra_gas = 100_000 + 3 * fork.sstore_state_gas()
189192
return (
190193
extra_gas
191194
+ intrinsic_gas_cost_calculator(calldata=input_data)

0 commit comments

Comments
 (0)