Repository: ethereum/execution-spec-tests
Pull request #1470: feat(tests): Add flag to configure `max_gas` for fill command
Author: login: reedsa
Labels: name: scope:fill
description: Scope: fill command
Created: 2025-04-16T19:23:23Z | Merged: 2025-05-05T17:39:51Z

## 🗒️ Description
<!-- Brief description of the changes introduced by this PR -->
Add flag to configure `max_gas` for fill command with default of of 30_000_000.
Add fixture for `max_gas` to use in `gas_limit` of a Transaction.

## 🔗 Related Issues
<!-- Reference any related issues using the GitHub issue number (e.g., Fixes #123) -->
#1434 

## ✅ Checklist

- [x] All: Set appropriate labels for the changes.
- [x] All: Considered squashing commits to improve commit history.
- [x] All: Added an entry to [CHANGELOG.md](/ethereum/execution-spec-tests/blob/main/docs/CHANGELOG.md).
- [x] All: Considered updating the online docs in the [./docs/](/ethereum/execution-spec-tests/blob/main/docs/) directory.
- [ ] Tests: All converted JSON/YML tests from [ethereum/tests](/ethereum/tests) have been added to [converted-ethereum-tests.txt](/ethereum/execution-spec-tests/blob/main/converted-ethereum-tests.txt).
- [ ] Tests: A PR with removal of converted JSON/YML tests from [ethereum/tests](/ethereum/tests) have been opened.
- [ ] Tests: Included the type and version of evm t8n tool used to locally execute test cases:  e.g., ref with commit hash or geth 1.13.1-stable-3f40e65.
- [ ] Tests: Ran `mkdocs serve` locally and verified the auto-generated docs for new tests in the [Test Case Reference](https://eest.ethereum.org/main/tests/) are correctly formatted.



Diff:
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 427226fc5c2..42f16d533c9 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -15,6 +15,7 @@ Test fixtures for use by clients are available for each release on the [Github r
 - ✨ The `static_filler` plug-in now has support for static state tests (from [GeneralStateTests](https://github.com/ethereum/tests/tree/develop/src/GeneralStateTestsFiller)) ([#1362](https://github.com/ethereum/execution-spec-tests/pull/1362)).
 - ✨ Introduce `pytest.mark.exception_test` to mark tests that contain an invalid transaction or block ([#1436](https://github.com/ethereum/execution-spec-tests/pull/1436)).
 - 🐞 Fix `DeprecationWarning: Pickle, copy, and deepcopy support will be removed from itertools in Python 3.14.` by avoiding use `itertools` object in the spec `BaseTest` pydantic model ([#1414](https://github.com/ethereum/execution-spec-tests/pull/1414)).
+- ✨ An optional configuration flag to override the maximum gas limit in the environment for filling or executing tests is now available. The `--block-gas-limit` flag overrides the default block gas limit during filling. The `--transaction-gas-limit` flag overrides the maximum for transactions during execution. ([#1470](https://github.com/ethereum/execution-spec-tests/pull/1470)).
 
 #### `consume`
 
diff --git a/docs/filling_tests/filling_tests_command_line.md b/docs/filling_tests/filling_tests_command_line.md
index cb420d5f0a8..43bca31786f 100644
--- a/docs/filling_tests/filling_tests_command_line.md
+++ b/docs/filling_tests/filling_tests_command_line.md
@@ -115,82 +115,74 @@ Output:
 
 ```text
 usage: fill [-h] [--strict-alloc] [--ca-start CA_START] [--ca-incr CA_INCR]
-            [--evm-code-type EVM_CODE_TYPE] [--solc-bin SOLC_BIN]
-            [--solc-version SOLC_VERSION] [--evm-bin EVM_BIN] [--traces]
-            [--verify-fixtures] [--verify-fixtures-bin VERIFY_FIXTURES_BIN]
-            [--filler-path FILLER_PATH] [--output OUTPUT] [--flat-output]
-            [--single-fixture-per-file] [--no-html] [--strict-alloc]
-            [--ca-start CA_START] [--ca-incr CA_INCR] [--build-name BUILD_NAME]
-            [--evm-dump-dir EVM_DUMP_DIR] [--forks] [--fork FORK] [--from FROM]
-            [--until UNTIL]
+            [--evm-code-type EVM_CODE_TYPE] [--solc-bin SOLC_BIN] [--solc-version SOLC_VERSION]
+            [--evm-bin EVM_BIN] [--traces] [--verify-fixtures]
+            [--verify-fixtures-bin VERIFY_FIXTURES_BIN] [--filler-path FILLER_PATH] [--output OUTPUT]
+            [--flat-output] [--single-fixture-per-file] [--no-html] [--build-name BUILD_NAME]
+            [--skip-index SKIP_INDEX] [--block-gas-limit BLOCK_GAS_LIMIT] [--evm-dump-dir EVM_DUMP_DIR]
+            [--skip-evm-dump] [--forks] [--fork FORK] [--from FROM] [--until UNTIL]
 
 options:
   -h, --help            show this help message and exit
 
-Arguments defining pre-allocation behavior.:
-  --strict-alloc        [DEBUG ONLY] Disallows deploying a contract in a
-                        predefined address.
-  --ca-start CA_START, --contract-address-start CA_START
-                        The starting address from which tests will deploy
-                        contracts.
-  --ca-incr CA_INCR, --contract-address-increment CA_INCR
-                        The address increment value to each deployed contract by
-                        a test.
+Arguments defining pre-allocation behavior during test filling.:
+  --strict-alloc        [DEBUG ONLY] Disallows deploying a contract in a predefined address.
+  --ca-start, --contract-address-start CA_START
+                        The starting address from which tests will deploy contracts.
+  --ca-incr, --contract-address-increment CA_INCR
+                        The address increment value to each deployed contract by a test.
   --evm-code-type EVM_CODE_TYPE
                         Type of EVM code to deploy in each test by default.
 
 Arguments defining the solc executable:
-  --solc-bin SOLC_BIN   Path to a solc executable (for Yul source compilation).
-                        No default; if unspecified `--solc-version` is used.
+  --solc-bin SOLC_BIN   Path to a solc executable (for Yul source compilation). No default; if
+                        unspecified `--solc-version` is used.
   --solc-version SOLC_VERSION
                         Version of the solc compiler to use. Default: 0.8.24.
 
 Arguments defining evm executable behavior:
-  --evm-bin EVM_BIN     Path to an evm executable that provides `t8n`. Default:
-                        First 'evm' entry in PATH.
-  --traces              Collect traces of the execution information from the
-                        transition tool.
-  --verify-fixtures     Verify generated fixture JSON files using geth's evm
-                        blocktest command. By default, the same evm binary as for
-                        the t8n tool is used. A different (geth) evm binary may
-                        be specified via --verify-fixtures-bin, this must be
-                        specified if filling with a non-geth t8n tool that does
-                        not support blocktest.
+  --evm-bin EVM_BIN     Path to an evm executable (or name of an executable in the PATH) that provides
+                        `t8n`. Default: `ethereum-spec-evm-resolver`.
+  --traces              Collect traces of the execution information from the transition tool.
+  --verify-fixtures     Verify generated fixture JSON files using geth's evm blocktest command. By
+                        default, the same evm binary as for the t8n tool is used. A different (geth) evm
+                        binary may be specified via --verify-fixtures-bin, this must be specified if
+                        filling with a non-geth t8n tool that does not support blocktest.
   --verify-fixtures-bin VERIFY_FIXTURES_BIN
-                        Path to an evm executable that provides the `blocktest`
-                        command. Default: The first (geth) 'evm' entry in PATH.
+                        Path to an evm executable that provides the `blocktest` command. Default: The
+                        first (geth) 'evm' entry in PATH.
 
 Arguments defining filler location and output:
   --filler-path FILLER_PATH
                         Path to filler directives
-  --output OUTPUT       Directory path to store the generated test fixtures. If
-                        the specified path ends in '.tar.gz', then the specified
-                        tarball is additionally created (the fixtures are still
-                        written to the specified path without the '.tar.gz'
-                        suffix). Can be deleted. Default: './fixtures'.
-  --flat-output         Output each test case in the directory without the folder
-                        structure.
+  --output OUTPUT       Directory path to store the generated test fixtures. If the specified path ends
+                        in '.tar.gz', then the specified tarball is additionally created (the fixtures
+                        are still written to the specified path without the '.tar.gz' suffix). Can be
+                        deleted. Default: './fixtures'.
+  --flat-output         Output each test case in the directory without the folder structure.
   --single-fixture-per-file
-                        Don't group fixtures in JSON files by test function;
-                        write each fixture to its own file. This can be used to
-                        increase the granularity of --verify-fixtures.
-  --no-html             Don't generate an HTML test report (in the output
-                        directory). The --html flag can be used to specify a
-                        different path.
+                        Don't group fixtures in JSON files by test function; write each fixture to its
+                        own file. This can be used to increase the granularity of --verify-fixtures.
+  --no-html             Don't generate an HTML test report (in the output directory). The --html flag can
+                        be used to specify a different path.
   --build-name BUILD_NAME
-                        Specify a build name for the fixtures.ini file, e.g.,
-                        'stable'.
-  --index               Generate an index file for all produced fixtures.
+                        Specify a build name for the fixtures.ini file, e.g., 'stable'.
+  --skip-index SKIP_INDEX
+                        Skip generating an index file for all produced fixtures.
+  --block-gas-limit BLOCK_GAS_LIMIT
+                        Default gas limit used ceiling used for blocks and tests that attempt to consume
+                        an entire block's gas. (Default: 72000000)
 
 Arguments defining debug behavior:
-  --evm-dump-dir EVM_DUMP_DIR, --t8n-dump-dir EVM_DUMP_DIR
-                        Path to dump the transition tool debug output.  (Default: <repo>/logs/evm)
+  --evm-dump-dir, --t8n-dump-dir EVM_DUMP_DIR
+                        Path to dump the transition tool debug output. (Default:
+                        <repo>/logs/evm)
+  --skip-evm-dump, --skip-t8n-dump
+                        Skip dumping the the transition tool debug output.
 
 Specify the fork range to generate fixtures for:
   --forks               Display forks supported by the test framework and exit.
   --fork FORK           Only fill tests for the specified fork.
   --from FROM           Fill tests from and including the specified fork.
   --until UNTIL         Fill tests until and including the specified fork.
-
-Exit: After displaying help.
 ```
diff --git a/src/ethereum_test_specs/blockchain.py b/src/ethereum_test_specs/blockchain.py
index b72d84b22cd..679c464c028 100644
--- a/src/ethereum_test_specs/blockchain.py
+++ b/src/ethereum_test_specs/blockchain.py
@@ -1,5 +1,6 @@
 """Ethereum blockchain test spec definition and filler."""
 
+import warnings
 from pprint import pprint
 from typing import Any, Callable, ClassVar, Dict, Generator, List, Optional, Sequence, Tuple, Type
 
@@ -409,7 +410,15 @@ def generate_block_data(
         env = block.set_environment(previous_env)
         env = env.set_fork_requirements(fork)
 
-        txs = [tx.with_signature_and_sender() for tx in block.txs]
+        txs: List[Transaction] = []
+        for tx in block.txs:
+            if not self.is_slow_test() and tx.gas_limit >= Environment().gas_limit:
+                warnings.warn(
+                    f"{self.node_id()} uses a high Transaction gas_limit: {tx.gas_limit}",
+                    stacklevel=2,
+                )
+
+            txs.append(tx.with_signature_and_sender())
 
         if failing_tx_count := len([tx for tx in txs if tx.error]) > 0:
             if failing_tx_count > 1:
diff --git a/src/ethereum_test_specs/state.py b/src/ethereum_test_specs/state.py
index be4e03c0c4e..0e7f5ffb4df 100644
--- a/src/ethereum_test_specs/state.py
+++ b/src/ethereum_test_specs/state.py
@@ -1,5 +1,6 @@
 """Ethereum state test spec definition and filler."""
 
+import warnings
 from pprint import pprint
 from typing import Any, Callable, ClassVar, Dict, Generator, List, Optional, Sequence, Type
 
@@ -163,6 +164,11 @@ def make_state_test_fixture(
 
         env = self.env.set_fork_requirements(fork)
         tx = self.tx.with_signature_and_sender(keep_secret_key=True)
+        if not self.is_slow_test() and tx.gas_limit >= Environment().gas_limit:
+            warnings.warn(
+                f"{self.node_id()} uses a high Transaction gas_limit: {tx.gas_limit}",
+                stacklevel=2,
+            )
         pre_alloc = Alloc.merge(
             Alloc.model_validate(fork.pre_allocation()),
             self.pre,
diff --git a/src/ethereum_test_specs/tests/test_fixtures.py b/src/ethereum_test_specs/tests/test_fixtures.py
index 5d9cc8eac50..d44d42c0617 100644
--- a/src/ethereum_test_specs/tests/test_fixtures.py
+++ b/src/ethereum_test_specs/tests/test_fixtures.py
@@ -68,7 +68,7 @@ def test_check_helper_fixtures():
     ],
 )
 def test_make_genesis(fork: Fork, fixture_hash: bytes, default_t8n: TransitionTool):  # noqa: D103
-    env = Environment()
+    env = Environment(gas_limit=100_000_000_000_000_000)
 
     pre = Alloc(
         {
@@ -479,6 +479,7 @@ def post(self):  # noqa: D102
     @pytest.fixture
     def genesis_environment(self):  # noqa: D102
         return Environment(
+            gas_limit=100_000_000_000_000_000,
             base_fee_per_gas=1000,
             fee_recipient="0xba5e000000000000000000000000000000000000",
         )
@@ -869,6 +870,7 @@ def test_fill_blockchain_invalid_txs(
 
     # We start genesis with a baseFee of 1000
     genesis_environment = Environment(
+        gas_limit=100_000_000_000_000_000,
         base_fee_per_gas=1000,
         fee_recipient="0xba5e000000000000000000000000000000000000",
     )
diff --git a/src/ethereum_test_types/__init__.py b/src/ethereum_test_types/__init__.py
index e5bbb6bf186..26b57266f9c 100644
--- a/src/ethereum_test_types/__init__.py
+++ b/src/ethereum_test_types/__init__.py
@@ -17,6 +17,7 @@
     ConsolidationRequest,
     DepositRequest,
     Environment,
+    EnvironmentDefaults,
     NetworkWrappedTransaction,
     Removable,
     Requests,
@@ -38,6 +39,7 @@
     "DepositRequest",
     "EmptyTrieRoot",
     "Environment",
+    "EnvironmentDefaults",
     "EOA",
     "Hash",
     "HeaderNonce",
diff --git a/src/ethereum_test_types/tests/test_types.py b/src/ethereum_test_types/tests/test_types.py
index e535989185e..63542c8ecd4 100644
--- a/src/ethereum_test_types/tests/test_types.py
+++ b/src/ethereum_test_types/tests/test_types.py
@@ -4,7 +4,14 @@
 
 import pytest
 
-from ethereum_test_base_types import AccessList, Address, Bytes, TestPrivateKey, to_json
+from ethereum_test_base_types import (
+    AccessList,
+    Address,
+    Bytes,
+    TestPrivateKey,
+    ZeroPaddedHexNumber,
+    to_json,
+)
 from ethereum_test_base_types.pydantic import CopyValidateModel
 
 from ..types import (
@@ -451,7 +458,7 @@ def test_account_merge(
             Environment(),
             {
                 "currentCoinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
-                "currentGasLimit": "0x016345785d8a0000",
+                "currentGasLimit": str(ZeroPaddedHexNumber(Environment().gas_limit)),
                 "currentNumber": "0x01",
                 "currentTimestamp": "0x03e8",
                 "blockHashes": {},
@@ -484,7 +491,7 @@ def test_account_merge(
             ),
             {
                 "currentCoinbase": "0x0000000000000000000000000000000000001234",
-                "currentGasLimit": "0x016345785d8a0000",
+                "currentGasLimit": str(ZeroPaddedHexNumber(Environment().gas_limit)),
                 "currentNumber": "0x01",
                 "currentTimestamp": "0x03e8",
                 "currentDifficulty": "0x05",
diff --git a/src/ethereum_test_types/types.py b/src/ethereum_test_types/types.py
index 1c3f0426021..b716a759afa 100644
--- a/src/ethereum_test_types/types.py
+++ b/src/ethereum_test_types/types.py
@@ -335,6 +335,18 @@ class Withdrawal(WithdrawalGeneric[HexNumber]):
 
 
 DEFAULT_BASE_FEE = 7
+CURRENT_MAINNET_BLOCK_GAS_LIMIT = 36_000_000
+DEFAULT_BLOCK_GAS_LIMIT = CURRENT_MAINNET_BLOCK_GAS_LIMIT * 2
+
+
+@dataclass
+class EnvironmentDefaults:
+    """Default environment values."""
+
+    # By default, the constant `DEFAULT_BLOCK_GAS_LIMIT` is used.
+    # Other libraries (pytest plugins) may override this value by modifying the
+    # `EnvironmentDefaults.gas_limit` class attribute.
+    gas_limit: int = DEFAULT_BLOCK_GAS_LIMIT
 
 
 class EnvironmentGeneric(CamelModel, Generic[NumberBoundTypeVar]):
@@ -344,7 +356,9 @@ class EnvironmentGeneric(CamelModel, Generic[NumberBoundTypeVar]):
         Address("0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
         alias="currentCoinbase",
     )
-    gas_limit: NumberBoundTypeVar = Field(100_000_000_000_000_000, alias="currentGasLimit")  # type: ignore
+    gas_limit: NumberBoundTypeVar = Field(
+        default_factory=lambda: EnvironmentDefaults.gas_limit, alias="currentGasLimit"
+    )  # type: ignore
     number: NumberBoundTypeVar = Field(1, alias="currentNumber")  # type: ignore
     timestamp: NumberBoundTypeVar = Field(1_000, alias="currentTimestamp")  # type: ignore
     prev_randao: NumberBoundTypeVar | None = Field(None, alias="currentRandom")
diff --git a/src/pytest_plugins/execute/execute.py b/src/pytest_plugins/execute/execute.py
index 24ece89e077..ede989be539 100644
--- a/src/pytest_plugins/execute/execute.py
+++ b/src/pytest_plugins/execute/execute.py
@@ -11,7 +11,7 @@
 from ethereum_test_forks import Fork
 from ethereum_test_rpc import EthRPC
 from ethereum_test_tools import SPEC_TYPES, BaseTest
-from ethereum_test_types import TransactionDefaults
+from ethereum_test_types import EnvironmentDefaults, TransactionDefaults
 from pytest_plugins.spec_version_checker.spec_version_checker import EIPSpecTestItem
 
 from ..shared.helpers import get_spec_format_for_item, labeled_format_parameter_set
@@ -56,6 +56,18 @@ def pytest_addoption(parser):
             "unless overridden by the test."
         ),
     )
+    execute_group.addoption(
+        "--transaction-gas-limit",
+        action="store",
+        dest="transaction_gas_limit",
+        default=EnvironmentDefaults.gas_limit // 4,
+        type=int,
+        help=(
+            "Maximum gas used to execute a single transaction. "
+            "Will be used as ceiling for tests that attempt to consume the entire block gas limit."
+            f"(Default: {EnvironmentDefaults.gas_limit // 4})"
+        ),
+    )
 
     report_group = parser.getgroup("tests", "Arguments defining html report behavior")
     report_group.addoption(
@@ -86,6 +98,9 @@ def pytest_configure(config):
         called before the pytest-html plugin's pytest_configure to ensure that
         it uses the modified `htmlpath` option.
     """
+    # Modify the block gas limit if specified.
+    if config.getoption("transaction_gas_limit"):
+        EnvironmentDefaults.gas_limit = config.getoption("transaction_gas_limit")
     if config.option.collectonly:
         return
     if config.getoption("disable_html") and config.getoption("htmlpath") is None:
diff --git a/src/pytest_plugins/filler/filler.py b/src/pytest_plugins/filler/filler.py
index c1201911a56..3ba09c12b63 100644
--- a/src/pytest_plugins/filler/filler.py
+++ b/src/pytest_plugins/filler/filler.py
@@ -31,6 +31,7 @@
     generate_github_url,
     get_current_commit_hash_or_tag,
 )
+from ethereum_test_types import EnvironmentDefaults
 
 from ..shared.helpers import get_spec_format_for_item, labeled_format_parameter_set
 
@@ -172,6 +173,17 @@ def pytest_addoption(parser: pytest.Parser):
         default=True,
         help="Skip generating an index file for all produced fixtures.",
     )
+    test_group.addoption(
+        "--block-gas-limit",
+        action="store",
+        dest="block_gas_limit",
+        default=EnvironmentDefaults.gas_limit,
+        type=int,
+        help=(
+            "Default gas limit used ceiling used for blocks and tests that attempt to "
+            f"consume an entire block's gas. (Default: {EnvironmentDefaults.gas_limit})"
+        ),
+    )
 
     debug_group = parser.getgroup("debug", "Arguments defining debug behavior")
     debug_group.addoption(
@@ -211,6 +223,9 @@ def pytest_configure(config):
         called before the pytest-html plugin's pytest_configure to ensure that
         it uses the modified `htmlpath` option.
     """
+    # Modify the block gas limit if specified.
+    if config.getoption("block_gas_limit"):
+        EnvironmentDefaults.gas_limit = config.getoption("block_gas_limit")
     if config.option.collectonly:
         return
     if not config.getoption("disable_html") and config.getoption("htmlpath") is None:
diff --git a/src/pytest_plugins/filler/tests/test_filler.py b/src/pytest_plugins/filler/tests/test_filler.py
index 951e19a41ef..e5014bb5811 100644
--- a/src/pytest_plugins/filler/tests/test_filler.py
+++ b/src/pytest_plugins/filler/tests/test_filler.py
@@ -11,6 +11,7 @@
 
 import pytest
 
+from ethereum_test_tools import Environment
 from ethereum_clis import ExecutionSpecsTransitionTool, TransitionTool
 from pytest_plugins.filler.filler import default_output_directory
 
@@ -547,6 +548,7 @@ def test_fixture_output_based_on_command_line_args(
     testdir.copy_example(name="pytest.ini")
     args.append("-v")
     args.append("--no-html")
+
     result = testdir.runpytest(*args)
     result.assert_outcomes(
         passed=total_test_count * 3,
@@ -610,3 +612,132 @@ def test_fixture_output_based_on_command_line_args(
         assert "build" in properties
         build_name = args[args.index("--build-name") + 1]
         assert properties["build"] == build_name
+
+
+test_module_environment_variables = textwrap.dedent(
+    """\
+    import pytest
+
+    from ethereum_test_tools import Account, Environment, Transaction
+
+    @pytest.mark.parametrize("block_gas_limit", [Environment().gas_limit])
+    @pytest.mark.valid_at("Cancun")
+    def test_max_gas_limit(state_test, pre, block_gas_limit):
+        env = Environment()
+        assert block_gas_limit == {expected_gas_limit}
+        tx = Transaction(gas_limit=block_gas_limit, sender=pre.fund_eoa())
+        state_test(env=env, pre=pre, post={{}}, tx=tx)
+    """
+)
+
+
+@pytest.mark.run_in_serial
+@pytest.mark.parametrize(
+    "args, expected_fixture_files, expected_fixture_counts, expected_gas_limit",
+    [
+        pytest.param(
+            [],
+            [
+                Path(
+                    "fixtures/state_tests/cancun/module_environment_variables/max_gas_limit.json"
+                ),
+            ],
+            [1],
+            Environment().gas_limit,
+            id="default-args",
+        ),
+        pytest.param(
+            ["--block-gas-limit", str(Environment().gas_limit * 2)],
+            [
+                Path(
+                    "fixtures/state_tests/cancun/module_environment_variables/max_gas_limit.json"
+                ),
+            ],
+            [1],
+            Environment().gas_limit * 2,
+            id="higher-gas-limit",
+        ),
+    ],
+)
+def test_fill_variables(
+    testdir, args, expected_fixture_files, expected_fixture_counts, expected_gas_limit
+):
+    """
+    Test filling tests that depend on variables such as the max block gas limit.
+    """
+    tests_dir = testdir.mkdir("tests")
+
+    cancun_tests_dir = tests_dir.mkdir("cancun")
+    test_module = cancun_tests_dir.join("test_module_environment_variables.py")
+    test_module.write(
+        test_module_environment_variables.format(expected_gas_limit=expected_gas_limit)
+    )
+
+    testdir.copy_example(name="pytest.ini")
+    args.append("-v")
+    args.append("-m")
+    args.append("state_test")
+    args.append("--no-html")
+    result = testdir.runpytest(*args)
+    result.assert_outcomes(
+        passed=1,
+        failed=0,
+        skipped=0,
+        errors=0,
+    )
+    if "--output" in args:
+        output_dir = Path(args[args.index("--output") + 1]).absolute()
+    else:
+        output_dir = Path(default_output_directory()).absolute()
+    assert output_dir.exists()
+
+    all_files = get_all_files_in_directory(output_dir)
+    meta_dir = os.path.join(output_dir, ".meta")
+    assert os.path.exists(meta_dir), f"The directory {meta_dir} does not exist"
+
+    expected_ini_file = "fixtures.ini"
+    expected_index_file = "index.json"
+    expected_resolver_file = None
+    if TransitionTool.default_tool == ExecutionSpecsTransitionTool:
+        expected_resolver_file = "eels_resolutions.json"
+
+    ini_file = None
+    index_file = None
+    for file in all_files:
+        if file.name == expected_ini_file:
+            ini_file = file
+        elif file.name == expected_index_file:
+            index_file = file
+        elif expected_resolver_file and file.name == expected_resolver_file:
+            resolver_file = file
+            assert resolver_file.exists(), f"{resolver_file} does not exist"
+
+    expected_additional_files = {expected_ini_file, expected_index_file}
+    if resolver_file:
+        expected_additional_files.add(expected_resolver_file)
+    all_fixtures = [file for file in all_files if file.name not in expected_additional_files]
+    for fixture_file, fixture_count in zip(expected_fixture_files, expected_fixture_counts):
+        assert fixture_file.exists(), f"{fixture_file} does not exist"
+        assert fixture_count == count_keys_in_fixture(fixture_file), (
+            f"Fixture count mismatch for {fixture_file}"
+        )
+
+    assert set(all_fixtures) == set(expected_fixture_files), (
+        f"Unexpected files in directory: {set(all_fixtures) - set(expected_fixture_files)}"
+    )
+
+    assert ini_file is not None, f"No {expected_ini_file} file was found in {meta_dir}"
+    config = configparser.ConfigParser()
+    config.read(ini_file)
+
+    if "--skip-index" not in args:
+        assert index_file is not None, f"No {expected_index_file} file was found in {meta_dir}"
+
+    properties = {key: value for key, value in config.items("fixtures")}
+    assert "timestamp" in properties
+    timestamp = datetime.fromisoformat(properties["timestamp"])
+    assert timestamp.year == datetime.now().year
+    if "--build-name" in args:
+        assert "build" in properties
+        build_name = args[args.index("--build-name") + 1]
+        assert properties["build"] == build_name
diff --git a/tests/cancun/eip1153_tstore/test_tstorage.py b/tests/cancun/eip1153_tstore/test_tstorage.py
index 6ef433a5b16..dc7d9c4bb24 100644
--- a/tests/cancun/eip1153_tstore/test_tstorage.py
+++ b/tests/cancun/eip1153_tstore/test_tstorage.py
@@ -263,6 +263,7 @@ class LoopRunUntilOutOfGasCases(PytestParameterEnum):
 
 
 @LoopRunUntilOutOfGasCases.parametrize()
+@pytest.mark.slow()
 def test_run_until_out_of_gas(
     state_test: StateTestFiller,
     pre: Alloc,
@@ -270,14 +271,16 @@ def test_run_until_out_of_gas(
     bytecode_repeat_times: int,
 ):
     """Use TSTORE over and over to different keys until we run out of gas."""
+    env = Environment()
+
     bytecode = Op.JUMPDEST + repeat_bytecode * bytecode_repeat_times + Op.JUMP(Op.PUSH0)
     code_address = pre.deploy_contract(code=bytecode)
     tx = Transaction(
         sender=pre.fund_eoa(),
         to=code_address,
-        gas_limit=30_000_000,
+        gas_limit=env.gas_limit,
     )
     post = {
         code_address: Account(code=bytecode, storage={}),
     }
-    state_test(env=Environment(), pre=pre, tx=tx, post=post)
+    state_test(env=env, pre=pre, tx=tx, post=post)
diff --git a/tests/constantinople/eip1014_create2/test_create_returndata.py b/tests/constantinople/eip1014_create2/test_create_returndata.py
index 400955315d4..e0e8cffc344 100644
--- a/tests/constantinople/eip1014_create2/test_create_returndata.py
+++ b/tests/constantinople/eip1014_create2/test_create_returndata.py
@@ -6,14 +6,7 @@
 
 import pytest
 
-from ethereum_test_tools import (
-    Account,
-    Alloc,
-    Environment,
-    StateTestFiller,
-    Transaction,
-    keccak256,
-)
+from ethereum_test_tools import Account, Alloc, StateTestFiller, Transaction, keccak256
 from ethereum_test_tools import Opcodes as Op
 
 from .spec import ref_spec_1014
@@ -133,8 +126,8 @@ def test_create2_return_data(
         to=address_to,
         protected=False,
         data=initcode,
-        gas_limit=0x0A00000000,
+        gas_limit=500_000,
         value=0,
     )  # type: ignore
 
-    state_test(env=Environment(), pre=pre, post=post, tx=tx)
+    state_test(pre=pre, post=post, tx=tx)
diff --git a/tests/constantinople/eip1014_create2/test_recreate.py b/tests/constantinople/eip1014_create2/test_recreate.py
index a7d9fb7ffc2..0f4f8969765 100644
--- a/tests/constantinople/eip1014_create2/test_recreate.py
+++ b/tests/constantinople/eip1014_create2/test_recreate.py
@@ -8,7 +8,6 @@
     Alloc,
     Block,
     BlockchainTestFiller,
-    Environment,
     Initcode,
     Transaction,
     Yul,
@@ -35,8 +34,6 @@ def test_recreate(
     Test that the storage is cleared when a contract is first destructed then re-created using
     CREATE2.
     """
-    env = Environment()
-
     creator_contract_code = Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE) + Op.CREATE2(
         0, 0, Op.CALLDATASIZE, 0
     )
@@ -61,7 +58,7 @@ def test_recreate(
     initcode = Initcode(deploy_code=deploy_code)
 
     create_tx = Transaction(
-        gas_limit=100000000,
+        gas_limit=100_000,
         to=creator_address,
         data=initcode,
         sender=sender,
@@ -72,7 +69,7 @@ def test_recreate(
     )
 
     set_storage_tx = Transaction(
-        gas_limit=100000000,
+        gas_limit=100_000,
         to=created_contract_address,
         value=1,
         sender=sender,
@@ -81,7 +78,7 @@ def test_recreate(
     blocks = [Block(txs=[create_tx, set_storage_tx])]
 
     destruct_tx = Transaction(
-        gas_limit=100000000,
+        gas_limit=100_000,
         to=created_contract_address,
         value=0,
         sender=sender,
@@ -89,14 +86,14 @@ def test_recreate(
 
     balance = 1
     send_funds_tx = Transaction(
-        gas_limit=100000000,
+        gas_limit=100_000,
         to=created_contract_address,
         value=balance,
         sender=sender,
     )
 
     re_create_tx = Transaction(
-        gas_limit=100000000,
+        gas_limit=100_000,
         to=creator_address,
         data=initcode,
         sender=sender,
@@ -117,4 +114,4 @@ def test_recreate(
         ),
     }
 
-    blockchain_test(genesis_environment=env, pre=pre, post=post, blocks=blocks)
+    blockchain_test(pre=pre, post=post, blocks=blocks)
diff --git a/tests/frontier/opcodes/test_all_opcodes.py b/tests/frontier/opcodes/test_all_opcodes.py
index 854e66d9398..297e3ad7068 100644
--- a/tests/frontier/opcodes/test_all_opcodes.py
+++ b/tests/frontier/opcodes/test_all_opcodes.py
@@ -66,7 +66,9 @@ def test_all_opcodes(state_test: StateTestFiller, pre: Alloc, fork: Fork):
         code=sum(
             Op.SSTORE(
                 Op.PUSH1(opcode.int()),
-                Op.CALL(1_000_000, opcode_address, 0, 0, 0, 0, 0),
+                # Limit gas to limit the gas consumed by the exceptional aborts in each
+                # subcall that uses an undefined opcode.
+                Op.CALL(50_000, opcode_address, 0, 0, 0, 0, 0),
             )
             for opcode, opcode_address in code_contract.items()
         )
@@ -82,14 +84,14 @@ def test_all_opcodes(state_test: StateTestFiller, pre: Alloc, fork: Fork):
 
     tx = Transaction(
         sender=pre.fund_eoa(),
-        gas_limit=500_000_000,
+        gas_limit=15_000_000,
         to=contract_address,
         data=b"",
         value=0,
         protected=False,
     )
 
-    state_test(env=Environment(), pre=pre, post=post, tx=tx)
+    state_test(pre=pre, post=post, tx=tx)
 
 
 @pytest.mark.valid_from("Cancun")
diff --git a/tests/frontier/opcodes/test_selfdestruct.py b/tests/frontier/opcodes/test_selfdestruct.py
index e65fead6f15..e165684a0d8 100644
--- a/tests/frontier/opcodes/test_selfdestruct.py
+++ b/tests/frontier/opcodes/test_selfdestruct.py
@@ -2,15 +2,7 @@
 
 import pytest
 
-from ethereum_test_tools import (
-    Account,
-    Alloc,
-    Block,
-    BlockchainTestFiller,
-    Environment,
-    Initcode,
-    Transaction,
-)
+from ethereum_test_tools import Account, Alloc, Block, BlockchainTestFiller, Initcode, Transaction
 from ethereum_test_tools import Opcodes as Op
 
 
@@ -22,7 +14,6 @@ def test_double_kill(blockchain_test: BlockchainTestFiller, pre: Alloc):
     the second transaction actually resurrects the contract as an empty account (prior to Spurious
     Dragon).
     """
-    env = Environment()
     sender = pre.fund_eoa()
 
     deploy_code = Op.SELFDESTRUCT(Op.ADDRESS)
@@ -30,7 +21,7 @@ def test_double_kill(blockchain_test: BlockchainTestFiller, pre: Alloc):
     initcode = Initcode(deploy_code=deploy_code)
 
     create_tx = Transaction(
-        gas_limit=100000000,
+        gas_limit=100_000,
         protected=False,
         to=None,
         data=initcode,
@@ -40,14 +31,14 @@ def test_double_kill(blockchain_test: BlockchainTestFiller, pre: Alloc):
     block_1 = Block(txs=[create_tx])
 
     first_kill = Transaction(
-        gas_limit=100000000,
+        gas_limit=100_000,
         protected=False,
         to=create_tx.created_contract,
         sender=sender,
     )
 
     second_kill = Transaction(
-        gas_limit=100000000,
+        gas_limit=100_000,
         protected=False,
         to=create_tx.created_contract,
         sender=sender,
@@ -64,4 +55,4 @@ def test_double_kill(blockchain_test: BlockchainTestFiller, pre: Alloc):
         ),
     }
 
-    blockchain_test(genesis_environment=env, pre=pre, post=post, blocks=[block_1, block_2])
+    blockchain_test(pre=pre, post=post, blocks=[block_1, block_2])
diff --git a/tests/istanbul/eip152_blake2/test_blake2.py b/tests/istanbul/eip152_blake2/test_blake2.py
index 34222c32239..63e19823467 100644
--- a/tests/istanbul/eip152_blake2/test_blake2.py
+++ b/tests/istanbul/eip152_blake2/test_blake2.py
@@ -532,7 +532,7 @@ def test_blake2b_invalid_gas(
 
 @pytest.mark.valid_from("Istanbul")
 @pytest.mark.parametrize("call_opcode", [Op.CALL, Op.CALLCODE])
-@pytest.mark.parametrize("gas_limit", [100_000_000, 90_000, 110_000, 200_000])
+@pytest.mark.parametrize("gas_limit", [Environment().gas_limit, 90_000, 110_000, 200_000])
 @pytest.mark.parametrize(
     ["data", "output"],
     [
@@ -606,8 +606,6 @@ def test_blake2b_gas_limit(
     output: ExpectedOutput,
 ):
     """Test BLAKE2b precompile with different gas limits."""
-    env = Environment()
-
     account = pre.deploy_contract(blake2b_contract_bytecode, storage={0: 0xDEADBEEF})
     sender = pre.fund_eoa()
 
@@ -635,7 +633,11 @@ def test_blake2b_gas_limit(
             }
         )
     }
-    state_test(env=env, pre=pre, post=post, tx=tx)
+    state_test(
+        pre=pre,
+        post=post,
+        tx=tx,
+    )
 
 
 @pytest.mark.valid_from("Istanbul")
@@ -695,7 +697,6 @@ def test_blake2b_gas_limit(
                 data_2="0xd37f63034b83f4a0a07cd238483874862921ef0c40630826a76e41bf3b02ffe3",
             ),
             id="EIP-152-modified-case8-data9-large-gas-limit",
-            marks=pytest.mark.slow,
         ),
         pytest.param(
             Blake2bInput(
@@ -720,6 +721,7 @@ def test_blake2b_gas_limit(
         ),
     ],
 )
+@pytest.mark.slow()
 def test_blake2b_large_gas_limit(
     state_test: StateTestFiller,
     pre: Alloc,
@@ -743,7 +745,7 @@ def test_blake2b_large_gas_limit(
         ty=0x0,
         to=account,
         data=data,
-        gas_limit=100_000_000,
+        gas_limit=env.gas_limit,
         protected=True,
         sender=sender,
         value=0,
diff --git a/tests/prague/eip2537_bls_12_381_precompiles/conftest.py b/tests/prague/eip2537_bls_12_381_precompiles/conftest.py
index f76fe87d357..f09bbd6cf96 100644
--- a/tests/prague/eip2537_bls_12_381_precompiles/conftest.py
+++ b/tests/prague/eip2537_bls_12_381_precompiles/conftest.py
@@ -4,6 +4,7 @@
 
 import pytest
 
+from ethereum_test_forks import Fork
 from ethereum_test_tools import EOA, Address, Alloc, Bytecode, Storage, Transaction, keccak256
 from ethereum_test_tools import Opcodes as Op
 
@@ -168,9 +169,17 @@ def post(call_contract_address: Address, call_contract_post_storage: Storage):
 
 
 @pytest.fixture
-def tx_gas_limit(precompile_gas: int) -> int:
+def tx_gas_limit(fork: Fork, input_data: bytes, precompile_gas: int) -> int:
     """Transaction gas limit used for the test (Can be overridden in the test)."""
-    return 10_000_000 + precompile_gas
+    intrinsic_gas_cost_calculator = fork.transaction_intrinsic_cost_calculator()
+    memory_expansion_gas_calculator = fork.memory_expansion_gas_calculator()
+    extra_gas = 100_000
+    return (
+        extra_gas
+        + intrinsic_gas_cost_calculator(calldata=input_data)
+        + memory_expansion_gas_calculator(new_bytes=len(input_data))
+        + precompile_gas
+    )
 
 
 @pytest.fixture
diff --git a/tests/prague/eip2537_bls_12_381_precompiles/test_bls12_variable_length_input_contracts.py b/tests/prague/eip2537_bls_12_381_precompiles/test_bls12_variable_length_input_contracts.py
index b76b990e096..63505ee6995 100644
--- a/tests/prague/eip2537_bls_12_381_precompiles/test_bls12_variable_length_input_contracts.py
+++ b/tests/prague/eip2537_bls_12_381_precompiles/test_bls12_variable_length_input_contracts.py
@@ -7,6 +7,7 @@
 
 import pytest
 
+from ethereum_test_forks import Fork
 from ethereum_test_tools import Alloc, Bytecode, Environment, StateTestFiller, Storage, Transaction
 from ethereum_test_tools import Opcodes as Op
 
@@ -97,6 +98,20 @@ def call_contract_code(
     return code
 
 
+@pytest.fixture
+def tx_gas_limit(fork: Fork, input_data: bytes, precompile_gas_list: List[int]) -> int:
+    """Transaction gas limit used for the test (Can be overridden in the test)."""
+    intrinsic_gas_cost_calculator = fork.transaction_intrinsic_cost_calculator()
+    memory_expansion_gas_calculator = fork.memory_expansion_gas_calculator()
+    extra_gas = 100_000 * len(precompile_gas_list)
+    return (
+        extra_gas
+        + intrinsic_gas_cost_calculator(calldata=input_data)
+        + memory_expansion_gas_calculator(new_bytes=len(input_data))
+        + sum(precompile_gas_list)
+    )
+
+
 @pytest.mark.parametrize(
     "precompile_gas_list,precompile_data_length_list",
     [
@@ -116,7 +131,6 @@ def call_contract_code(
     ],
 )
 @pytest.mark.parametrize("expected_output", [PointG1()], ids=[""])
-@pytest.mark.parametrize("tx_gas_limit", [100_000_000], ids=[""])
 @pytest.mark.parametrize("precompile_address", [Spec.G1MSM])
 def test_valid_gas_g1msm(
     state_test: StateTestFiller,
@@ -131,7 +145,7 @@ def test_valid_gas_g1msm(
     If any of the calls fail, the test will fail.
     """
     state_test(
-        env=Environment(),
+        env=Environment(gas_limit=tx.gas_limit),
         pre=pre,
         tx=tx,
         post=post,
@@ -157,7 +171,6 @@ def test_valid_gas_g1msm(
     ],
 )
 @pytest.mark.parametrize("expected_output", [Spec.INVALID], ids=[""])
-@pytest.mark.parametrize("tx_gas_limit", [100_000_000], ids=[""])
 @pytest.mark.parametrize("precompile_address", [Spec.G1MSM])
 def test_invalid_gas_g1msm(
     state_test: StateTestFiller,
@@ -172,7 +185,7 @@ def test_invalid_gas_g1msm(
     If any of the calls succeeds, the test will fail.
     """
     state_test(
-        env=Environment(),
+        env=Environment(gas_limit=tx.gas_limit),
         pre=pre,
         tx=tx,
         post=post,
@@ -200,7 +213,6 @@ def test_invalid_gas_g1msm(
     ],
 )
 @pytest.mark.parametrize("expected_output", [Spec.INVALID], ids=[""])
-@pytest.mark.parametrize("tx_gas_limit", [100_000_000], ids=[""])
 @pytest.mark.parametrize("precompile_address", [Spec.G1MSM])
 def test_invalid_length_g1msm(
     state_test: StateTestFiller,
@@ -215,7 +227,7 @@ def test_invalid_length_g1msm(
     If any of the calls succeeds, the test will fail.
     """
     state_test(
-        env=Environment(),
+        env=Environment(gas_limit=tx.gas_limit),
         pre=pre,
         tx=tx,
         post=post,
@@ -241,7 +253,6 @@ def test_invalid_length_g1msm(
     ],
 )
 @pytest.mark.parametrize("expected_output", [PointG2()], ids=[""])
-@pytest.mark.parametrize("tx_gas_limit", [110_000_000], ids=[""])
 @pytest.mark.parametrize("precompile_address", [Spec.G2MSM])
 def test_valid_gas_g2msm(
     state_test: StateTestFiller,
@@ -256,7 +267,7 @@ def test_valid_gas_g2msm(
     If any of the calls fail, the test will fail.
     """
     state_test(
-        env=Environment(),
+        env=Environment(gas_limit=tx.gas_limit),
         pre=pre,
         tx=tx,
         post=post,
@@ -282,7 +293,6 @@ def test_valid_gas_g2msm(
     ],
 )
 @pytest.mark.parametrize("expected_output", [Spec.INVALID], ids=[""])
-@pytest.mark.parametrize("tx_gas_limit", [100_000_000], ids=[""])
 @pytest.mark.parametrize("precompile_address", [Spec.G2MSM])
 def test_invalid_gas_g2msm(
     state_test: StateTestFiller,
@@ -297,7 +307,7 @@ def test_invalid_gas_g2msm(
     If any of the calls succeeds, the test will fail.
     """
     state_test(
-        env=Environment(),
+        env=Environment(gas_limit=tx.gas_limit),
         pre=pre,
         tx=tx,
         post=post,
@@ -325,7 +335,6 @@ def test_invalid_gas_g2msm(
     ],
 )
 @pytest.mark.parametrize("expected_output", [Spec.INVALID], ids=[""])
-@pytest.mark.parametrize("tx_gas_limit", [100_000_000], ids=[""])
 @pytest.mark.parametrize("precompile_address", [Spec.G2MSM])
 def test_invalid_length_g2msm(
     state_test: StateTestFiller,
@@ -340,7 +349,7 @@ def test_invalid_length_g2msm(
     If any of the calls succeeds, the test will fail.
     """
     state_test(
-        env=Environment(),
+        env=Environment(gas_limit=tx.gas_limit),
         pre=pre,
         tx=tx,
         post=post,
@@ -363,7 +372,6 @@ def test_invalid_length_g2msm(
     ],
 )
 @pytest.mark.parametrize("expected_output", [Spec.PAIRING_TRUE], ids=[""])
-@pytest.mark.parametrize("tx_gas_limit", [100_000_000], ids=[""])
 @pytest.mark.parametrize("precompile_address", [Spec.PAIRING])
 def test_valid_gas_pairing(
     state_test: StateTestFiller,
@@ -378,7 +386,7 @@ def test_valid_gas_pairing(
     If any of the calls fails, the test will fail.
     """
     state_test(
-        env=Environment(),
+        env=Environment(gas_limit=tx.gas_limit),
         pre=pre,
         tx=tx,
         post=post,
@@ -401,7 +409,6 @@ def test_valid_gas_pairing(
     ],
 )
 @pytest.mark.parametrize("expected_output", [Spec.INVALID], ids=[""])
-@pytest.mark.parametrize("tx_gas_limit", [100_000_000], ids=[""])
 @pytest.mark.parametrize("precompile_address", [Spec.PAIRING])
 def test_invalid_gas_pairing(
     state_test: StateTestFiller,
@@ -416,7 +423,7 @@ def test_invalid_gas_pairing(
     If any of the calls succeeds, the test will fail.
     """
     state_test(
-        env=Environment(),
+        env=Environment(gas_limit=tx.gas_limit),
         pre=pre,
         tx=tx,
         post=post,
@@ -444,7 +451,6 @@ def test_invalid_gas_pairing(
     ],
 )
 @pytest.mark.parametrize("expected_output", [Spec.INVALID], ids=[""])
-@pytest.mark.parametrize("tx_gas_limit", [100_000_000], ids=[""])
 @pytest.mark.parametrize("precompile_address", [Spec.PAIRING])
 def test_invalid_length_pairing(
     state_test: StateTestFiller,
@@ -459,7 +465,7 @@ def test_invalid_length_pairing(
     If any of the calls succeeds, the test will fail.
     """
     state_test(
-        env=Environment(),
+        env=Environment(gas_limit=tx.gas_limit),
         pre=pre,
         tx=tx,
         post=post,
diff --git a/tests/prague/eip6110_deposits/test_deposits.py b/tests/prague/eip6110_deposits/test_deposits.py
index 6354fe21228..98d0776e0a4 100644
--- a/tests/prague/eip6110_deposits/test_deposits.py
+++ b/tests/prague/eip6110_deposits/test_deposits.py
@@ -704,7 +704,7 @@ def test_deposit(
 ):
     """Test making a deposit to the beacon chain deposit contract."""
     blockchain_test(
-        genesis_environment=Environment(),
+        genesis_environment=Environment(gas_limit=sum(tx.gas_limit for tx in blocks[0].txs)),
         pre=pre,
         post={},
         blocks=blocks,
diff --git a/tests/prague/eip7702_set_code_tx/test_gas.py b/tests/prague/eip7702_set_code_tx/test_gas.py
index 66628a37f3a..2982f6c50eb 100644
--- a/tests/prague/eip7702_set_code_tx/test_gas.py
+++ b/tests/prague/eip7702_set_code_tx/test_gas.py
@@ -415,11 +415,13 @@ def sender(
 
 
 def gas_test_parameter_args(
-    include_many: bool = True, include_data: bool = True, include_pre_authorized: bool = True
+    include_many: bool = True,
+    include_data: bool = True,
+    include_pre_authorized: bool = True,
+    execution_gas_allowance: bool = False,
 ):
     """Return the parametrize decorator that can be used in all gas test functions."""
     multiple_authorizations_count = 2
-    many_authorizations_count = 5_000
 
     defaults = {
         "signer_type": SignerType.SINGLE_SIGNER,
@@ -691,6 +693,12 @@ def gas_test_parameter_args(
         ]
 
     if include_many:
+        # Fit as many authorizations as possible within the block gas limit.
+        max_gas = Environment().gas_limit - 21_000
+        if execution_gas_allowance:
+            # Leave some gas for the execution of the test code.
+            max_gas -= 1_000_000
+        many_authorizations_count = max_gas // Spec.PER_EMPTY_ACCOUNT_COST
         cases += [
             pytest.param(
                 {
@@ -721,7 +729,9 @@ def gas_test_parameter_args(
 # Tests
 
 
-@pytest.mark.parametrize(**gas_test_parameter_args(include_pre_authorized=False))
+@pytest.mark.parametrize(
+    **gas_test_parameter_args(include_pre_authorized=False, execution_gas_allowance=True)
+)
 def test_gas_cost(
     state_test: StateTestFiller,
     pre: Alloc,
@@ -810,7 +820,6 @@ def test_gas_cost(
     )
 
     state_test(
-        env=Environment(gas_limit=max(tx_gas_limit, 30_000_000)),
         pre=pre,
         tx=tx,
         post={
@@ -967,7 +976,6 @@ def test_account_warming(
     }
 
     state_test(
-        env=Environment(),
         pre=pre,
         tx=tx,
         post=post,
@@ -1020,7 +1028,6 @@ def test_intrinsic_gas_cost(
     )
 
     state_test(
-        env=Environment(),
         pre=pre,
         tx=tx,
         post={},
@@ -1070,7 +1077,6 @@ def test_self_set_code_cost(
     )
 
     state_test(
-        env=Environment(),
         pre=pre,
         tx=tx,
         post={
@@ -1123,7 +1129,6 @@ def test_call_to_pre_authorized_oog(
     )
 
     state_test(
-        env=Environment(),
         pre=pre,
         tx=tx,
         post={
diff --git a/tests/prague/eip7702_set_code_tx/test_set_code_txs.py b/tests/prague/eip7702_set_code_tx/test_set_code_txs.py
index c46b167dcd4..1654358847a 100644
--- a/tests/prague/eip7702_set_code_tx/test_set_code_txs.py
+++ b/tests/prague/eip7702_set_code_tx/test_set_code_txs.py
@@ -689,7 +689,7 @@ def test_set_code_max_depth_call_stack(
     )
 
     state_test(
-        env=Environment(),
+        env=Environment(gas_limit=tx.gas_limit),
         pre=pre,
         tx=tx,
         post={
@@ -3415,29 +3415,13 @@ def test_creating_delegation_designation_contract(
         ),
     ],
 )
-@pytest.mark.parametrize(
-    "max_gas",
-    [
-        pytest.param(
-            120_000_000,
-            id="120m",
-            marks=pytest.mark.execute(pytest.mark.skip(reason="excessive gas")),
-        ),
-        pytest.param(
-            20_000_000,
-            id="20m",
-            marks=pytest.mark.fill(pytest.mark.skip(reason="execute-only test")),
-        ),
-    ],
-)
 def test_many_delegations(
     state_test: StateTestFiller,
     pre: Alloc,
-    max_gas: int,
     signer_balance: int,
 ):
     """
-    Perform as many delegations as possible in a single 120 million gas transaction.
+    Perform as many delegations as possible in a transaction using the entire block gas limit.
 
     Every delegation comes from a different signer.
 
@@ -3446,6 +3430,8 @@ def test_many_delegations(
     The transaction is expected to succeed and the state after the transaction is expected to have
     the code of the entry contract set to 1.
     """
+    env = Environment()
+    max_gas = env.gas_limit
     gas_for_delegations = max_gas - 21_000 - 20_000 - (3 * 2)
 
     delegation_count = gas_for_delegations // Spec.PER_EMPTY_ACCOUNT_COST
diff --git a/tests/shanghai/eip3651_warm_coinbase/test_warm_coinbase.py b/tests/shanghai/eip3651_warm_coinbase/test_warm_coinbase.py
index bb1716e7a39..b3a3c5d47ea 100644
--- a/tests/shanghai/eip3651_warm_coinbase/test_warm_coinbase.py
+++ b/tests/shanghai/eip3651_warm_coinbase/test_warm_coinbase.py
@@ -104,7 +104,7 @@ def test_warm_coinbase_call_out_of_gas(
         chain_id=0x01,
         nonce=0,
         to=caller_address,
-        gas_limit=100000000,
+        gas_limit=100_000,
         gas_price=10,
         sender=sender,
     )
@@ -244,7 +244,7 @@ def test_warm_coinbase_gas_usage(
         chain_id=0x01,
         nonce=0,
         to=measure_address,
-        gas_limit=100000000,
+        gas_limit=100_000,
         gas_price=10,
         sender=sender,
     )


Reviews:
user: login: marioevz
body: I think it looks very good!

After going through the code, I'm more convinced about the separation between `gas_limit` and `block_gas_limit`.

I'll try the changes today locally and potentially merge if it goes well :)
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-02T14:50:48Z
user: login: marioevz
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-03T00:44:21Z
user: login: marioevz
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-03T00:46:01Z
user: login: reedsa
body: Great work on these updates! I think the only update I would make is to the help text and I'll go ahead and push up that change.

Any test that currently just uses the default environment could also stop using `env = Environment()` to pass into `state_test` but isn't necessarily hurting anything as is. Looks good to go!
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-05T15:27:08Z
user: login: marioevz
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-05T15:54:30Z
user: login: marioevz
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-05T15:55:30Z
user: login: marioevz
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-05T17:22:57Z
user: login: marioevz
body: LGTM, thanks for this!

I'll apply my comments and merge :)
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-05T17:30:25Z

Review comments:
diff_hunk: @@ -409,7 +410,15 @@ def generate_block_data(
         env = block.set_environment(previous_env)
         env = env.set_fork_requirements(fork)
 
-        txs = [tx.with_signature_and_sender() for tx in block.txs]
+        txs: List[Transaction] = []
+        for tx in block.txs:
+            if not self.is_slow_test() and tx.gas_limit >= 30_000_000:
path: src/ethereum_test_specs/blockchain.py
user: login: marioevz
body: I think this is a great addition, we should overall reduce the amount of tests that go over this limit unless they have very specific reasons to do it.
created_at: 2025-05-02T14:46:55Z
author_association: MEMBER
diff_hunk: @@ -335,6 +335,18 @@ class Withdrawal(WithdrawalGeneric[HexNumber]):
 
 
 DEFAULT_BASE_FEE = 7
+CURRENT_MAINNET_BLOCK_GAS_LIMIT = 36_000_000
+DEFAULT_BLOCK_GAS_LIMIT = CURRENT_MAINNET_BLOCK_GAS_LIMIT * 2
path: src/ethereum_test_types/types.py
user: login: marioevz
body: I'm thinking this should be a sane limit of always filling the tests with twice the value we currently have in mainnet, with the possibility of preemptively bumping it before we signal a safe increment to client devs/node operators.
created_at: 2025-05-03T00:44:21Z
author_association: MEMBER
diff_hunk: @@ -532,7 +532,7 @@ def test_blake2b_invalid_gas(
 
 @pytest.mark.valid_from("Istanbul")
 @pytest.mark.parametrize("call_opcode", [Op.CALL, Op.CALLCODE])
-@pytest.mark.parametrize("gas_limit", [100_000_000, 90_000, 110_000, 200_000])
+@pytest.mark.parametrize("gas_limit", [Environment().gas_limit, 90_000, 110_000, 200_000])
path: tests/istanbul/eip152_blake2/test_blake2.py
user: login: marioevz
body: @reedsa let me know what you think of this since you were the original author of the test.

The idea is that the bump occurs automatically when we bump the default in `CURRENT_MAINNET_BLOCK_GAS_LIMIT` or when we try to fill with a higher block gas limit passed as parameter.
created_at: 2025-05-03T00:46:00Z
author_association: MEMBER
diff_hunk: @@ -172,6 +173,17 @@ def pytest_addoption(parser: pytest.Parser):
         default=True,
         help="Skip generating an index file for all produced fixtures.",
     )
+    test_group.addoption(
path: src/pytest_plugins/filler/filler.py
user: login: reedsa
body: Having this in the test group feels better than on it's own 👍 Did you happen to understand why the new test group I added wasn't showing up with a unique description?
created_at: 2025-05-05T15:16:42Z
author_association: CONTRIBUTOR
diff_hunk: @@ -56,6 +56,18 @@ def pytest_addoption(parser):
             "unless overridden by the test."
         ),
     )
+    execute_group.addoption(
path: src/pytest_plugins/execute/execute.py
user: login: reedsa
body: Execution tests set the txn gas limit, is this because the tests have no control over the block gas limit on the testnet?
created_at: 2025-05-05T15:18:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -532,7 +532,7 @@ def test_blake2b_invalid_gas(
 
 @pytest.mark.valid_from("Istanbul")
 @pytest.mark.parametrize("call_opcode", [Op.CALL, Op.CALLCODE])
-@pytest.mark.parametrize("gas_limit", [100_000_000, 90_000, 110_000, 200_000])
+@pytest.mark.parametrize("gas_limit", [Environment().gas_limit, 90_000, 110_000, 200_000])
path: tests/istanbul/eip152_blake2/test_blake2.py
user: login: reedsa
body: Good idea, I think these original values are pretty arbitrary. It's great having the ability to set this in a param!
created_at: 2025-05-05T15:25:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -172,6 +173,17 @@ def pytest_addoption(parser: pytest.Parser):
         default=True,
         help="Skip generating an index file for all produced fixtures.",
     )
+    test_group.addoption(
path: src/pytest_plugins/filler/filler.py
user: login: marioevz
body: It's a bit of a mess the help in our commands 😅

We do some regex matching to see what to include and what not to include in the commands, and I think some cleanup is necessary because the current method is not ideal.
created_at: 2025-05-05T15:54:30Z
author_association: MEMBER
diff_hunk: @@ -56,6 +56,18 @@ def pytest_addoption(parser):
             "unless overridden by the test."
         ),
     )
+    execute_group.addoption(
path: src/pytest_plugins/execute/execute.py
user: login: marioevz
body: Yes, that and the fact that we normally don't have infinite eth to spare in sepolia or hoody, so we limit the amount of gas per test even further.
created_at: 2025-05-05T15:55:30Z
author_association: MEMBER
diff_hunk: @@ -532,7 +532,7 @@ def test_blake2b_invalid_gas(
 
 @pytest.mark.valid_from("Istanbul")
 @pytest.mark.parametrize("call_opcode", [Op.CALL, Op.CALLCODE])
-@pytest.mark.parametrize("gas_limit", [100_000_000, 90_000, 110_000, 200_000])
+@pytest.mark.parametrize("gas_limit", [Environment().gas_limit, 90_000, 110_000, 200_000])
path: tests/istanbul/eip152_blake2/test_blake2.py
user: login: marioevz
body: I wrote a unit test for this pattern and actually found a bug:
I was overwriting the `EnvironmentDefaults` in a fixture, but if the test uses `Environment().gas_limit` to generate its parametrization like in this example, pytest only resolves fixtures during actual test execution, so too late for this.
I modified the `EnvironmentDefaults` mod to happen during `pytest_config` which happens before collection even.
created_at: 2025-05-05T17:22:57Z
author_association: MEMBER
diff_hunk: @@ -115,82 +115,74 @@ Output:
 
 ```text
 usage: fill [-h] [--strict-alloc] [--ca-start CA_START] [--ca-incr CA_INCR]
-            [--evm-code-type EVM_CODE_TYPE] [--solc-bin SOLC_BIN]
-            [--solc-version SOLC_VERSION] [--evm-bin EVM_BIN] [--traces]
-            [--verify-fixtures] [--verify-fixtures-bin VERIFY_FIXTURES_BIN]
-            [--filler-path FILLER_PATH] [--output OUTPUT] [--flat-output]
-            [--single-fixture-per-file] [--no-html] [--strict-alloc]
-            [--ca-start CA_START] [--ca-incr CA_INCR] [--build-name BUILD_NAME]
-            [--evm-dump-dir EVM_DUMP_DIR] [--forks] [--fork FORK] [--from FROM]
-            [--until UNTIL]
+            [--evm-code-type EVM_CODE_TYPE] [--solc-bin SOLC_BIN] [--solc-version SOLC_VERSION]
+            [--evm-bin EVM_BIN] [--traces] [--verify-fixtures]
+            [--verify-fixtures-bin VERIFY_FIXTURES_BIN] [--filler-path FILLER_PATH] [--output OUTPUT]
+            [--flat-output] [--single-fixture-per-file] [--no-html] [--build-name BUILD_NAME]
+            [--skip-index SKIP_INDEX] [--block-gas-limit BLOCK_GAS_LIMIT] [--evm-dump-dir EVM_DUMP_DIR]
+            [--skip-evm-dump] [--forks] [--fork FORK] [--from FROM] [--until UNTIL]
 
 options:
   -h, --help            show this help message and exit
 
-Arguments defining pre-allocation behavior.:
-  --strict-alloc        [DEBUG ONLY] Disallows deploying a contract in a
-                        predefined address.
-  --ca-start CA_START, --contract-address-start CA_START
-                        The starting address from which tests will deploy
-                        contracts.
-  --ca-incr CA_INCR, --contract-address-increment CA_INCR
-                        The address increment value to each deployed contract by
-                        a test.
+Arguments defining pre-allocation behavior during test filling.:
+  --strict-alloc        [DEBUG ONLY] Disallows deploying a contract in a predefined address.
+  --ca-start, --contract-address-start CA_START
+                        The starting address from which tests will deploy contracts.
+  --ca-incr, --contract-address-increment CA_INCR
+                        The address increment value to each deployed contract by a test.
   --evm-code-type EVM_CODE_TYPE
                         Type of EVM code to deploy in each test by default.
 
 Arguments defining the solc executable:
-  --solc-bin SOLC_BIN   Path to a solc executable (for Yul source compilation).
-                        No default; if unspecified `--solc-version` is used.
+  --solc-bin SOLC_BIN   Path to a solc executable (for Yul source compilation). No default; if
+                        unspecified `--solc-version` is used.
   --solc-version SOLC_VERSION
                         Version of the solc compiler to use. Default: 0.8.24.
 
 Arguments defining evm executable behavior:
-  --evm-bin EVM_BIN     Path to an evm executable that provides `t8n`. Default:
-                        First 'evm' entry in PATH.
-  --traces              Collect traces of the execution information from the
-                        transition tool.
-  --verify-fixtures     Verify generated fixture JSON files using geth's evm
-                        blocktest command. By default, the same evm binary as for
-                        the t8n tool is used. A different (geth) evm binary may
-                        be specified via --verify-fixtures-bin, this must be
-                        specified if filling with a non-geth t8n tool that does
-                        not support blocktest.
+  --evm-bin EVM_BIN     Path to an evm executable (or name of an executable in the PATH) that provides
+                        `t8n`. Default: `ethereum-spec-evm-resolver`.
+  --traces              Collect traces of the execution information from the transition tool.
+  --verify-fixtures     Verify generated fixture JSON files using geth's evm blocktest command. By
+                        default, the same evm binary as for the t8n tool is used. A different (geth) evm
+                        binary may be specified via --verify-fixtures-bin, this must be specified if
+                        filling with a non-geth t8n tool that does not support blocktest.
   --verify-fixtures-bin VERIFY_FIXTURES_BIN
-                        Path to an evm executable that provides the `blocktest`
-                        command. Default: The first (geth) 'evm' entry in PATH.
+                        Path to an evm executable that provides the `blocktest` command. Default: The
+                        first (geth) 'evm' entry in PATH.
 
 Arguments defining filler location and output:
   --filler-path FILLER_PATH
                         Path to filler directives
-  --output OUTPUT       Directory path to store the generated test fixtures. If
-                        the specified path ends in '.tar.gz', then the specified
-                        tarball is additionally created (the fixtures are still
-                        written to the specified path without the '.tar.gz'
-                        suffix). Can be deleted. Default: './fixtures'.
-  --flat-output         Output each test case in the directory without the folder
-                        structure.
+  --output OUTPUT       Directory path to store the generated test fixtures. If the specified path ends
+                        in '.tar.gz', then the specified tarball is additionally created (the fixtures
+                        are still written to the specified path without the '.tar.gz' suffix). Can be
+                        deleted. Default: './fixtures'.
+  --flat-output         Output each test case in the directory without the folder structure.
   --single-fixture-per-file
-                        Don't group fixtures in JSON files by test function;
-                        write each fixture to its own file. This can be used to
-                        increase the granularity of --verify-fixtures.
-  --no-html             Don't generate an HTML test report (in the output
-                        directory). The --html flag can be used to specify a
-                        different path.
+                        Don't group fixtures in JSON files by test function; write each fixture to its
+                        own file. This can be used to increase the granularity of --verify-fixtures.
+  --no-html             Don't generate an HTML test report (in the output directory). The --html flag can
+                        be used to specify a different path.
   --build-name BUILD_NAME
-                        Specify a build name for the fixtures.ini file, e.g.,
-                        'stable'.
-  --index               Generate an index file for all produced fixtures.
+                        Specify a build name for the fixtures.ini file, e.g., 'stable'.
+  --skip-index SKIP_INDEX
+                        Skip generating an index file for all produced fixtures.
+  --block-gas-limit BLOCK_GAS_LIMIT
+                        Default gas limit used ceiling used for blocks and tests that attempt to consume
+                        an entire block's gas. (Default: 72000000)
 
 Arguments defining debug behavior:
-  --evm-dump-dir EVM_DUMP_DIR, --t8n-dump-dir EVM_DUMP_DIR
-                        Path to dump the transition tool debug output.  (Default: <repo>/logs/evm)
+  --evm-dump-dir, --t8n-dump-dir EVM_DUMP_DIR
+                        Path to dump the transition tool debug output. (Default:
+                        /Users/stu/projects/ethereum/execution-spec-tests/logs/evm)
path: docs/filling_tests/filling_tests_command_line.md
user: login: marioevz
body: ```suggestion
                        <repo>/logs/evm)
```
created_at: 2025-05-05T17:27:36Z
author_association: MEMBER
diff_hunk: @@ -418,6 +418,7 @@ stdout
 stExample
 str
 streetsidesoftware
+stu
path: whitelist.txt
user: login: marioevz
body: ```suggestion
```
created_at: 2025-05-05T17:27:49Z
author_association: MEMBER

PR comments:
user: login: reedsa
created_at: 2025-04-21T23:00:26Z
body: Are tests that use more than `30_000_000` gas expected to be set to the enormous amounts like in [this example](https://github.com/ethereum/execution-spec-tests/blob/3719e9277ca9fdaf97799b8f4084f57e977eb7e4/tests/osaka/eip7692_eof_v1/eip7873_tx_create/test_txcreate.py#L497). Some values of `50_000_000`, etc. in various osaka tests as well.

Should these values remain or should they be set to the `max_gas` value from the configurable fixture?


Another question: There are gas limits used in the execution command. Are those to remain as is for now?
author_association: CONTRIBUTOR
user: login: reedsa
created_at: 2025-04-23T15:25:10Z
body: @marioevz I like the idea of setting the gas_limit as part of the [`Environment` class](https://github.com/ethereum/execution-spec-tests/blob/3719e9277ca9fdaf97799b8f4084f57e977eb7e4/src/ethereum_test_types/types.py#L347). I assume the initial value should just use the flag value via the test fixture somehow? Perhaps a new method on the class similar to `set_fork_requirements` that is called from [`make_state_test_fixture`](https://github.com/ethereum/execution-spec-tests/blob/3719e9277ca9fdaf97799b8f4084f57e977eb7e4/src/ethereum_test_specs/state.py#L170)?

I noticed there is a default value of `100_000_000_000_000_000` for the `gas_limit`. Should that value be lowered to the default configurable value of `30_000_000` and allow overrides with the `--gas_limit` flag?

Once it is in the environment, all tests will change and I'm not certain what effect lowering the value will have. Is this the right approach?
author_association: CONTRIBUTOR
user: login: marioevz
created_at: 2025-04-23T18:36:07Z
body: > @marioevz I like the idea of setting the gas_limit as part of the [`Environment` class](https://github.com/ethereum/execution-spec-tests/blob/3719e9277ca9fdaf97799b8f4084f57e977eb7e4/src/ethereum_test_types/types.py#L347). I assume the initial value should just use the flag value via the test fixture somehow? Perhaps a new method on the class similar to `set_fork_requirements` that is called from [`make_state_test_fixture`](https://github.com/ethereum/execution-spec-tests/blob/3719e9277ca9fdaf97799b8f4084f57e977eb7e4/src/ethereum_test_specs/state.py#L170)?
> 
> I noticed there is a default value of `100_000_000_000_000_000` for the `gas_limit`. Should that value be lowered to the default configurable value of `30_000_000` and allow overrides with the `--gas_limit` flag?
> 
> Once it is in the environment, all tests will change and I'm not certain what effect lowering the value will have. Is this the right approach?

I think the default of `100_000_000_000_000_000` is way overblown, and we should be able to lower it and match it to the value we specify as the block limit, and not that many tests should fail.

Doing the environment-as-a-fixture would require some big changes, like the ones we did for the pre-as-a-fixture.
I.e. The environment changes from being something that gets instantiated by the test function (most tests just do `Environment()`) to something that is passed as a parameter and then read and potentially modified if necessary.

It might not even be necessary that the test function uses the parameter and we could simply pass it from the filler to the spec like we do for the `pre` here: https://github.com/ethereum/execution-spec-tests/blob/b48d1dc81233af6e4d6c7c84e60e8eaa4067a288/src/pytest_plugins/filler/filler.py#L717-L718

If the test function requires to know about its environment, it will be included in the test function as a parameter:
```
def test_something(pre: Alloc, env: Environment ...):
```

And the test could then:
- Read values from its environment, like the `gas_limit` and adapt the test to only use that at most. If the test uses the environment as read-only, the test can be easily filled (`uv run fill`) and executed (`uv run execute`).
- Write values to its environment, like increase the `gas_limit` to a minimum value because the test requires it as a minimum to execute its test logic, and in this case the test could be filled but not executed (because we cannot modify the environment we are running in when it's a live network).

One change I would do to the current implementation of this PR is rename `max_gas` to `block_gas_limit`.
author_association: MEMBER
user: login: reedsa
created_at: 2025-05-01T18:10:25Z
body: @marioevz Pushed up my latest changes and had some follow up questions for what we've discussed.
1. I was wondering if it would be useful to have the existing `env.gas_limit` only used for transactions and add a new `env.block_gas_limit` variable that is configurable?
2. I am looking at the pytantic models, not totally certain about where validation happens to check that the env has the `block_gas_limit` value set? So far I have: `block_gas_limit: NumberBoundTypeVar = Field(DEFAULT_BLOCK_GAS_LIMIT, alias="currentBlockGasLimit")` as an attribute of `EnvironmentGeneric` with the default set.
author_association: CONTRIBUTOR
user: login: marioevz
created_at: 2025-05-01T19:03:06Z
body: >     1. I was wondering if it would be useful to have the existing `env.gas_limit` only used for transactions and add a new `env.block_gas_limit` variable that is configurable?

I normally see `tx.gas_limit` as the limit applied to the transaction and `env.gas_limit` as the total gas limit in the environment (block) where the transaction will execute. If you set `tx.gas_limit=env.gas_limit` it should (IMO) be seen as "the tx should consume all the gas that it can from the environment where it runs".

>     2. I am looking at the pytantic models, not totally certain about where validation happens to check that the env has the `block_gas_limit` value set? So far I have: `block_gas_limit: NumberBoundTypeVar = Field(DEFAULT_BLOCK_GAS_LIMIT, alias="currentBlockGasLimit")` as an attribute of `EnvironmentGeneric` with the default set.

I don't think this validation happens anywhere at the moment, it's simply set to a default max.

As an example, we do a hacky trick to alter the defaults of a transaction by using a `TransactionDefaults` class:
https://github.com/ethereum/execution-spec-tests/blob/c35b42f3d84618e0430124b424c0f362bdbe4ab7/src/ethereum_test_types/types.py#L578-L585

And then in the `fill`/`execute` plugins we import and modify the value to the new defaults for the given execution context:
https://github.com/ethereum/execution-spec-tests/blob/c35b42f3d84618e0430124b424c0f362bdbe4ab7/src/pytest_plugins/execute/execute.py#L192-L200

Maybe this helps for environment too?

author_association: MEMBER
user: login: reedsa
created_at: 2025-05-02T16:35:14Z
body: @marioevz Is it worth removing the `env = Environment()` setup that is in many of the tests?

I also haven't updated the execute command with a default value. Is that necessary?
author_association: CONTRIBUTOR
user: login: marioevz
created_at: 2025-05-02T16:47:10Z
body: > @marioevz Is it worth removing the `env = Environment()` setup that is in many of the tests?

I was just thinking about that, it's maybe way too many tests using this pattern.

Maybe since it's simpler to just use the [EnvironmentDefaults](https://github.com/ethereum/execution-spec-tests/blob/c35b42f3d84618e0430124b424c0f362bdbe4ab7/src/pytest_plugins/execute/execute.py#L192-L200) trick in this PR and focus on the ones that directly set `Environment(gas_limit=...)`?

> I also haven't updated the execute command with a default value. Is that necessary?

If we go ahead and skip using a fixture then nothing needs to be changed for execute, but if we end up using the fixture route then we need to define it also in the execute plugin.
author_association: MEMBER
user: login: marioevz
created_at: 2025-05-02T17:00:50Z
body: Just to summarize, the two options are:
#### `env` fixture
- Tests would have to define the `env` parameter, and then pass it to `state_test`.
- Basically all state tests are affected

#### `EnvironmentDefaults`
- Only tests that modify gas limit would be affected, and they would need to do:
```python
env = Environment()
...
tx.gas_limit = env.gas_limit  # <- env.gas_limit here automatically contains the --block-max-gas value
```
- We could detect tests that go over this limit by checking `tx.gas_limit > Environment().gas_limit`, but for fill it's irrelevant, and we might only need to check this for execute.

author_association: MEMBER
user: login: reedsa
created_at: 2025-05-02T17:21:46Z
body: I'm fine with using the `EnvironmentFixture` instead of the fixture. I'll update that shortly!
author_association: CONTRIBUTOR
user: login: reedsa
created_at: 2025-05-02T20:08:14Z
body: @marioevz I'm not seeing the flag in the help section when I put in the correct description for the flag group `parser.getgroup("env", "Arguments defining the environment")`. The flag had worked prior when I had it using the same description as the debug group. 😕 

With the `EnvironmentDefaults` approach I am not sure if that's preventing the limit flag from propogating into the fill tests. Maybe I'm missing something or confused about how the flag should work without using a fixture.
author_association: CONTRIBUTOR
user: login: marioevz
created_at: 2025-05-02T21:53:12Z
body: > @marioevz I'm not seeing the flag in the help section when I put in the correct description for the flag group `parser.getgroup("env", "Arguments defining the environment")`. The flag had worked prior when I had it using the same description as the debug group. 😕
> 
> With the `EnvironmentDefaults` approach I am not sure if that's preventing the limit flag from propogating into the fill tests. Maybe I'm missing something or confused about how the flag should work without using a fixture.

Have an idea on how to fix it: I think we should move the flag to the `shared` plugin.

I'll push a commit in a bit 👍 
author_association: MEMBER
user: login: marioevz
created_at: 2025-05-03T00:51:53Z
body: @reedsa Added the changes and it seems to be working now.

The nice thing is that with this change, since the default for `Environment.gas_limit` was drastically reduced, tests that were using excessive gas started failing, and I took the opportunity and reduced the gas limit of many tests where it was unnecessary.

Let me know what you think of the changes.
author_association: MEMBER