Skip to content

Commit 897ca4b

Browse files
committed
Merge eips/amsterdam/eip-8037 into devnets/bal/4
# Conflicts: # src/ethereum/forks/amsterdam/fork.py # src/ethereum/forks/amsterdam/vm/__init__.py # src/ethereum/forks/amsterdam/vm/instructions/system.py
2 parents ecad2d4 + f83131f commit 897ca4b

708 files changed

Lines changed: 19618 additions & 1438 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/contracts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def deploy_deterministic_factory_contract(
7878
fund_tx = Transaction(
7979
to=deploy_tx_sender,
8080
value=fund_amount,
81+
gas_limit=200_000,
8182
gas_price=gas_price,
8283
sender=seed_key,
8384
)

packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/execute_recover.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def test_recover_funds(
2424
del index
2525

2626
remaining_balance = eth_rpc.get_balance(eoa)
27-
refund_gas_limit = 21_000
27+
refund_gas_limit = 200_000
2828
tx_cost = refund_gas_limit * gas_price
2929
if remaining_balance < tx_cost:
3030
pytest.skip(

packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/pre_alloc.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ def __init__(
257257
address_stubs: AddressStubs | None = None,
258258
block_number: int = 0,
259259
timestamp: int = 0,
260+
funding_gas_limit: int = 200_000,
260261
**kwargs: Any,
261262
) -> None:
262263
"""Initialize the pre-alloc with the given parameters."""
@@ -269,6 +270,7 @@ def __init__(
269270
self._address_stubs = address_stubs or AddressStubs(root={})
270271
self._block_number = block_number
271272
self._timestamp = timestamp
273+
self._funding_gas_limit = funding_gas_limit
272274

273275
def code_pre_processor(self, code: Bytecode) -> Bytecode:
274276
"""Pre-processes the code before setting it."""
@@ -645,6 +647,7 @@ def _fund_eoa(
645647
target=label,
646648
to=eoa,
647649
value=amount,
650+
gas_limit=self._funding_gas_limit,
648651
)
649652

650653
if fund_tx is not None:
@@ -862,6 +865,7 @@ def _resolve_fund_addresses(self) -> None:
862865
target=d.address.label,
863866
to=d.address,
864867
value=d.amount - current_balance,
868+
gas_limit=self._funding_gas_limit,
865869
)
866870
new_balance = d.amount
867871
else:
@@ -876,6 +880,7 @@ def _resolve_fund_addresses(self) -> None:
876880
target=d.address.label,
877881
to=d.address,
878882
value=d.amount,
883+
gas_limit=self._funding_gas_limit,
879884
)
880885
new_balance = current_balance + d.amount
881886

@@ -985,6 +990,7 @@ def pre(
985990
max_fee_per_gas: int,
986991
max_priority_fee_per_gas: int,
987992
dry_run: bool,
993+
sender_fund_refund_gas_limit: int,
988994
request: pytest.FixtureRequest,
989995
) -> Generator[Alloc, None, None]:
990996
"""Return default pre allocation for all tests (Empty alloc)."""
@@ -1009,6 +1015,7 @@ def pre(
10091015
chain_id=chain_config.chain_id,
10101016
node_id=request.node.nodeid,
10111017
address_stubs=address_stubs,
1018+
funding_gas_limit=sender_fund_refund_gas_limit,
10121019
)
10131020

10141021
# Yield the pre-alloc for usage during the test
@@ -1034,7 +1041,7 @@ def pre(
10341041
# Build refund transactions
10351042
refund_txs: List[Transaction] = []
10361043
skipped_refunds = 0
1037-
refund_gas_limit = 21_000
1044+
refund_gas_limit = sender_fund_refund_gas_limit
10381045
tx_cost = refund_gas_limit * max_fee_per_gas
10391046
for idx, eoa in enumerate(funded_eoas):
10401047
account = eth_rpc.get_account(eoa, skip_code=True)

packages/testing/src/execution_testing/cli/pytest_commands/plugins/execute/sender.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def pytest_addoption(parser: pytest.Parser) -> None:
5656
action="store",
5757
dest="sender_fund_refund_gas_limit",
5858
type=Wei,
59-
default=21_000,
59+
default=200_000,
6060
help=(
6161
"Gas limit set for the funding transactions of each worker's sender key." # noqa: E501
6262
),

packages/testing/src/execution_testing/cli/pytest_commands/plugins/filler/filler.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,44 @@ def pytest_html_results_table_row(report: Any, cells: Any) -> None:
11671167
del cells[-1] # Remove the "Links" column
11681168

11691169

1170+
@pytest.hookimpl(hookwrapper=True)
1171+
def pytest_runtest_setup(item: Any) -> Generator[None, None, None]:
1172+
"""
1173+
Snapshot parametrize values before fixture setup to detect unintended
1174+
mutations of shared pytest parameter objects across fixture format runs.
1175+
"""
1176+
if hasattr(item, "callspec"):
1177+
item._param_repr_snapshot = {
1178+
key: repr(value) for key, value in item.callspec.params.items()
1179+
}
1180+
yield
1181+
1182+
1183+
def pytest_runtest_teardown(item: Any) -> None:
1184+
"""
1185+
Compare parametrize values after test teardown to the pre-setup snapshot.
1186+
1187+
Warn if any fixture mutated shared parameter objects — these mutations
1188+
persist across fixture format runs and can cause subtle bugs (e.g.
1189+
block hash mismatches between blockchain_test and blockchain_engine_test).
1190+
"""
1191+
snapshot = getattr(item, "_param_repr_snapshot", None)
1192+
if snapshot is None:
1193+
return
1194+
for key, original_repr in snapshot.items():
1195+
current_repr = repr(item.callspec.params[key])
1196+
if current_repr != original_repr:
1197+
warnings.warn(
1198+
f"Shared pytest parameter '{key}' was mutated during "
1199+
f"test '{item.nodeid}'. Mutations on parametrize values "
1200+
f"persist across fixture format runs and can cause "
1201+
f"divergent test results. Avoid mutating these objects "
1202+
f"in fixtures; compute derived values locally instead.",
1203+
stacklevel=1,
1204+
)
1205+
del item._param_repr_snapshot
1206+
1207+
11701208
@pytest.hookimpl(hookwrapper=True)
11711209
def pytest_runtest_makereport(
11721210
item: Any, call: Any

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def type_4_default_transaction(sender: EOA, pre: Alloc) -> Transaction:
106106
sender=sender,
107107
max_fee_per_gas=10**10,
108108
max_priority_fee_per_gas=10**9,
109-
gas_limit=150_000,
109+
gas_limit=500_000,
110110
data=b"\x00" * 200,
111111
access_list=[
112112
AccessList(address=0x4567, storage_keys=[1000, 2000, 3000]),

packages/testing/src/execution_testing/client_clis/cli_types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ class TransactionTraces(CamelModel):
152152
traces: List[TraceLine]
153153
output: str | None = None
154154
gas_used: HexNumber | None = None
155+
error: str | None = None
155156

156157
@classmethod
157158
def from_file(cls, trace_file_path: Path) -> Self:

packages/testing/src/execution_testing/forks/base_fork.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,51 @@ def opcode_gas_map(
493493
"""
494494
pass
495495

496+
@classmethod
497+
@abstractmethod
498+
def opcode_state_map(
499+
cls,
500+
) -> Dict[OpcodeBase, int | Callable[[OpcodeBase], int]]:
501+
"""
502+
Return a mapping of opcodes to their state gas costs.
503+
504+
Each entry is either:
505+
- Constants (int): Multiplier of the cost_per_state_byte
506+
- Callables: Functions that take the opcode instance with metadata and
507+
return the full state gas cost
508+
"""
509+
pass
510+
511+
@classmethod
512+
@abstractmethod
513+
def opcode_refund_map(
514+
cls,
515+
) -> Dict[OpcodeBase, int | Callable[[OpcodeBase], int]]:
516+
"""
517+
Return a mapping of opcodes to their gas refunds.
518+
519+
Each entry is either:
520+
- Constants (int): Direct gas refund values
521+
- Callables: Functions that take the opcode instance with metadata and
522+
return gas refund
523+
"""
524+
pass
525+
526+
@classmethod
527+
@abstractmethod
528+
def opcode_state_refund_map(
529+
cls,
530+
) -> Dict[OpcodeBase, int | Callable[[OpcodeBase], int]]:
531+
"""
532+
Return a mapping of opcodes to their state refunds.
533+
534+
Each entry is either:
535+
- Constants (int): Multiplier of the cost_per_state_byte
536+
- Callables: Functions that take the opcode instance with metadata and
537+
return the state refund
538+
"""
539+
pass
540+
496541
# Gas calculation helpers
497542
@classmethod
498543
@abstractmethod
@@ -620,6 +665,14 @@ def base_fee_change_calculator(cls) -> BaseFeeChangeCalculator:
620665
"""
621666
pass
622667

668+
@classmethod
669+
@abstractmethod
670+
def cost_per_state_byte(cls) -> int:
671+
"""
672+
Calculate the state gas cost per byte based on `cls._env_gas_limit`.
673+
"""
674+
pass
675+
623676
# Fee helpers
624677
@classmethod
625678
@abstractmethod
@@ -662,6 +715,16 @@ def transaction_intrinsic_cost_calculator(
662715
"""
663716
pass
664717

718+
@classmethod
719+
def transaction_intrinsic_state_gas(
720+
cls,
721+
*,
722+
contract_creation: bool = False, # noqa: ARG003
723+
authorization_count: int = 0, # noqa: ARG003
724+
) -> int:
725+
"""Return intrinsic state gas (zero pre-Amsterdam)."""
726+
return 0
727+
665728
@classmethod
666729
@abstractmethod
667730
def blob_gas_price_calculator(cls) -> BlobGasPriceCalculator:
@@ -797,6 +860,24 @@ def transaction_gas_limit_cap(cls) -> int | None:
797860
"""
798861
pass
799862

863+
@classmethod
864+
@abstractmethod
865+
def sstore_state_gas(cls) -> int:
866+
"""Return state gas for a zero-to-nonzero SSTORE."""
867+
pass
868+
869+
@classmethod
870+
@abstractmethod
871+
def code_deposit_state_gas(cls, *, code_size: int) -> int:
872+
"""Return state gas for code deposit of the given size."""
873+
pass
874+
875+
@classmethod
876+
@abstractmethod
877+
def create_state_gas(cls, *, code_size: int = 0) -> int:
878+
"""Return total state gas for CREATE."""
879+
pass
880+
800881
@classmethod
801882
@abstractmethod
802883
def block_rlp_size_limit(cls) -> int | None:

0 commit comments

Comments
 (0)