Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
2f56dfc
feat(test-specs): Allow implicit gas-limit
marioevz May 29, 2026
917925c
feat(tests): Remove gas-limit from some tests
marioevz May 29, 2026
8bf5bde
fix(tests): Fix Osaka, Paris, Prague
marioevz Jun 1, 2026
acdb5f7
feat(test-forks): Fix EIP-7883 not being in Osaka
marioevz Jun 1, 2026
05843a0
feat(test-fill): Bump default pre.fund_eoa amount to fix deposit tests
marioevz Jun 1, 2026
007554e
fix(tests): Byzantium pre-compile fixtures
marioevz Jun 1, 2026
9e1886f
fix(tests): Typed transaction fixture
marioevz Jun 1, 2026
87e73c0
fix(tests): Typed transaction fixture (8037)
marioevz Jun 1, 2026
0a3644f
fix(tests): Fix constantinople, frontier, homestead, istanbul
marioevz Jun 1, 2026
9c07e38
fix(tests): EIP-7708 and EIP-8024
marioevz Jun 2, 2026
76bff2d
fix(tests): Ported static
marioevz Jun 2, 2026
5d397f7
feat(test-execute): Implement implicit gas limit
marioevz Jun 3, 2026
1a9d3ca
fix(tests): Fix 7708+7843
marioevz Jun 4, 2026
c03111c
fix(tests): Fix 7928
marioevz Jun 4, 2026
090caa6
fix(test-types): Fix `Transaction.set_gas_limit`
marioevz Jun 4, 2026
cef5cf2
fix(test-specs): Fix typing
marioevz Jun 4, 2026
e839f05
fix(tests): Fix Shanghai typing
marioevz Jun 4, 2026
b2e26e4
fix(tests): Fix benchmark typing
marioevz Jun 4, 2026
db6ac80
fix(tests): Fix EIP-1153
marioevz Jun 5, 2026
6aaafb1
fix(test-fixtures): lint
marioevz Jun 5, 2026
75c30f2
fix(tests): Fix EIP-4844
marioevz Jun 5, 2026
e224186
fix(tests): Fix EIP-5656
marioevz Jun 5, 2026
18151d6
fix(tests): Fix EIP-6780
marioevz Jun 5, 2026
9982e0d
fix(tests): Fix EIP-7516
marioevz Jun 5, 2026
ff3b69c
fix(tests): Fix Frontier (except test_scenarios.py)
marioevz Jun 5, 2026
268e550
fix(tests): Fix Blake2 Delegate call
marioevz Jun 5, 2026
d0fa63b
fix(tests): Refactor/improve Blake2 tests
marioevz Jun 5, 2026
8137762
fix(tests): Fix Osaka
marioevz Jun 5, 2026
b622ddc
fix(tests): Fix Prague
marioevz Jun 5, 2026
099f588
feat(test-forks): Introduce `state_gas_reservoir_enabled`
marioevz Jun 5, 2026
19d0591
feat(test-forks): Introduce `state_gas_reservoir_enabled`
marioevz Jun 5, 2026
99fac84
fix(test-types): Fix `set_gas_limit` logic
marioevz Jun 5, 2026
a0d16e4
fix(tests): Shanghai: EIP-3860
marioevz Jun 5, 2026
1687cd9
refactor(tests): Amsterdam: EIP-8037 (use `state_gas_reservoir`)
marioevz Jun 5, 2026
9feb565
fix(tests): Frontier: Rollback test_call_and_callcode_gas_calculation.py
marioevz Jun 10, 2026
a655864
refactor(test-types): Remove duplicated method
marioevz Jun 11, 2026
10939b8
refactor(test-types): Remove `None` from gas_limit type
marioevz Jun 11, 2026
92ffb3d
fix(test-types): Typo
marioevz Jun 11, 2026
7540d32
refactor(test-specs): Copy transactions for state/blockchain filling
marioevz Jun 11, 2026
1b5659c
refactor(test-types): Raise when available gas is zero
marioevz Jun 11, 2026
8e8f9dd
chore(test-types): Verbose descriptions
marioevz Jun 11, 2026
f82f657
fix(test-types): Raise when state gas reservoir is requested but not …
marioevz Jun 11, 2026
652c815
chore(tests): fix failing ci and revert some implicit gas limit removals
spencer-tb Jun 12, 2026
0d8908c
fix(test-types): harden implicit gas-limit resolution
spencer-tb Jun 12, 2026
e26c9c5
feat(test-types): add unit tests for implicit gas-limit resolution
spencer-tb Jun 12, 2026
a2e13fb
fix(tests): Fix requests tests using gas_limit=None
marioevz Jun 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@

from execution_testing.base_types import Account
from execution_testing.base_types import Alloc as BaseAlloc
from execution_testing.base_types.base_types import HexNumber
from execution_testing.execution import BaseExecute
from execution_testing.forks import Fork, TransitionFork
from execution_testing.logging import get_logger
from execution_testing.rpc import EngineRPC, EthRPC
from execution_testing.specs import BaseTest
from execution_testing.test_types import (
Environment,
EnvironmentDefaults,
)

Expand Down Expand Up @@ -271,6 +273,17 @@ def gas_limit_accumulator() -> Generator[GasInfoAccumulator, None, None]:
logger.info(f"Total minimum balance: {total_min_eth:.18f}")


@pytest.fixture(scope="session")
def env_gas_limit(eth_rpc: EthRPC) -> HexNumber:
"""
Return the environment gas limit derived from the head block before
tests start running.
"""
head_block = eth_rpc.get_block_by_number()
assert head_block is not None, "Unable to obtain head block from RPC"
return HexNumber(head_block["gasLimit"])


def base_test_parametrizer(cls: Type[BaseTest]) -> Any:
"""
Generate pytest.fixture for a given BaseTest subclass.
Expand All @@ -288,7 +301,7 @@ def base_test_parametrizer(cls: Type[BaseTest]) -> Any:
)
def base_test_parametrizer_func(
request: Any,
fork: Fork | TransitionFork,
fork: Fork,
pre: Alloc,
eth_rpc: EthRPC,
engine_rpc: EngineRPC | None,
Expand All @@ -302,6 +315,7 @@ def base_test_parametrizer_func(
max_fee_per_blob_gas: int,
max_gas_limit_per_test: int | None,
gas_limit_accumulator: GasInfoAccumulator,
env_gas_limit: HexNumber,
is_tx_gas_heavy_test: bool,
is_exception_test: bool,
) -> Type[BaseTest]:
Expand Down Expand Up @@ -348,24 +362,23 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
if p not in kwargs
}

# TODO: get values from network
timestamp = 0
block_number = 0

request.node.config.sender_address = str(pre._sender)

super(BaseTestWrapper, self).__init__(*args, **kwargs)
execute = self.execute(execute_format=execute_format)

# get balances of required sender accounts
required_balances = execute.get_required_sender_balances(
execute.prepare_transactions(
env=Environment(gas_limit=env_gas_limit),
gas_price=gas_price,
max_fee_per_gas=max_fee_per_gas,
max_priority_fee_per_gas=max_priority_fee_per_gas,
max_fee_per_blob_gas=max_fee_per_blob_gas,
fork=fork.fork_at(
block_number=block_number, timestamp=timestamp
),
fork=fork,
)

# get balances of required sender accounts
required_balances = execute.get_required_sender_balances(
fork=fork,
)

pre.resolve_deferred_checks()
Expand Down Expand Up @@ -432,9 +445,7 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
)

execute_result = execute.execute(
fork=fork.fork_at(
block_number=block_number, timestamp=timestamp
),
fork=fork,
eth_rpc=eth_rpc,
engine_rpc=engine_rpc,
request=request,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,7 @@ def minimum_balance_for_pending_transactions(
max_priority_fee_per_gas=max_priority_fee_per_gas,
max_fee_per_blob_gas=max_fee_per_blob_gas,
)
assert "gas_limit" in tx.model_fields_set, "tx gas limit not set"
gas_consumption += tx.gas_limit
minimum_balance += tx.signer_minimum_balance(fork=fork)
return minimum_balance + gas_consumption * gas_price, gas_consumption
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def pytest_addoption(parser: pytest.Parser) -> None:
class Alloc(SharedAlloc):
"""Allocation of accounts in the state, pre and post test execution."""

_eoa_fund_amount_default: int = PrivateAttr(10**21)
_eoa_fund_amount_default: int = PrivateAttr(10**27)
_account_salt: Dict[Hash, int] = PrivateAttr(default_factory=dict)
_stub_accounts: Dict[str, Account] = PrivateAttr(default_factory=dict)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ def count_keys_in_fixture(file_path: Path) -> int: # noqa: D103
@pytest.mark.valid_until("Shanghai")
def test_paris_one(state_test) -> None:
state_test(env=Environment(),
pre={TestAddress: Account(balance=1_000_000)}, post={}, tx=Transaction())
pre={TestAddress: Account(balance=1_000_000)}, post={}, tx=Transaction(gas_limit=0x5208))

@pytest.mark.valid_from("Paris")
@pytest.mark.valid_until("Shanghai")
def test_paris_two(state_test) -> None:
state_test(env=Environment(),
pre={TestAddress: Account(balance=1_000_000)}, post={}, tx=Transaction())
pre={TestAddress: Account(balance=1_000_000)}, post={}, tx=Transaction(gas_limit=0x5208))
"""
)
test_count_paris = 4
Expand All @@ -79,14 +79,14 @@ def test_paris_two(state_test) -> None:
@pytest.mark.valid_until("Shanghai")
def test_shanghai_one(state_test) -> None:
state_test(env=Environment(),
pre={TestAddress: Account(balance=1_000_000)}, post={}, tx=Transaction())
pre={TestAddress: Account(balance=1_000_000)}, post={}, tx=Transaction(gas_limit=0x5208))

@pytest.mark.parametrize("x", [1, 2, 3])
@pytest.mark.valid_from("Paris")
@pytest.mark.valid_until("Shanghai")
def test_shanghai_two(state_test, x) -> None:
state_test(env=Environment(),
pre={TestAddress: Account(balance=1_000_000)}, post={}, tx=Transaction())
pre={TestAddress: Account(balance=1_000_000)}, post={}, tx=Transaction(gas_limit=0x5208))
"""
)

Expand Down Expand Up @@ -988,7 +988,7 @@ def test_benchmark_one(state_test) -> None:
env=Environment(),
pre={TestAddress: Account(balance=1_000_000)},
post={},
tx=Transaction(),
tx=Transaction(gas_limit=0x5208),
)
"""
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def test_verify_sync_default(blockchain_test) -> None:
blockchain_test(
pre={TestAddress: TEST_ADDRESS},
post={},
blocks=[Block(txs=[Transaction()])]
blocks=[Block(txs=[Transaction(gas_limit=0x5208)])]
)


Expand All @@ -33,7 +33,7 @@ def test_verify_sync_with_marker(blockchain_test) -> None:
blockchain_test(
pre={TestAddress: TEST_ADDRESS},
post={},
blocks=[Block(txs=[Transaction()])]
blocks=[Block(txs=[Transaction(gas_limit=0x5208)])]
)

@pytest.mark.valid_at("Cancun")
Expand All @@ -52,7 +52,7 @@ def test_verify_sync_with_param_marks(blockchain_test, has_exception) -> None:
post={},
blocks=[
Block(
txs=[Transaction()],
txs=[Transaction(gas_limit=0x5208)],
rlp_modifier=Header(gas_limit=0) if has_exception else None,
exception=BlockException.INCORRECT_BLOCK_FORMAT if has_exception else None,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ def type_0_default_transaction(sender: EOA) -> Transaction:
ty=0,
sender=sender,
gas_price=10**9,
gas_limit=100_000,
data=b"\x00" * 100,
protected=True,
)
Expand All @@ -38,7 +37,6 @@ def type_1_default_transaction(sender: EOA) -> Transaction:
ty=1,
sender=sender,
gas_price=10**9,
gas_limit=100_000,
data=b"\x00" * 100,
access_list=[
AccessList(address=0x1234, storage_keys=[0, 1, 2]),
Expand All @@ -56,7 +54,6 @@ def type_2_default_transaction(sender: EOA) -> Transaction:
sender=sender,
max_fee_per_gas=10**10,
max_priority_fee_per_gas=10**9,
gas_limit=100_000,
data=b"\x00" * 200,
access_list=[
AccessList(address=0x2468, storage_keys=[10, 20, 30]),
Expand All @@ -74,7 +71,6 @@ def type_3_default_transaction(sender: EOA) -> Transaction:
max_fee_per_gas=10**10,
max_priority_fee_per_gas=10**9,
max_fee_per_blob_gas=10**9,
gas_limit=100_000,
data=b"\x00" * 150,
access_list=[
AccessList(address=0x3690, storage_keys=[100, 200]),
Expand Down Expand Up @@ -106,7 +102,6 @@ def type_4_default_transaction(sender: EOA, pre: Alloc) -> Transaction:
sender=sender,
max_fee_per_gas=10**10,
max_priority_fee_per_gas=10**9,
gas_limit=500_000,
data=b"\x00" * 200,
access_list=[
AccessList(address=0x4567, storage_keys=[1000, 2000, 3000]),
Expand Down
21 changes: 18 additions & 3 deletions packages/testing/src/execution_testing/execution/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from execution_testing.base_types import Address, CamelModel
from execution_testing.forks import Fork
from execution_testing.rpc import EngineRPC, EthRPC
from execution_testing.test_types import Environment


class ExecuteResult(CamelModel):
Expand Down Expand Up @@ -42,18 +43,32 @@ def __pydantic_init_subclass__(cls, **kwargs: Any) -> None:
# Register the new execute format
BaseExecute.formats[cls.format_name] = cls

def get_required_sender_balances(
def prepare_transactions(
self,
*,
env: Environment,
gas_price: int,
max_fee_per_gas: int,
max_priority_fee_per_gas: int,
max_fee_per_blob_gas: int,
fork: Fork,
) -> Dict[Address, int]:
"""Get the required sender balances."""
) -> None:
"""Prepare transactions by setting their final gas properties."""
del env
del gas_price, max_fee_per_gas, max_priority_fee_per_gas
del max_fee_per_blob_gas, fork
raise Exception(
"Method `prepare_transactions` not implemented for "
f"{self.format_name}"
)

def get_required_sender_balances(
self,
*,
fork: Fork,
) -> Dict[Address, int]:
"""Get the required sender balances."""
del fork
raise Exception(
"Method `get_required_sender_balances` not implemented for "
f"{self.format_name}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
)
from execution_testing.rpc.rpc_types import GetBlobsResponse
from execution_testing.test_types import (
Environment,
NetworkWrappedTransaction,
Transaction,
)
Expand Down Expand Up @@ -149,26 +150,50 @@ class BlobTransaction(BaseExecute):
nonexisting_blob_hashes: List[Hash] | None = None
get_blobs_version: int | None = None

def get_required_sender_balances(
def prepare_transactions(
self,
*,
env: Environment,
gas_price: int,
max_fee_per_gas: int,
max_priority_fee_per_gas: int,
max_fee_per_blob_gas: int,
fork: Fork,
) -> Dict[Address, int]:
"""Get the required sender balances."""
balances: Dict[Address, int] = {}
) -> None:
"""Prepare transactions by setting their final gas properties."""
txs: List[Transaction] = []
for tx in self.txs:
sender = tx.sender
assert sender is not None, "Sender is None"
if isinstance(tx, NetworkWrappedTransaction):
txs.append(tx.tx)
else:
txs.append(tx)
max_tx_gas_limit = Transaction.calculate_max_gas_limit(
txs=txs,
env_gas_limit=int(env.gas_limit),
transaction_gas_limit_cap=fork.transaction_gas_limit_cap(),
state_gas_reservoir_enabled=fork.state_gas_reservoir_enabled(),
)
for tx in txs:
tx.set_gas_limit(
max_gas_limit=max_tx_gas_limit,
transaction_gas_limit_cap=fork.transaction_gas_limit_cap(),
state_gas_reservoir_enabled=fork.state_gas_reservoir_enabled(),
)
tx.set_gas_price(
gas_price=gas_price,
max_fee_per_gas=max_fee_per_gas,
max_priority_fee_per_gas=max_priority_fee_per_gas,
max_fee_per_blob_gas=max_fee_per_blob_gas,
)

def get_required_sender_balances(
self, *, fork: Fork
) -> Dict[Address, int]:
"""Get the required sender balances."""
balances: Dict[Address, int] = {}
for tx in self.txs:
sender = tx.sender
assert sender is not None, "Sender is None"
if sender not in balances:
balances[sender] = 0
balances[sender] += tx.signer_minimum_balance(fork=fork)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
SendTransactionExceptionError,
)
from execution_testing.test_types import (
Environment,
NetworkWrappedTransaction,
TestPhase,
Transaction,
Expand All @@ -39,27 +40,46 @@ class TransactionPost(BaseExecute):
"are included"
)

def get_required_sender_balances(
def prepare_transactions(
self,
*,
env: Environment,
gas_price: int,
max_fee_per_gas: int,
max_priority_fee_per_gas: int,
max_fee_per_blob_gas: int,
fork: Fork,
) -> Dict[Address, int]:
"""Get the required sender balances."""
balances: Dict[Address, int] = {}
) -> None:
"""Prepare transactions by setting their final gas properties."""
for block in self.blocks:
max_tx_gas_limit = Transaction.calculate_max_gas_limit(
txs=block,
env_gas_limit=int(env.gas_limit),
transaction_gas_limit_cap=fork.transaction_gas_limit_cap(),
state_gas_reservoir_enabled=fork.state_gas_reservoir_enabled(),
)
for tx in block:
sender = tx.sender
assert sender is not None, "Sender is None"
tx.set_gas_limit(
max_gas_limit=max_tx_gas_limit,
transaction_gas_limit_cap=fork.transaction_gas_limit_cap(),
state_gas_reservoir_enabled=fork.state_gas_reservoir_enabled(),
)
tx.set_gas_price(
gas_price=gas_price,
max_fee_per_gas=max_fee_per_gas,
max_priority_fee_per_gas=max_priority_fee_per_gas,
max_fee_per_blob_gas=max_fee_per_blob_gas,
)

def get_required_sender_balances(
self, *, fork: Fork
) -> Dict[Address, int]:
"""Get the required sender balances."""
balances: Dict[Address, int] = {}
for block in self.blocks:
for tx in block:
sender = tx.sender
assert sender is not None, "Sender is None"
if sender not in balances:
balances[sender] = 0
balances[sender] += tx.signer_minimum_balance(fork=fork)
Expand Down
Loading
Loading