Skip to content

Commit 0c6f531

Browse files
reedsamarioevz
andauthored
feat(plugins,tests): Add flag to configure max_gas for fill command (#1470)
* Add flag to configure `max_gas` for fill command Add fixture for `max_gas` with default of 30_000_000 * Warnings for blockchain and state tests using gas_limit >= 30_000_000 * Set gas_limit from fixture for fill command * Update CHANGELOG Update fill command output in docs * Add env fixture to pytest fill plugin and pass Environment to state tests directly * Updates for using EnvironmentDefaults * refactor(plugins/shared): Move block gas limit flag to shared * refactor(tests): test fixes * fix(specs): Unit tests * fix(specs): More unit tests * fix(types): Change semantics of max block gas limit * refactor(plugins): Use different max gas defaults for execute/fill * revert(pytest.ini): Remove filler.env * fix(tests): Reduce amount of excessive-gas-usage tests * fix(types): Fix unit tests take 3 * fix(tests): Mark tests timing out as slow * Update docs for max gas flag * fix(plugins): Move environment defaults modification in pytest_config * fix tox * Apply suggestions from code review --------- Co-authored-by: Mario Vega <[email protected]>
1 parent 624f60b commit 0c6f531

File tree

23 files changed

+339
-151
lines changed

23 files changed

+339
-151
lines changed

docs/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ This feature can be disabled by using `--disable-strict-exception-matching` for
8181
- ✨ 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)).
8282
- ✨ 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)).
8383
- 🐞 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)).
84+
- ✨ 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)).
8485

8586
#### `consume`
8687

docs/filling_tests/filling_tests_command_line.md

+43-51
Original file line numberDiff line numberDiff line change
@@ -115,82 +115,74 @@ Output:
115115

116116
```text
117117
usage: fill [-h] [--strict-alloc] [--ca-start CA_START] [--ca-incr CA_INCR]
118-
[--evm-code-type EVM_CODE_TYPE] [--solc-bin SOLC_BIN]
119-
[--solc-version SOLC_VERSION] [--evm-bin EVM_BIN] [--traces]
120-
[--verify-fixtures] [--verify-fixtures-bin VERIFY_FIXTURES_BIN]
121-
[--filler-path FILLER_PATH] [--output OUTPUT] [--flat-output]
122-
[--single-fixture-per-file] [--no-html] [--strict-alloc]
123-
[--ca-start CA_START] [--ca-incr CA_INCR] [--build-name BUILD_NAME]
124-
[--evm-dump-dir EVM_DUMP_DIR] [--forks] [--fork FORK] [--from FROM]
125-
[--until UNTIL]
118+
[--evm-code-type EVM_CODE_TYPE] [--solc-bin SOLC_BIN] [--solc-version SOLC_VERSION]
119+
[--evm-bin EVM_BIN] [--traces] [--verify-fixtures]
120+
[--verify-fixtures-bin VERIFY_FIXTURES_BIN] [--filler-path FILLER_PATH] [--output OUTPUT]
121+
[--flat-output] [--single-fixture-per-file] [--no-html] [--build-name BUILD_NAME]
122+
[--skip-index SKIP_INDEX] [--block-gas-limit BLOCK_GAS_LIMIT] [--evm-dump-dir EVM_DUMP_DIR]
123+
[--skip-evm-dump] [--forks] [--fork FORK] [--from FROM] [--until UNTIL]
126124
127125
options:
128126
-h, --help show this help message and exit
129127
130-
Arguments defining pre-allocation behavior.:
131-
--strict-alloc [DEBUG ONLY] Disallows deploying a contract in a
132-
predefined address.
133-
--ca-start CA_START, --contract-address-start CA_START
134-
The starting address from which tests will deploy
135-
contracts.
136-
--ca-incr CA_INCR, --contract-address-increment CA_INCR
137-
The address increment value to each deployed contract by
138-
a test.
128+
Arguments defining pre-allocation behavior during test filling.:
129+
--strict-alloc [DEBUG ONLY] Disallows deploying a contract in a predefined address.
130+
--ca-start, --contract-address-start CA_START
131+
The starting address from which tests will deploy contracts.
132+
--ca-incr, --contract-address-increment CA_INCR
133+
The address increment value to each deployed contract by a test.
139134
--evm-code-type EVM_CODE_TYPE
140135
Type of EVM code to deploy in each test by default.
141136
142137
Arguments defining the solc executable:
143-
--solc-bin SOLC_BIN Path to a solc executable (for Yul source compilation).
144-
No default; if unspecified `--solc-version` is used.
138+
--solc-bin SOLC_BIN Path to a solc executable (for Yul source compilation). No default; if
139+
unspecified `--solc-version` is used.
145140
--solc-version SOLC_VERSION
146141
Version of the solc compiler to use. Default: 0.8.24.
147142
148143
Arguments defining evm executable behavior:
149-
--evm-bin EVM_BIN Path to an evm executable that provides `t8n`. Default:
150-
First 'evm' entry in PATH.
151-
--traces Collect traces of the execution information from the
152-
transition tool.
153-
--verify-fixtures Verify generated fixture JSON files using geth's evm
154-
blocktest command. By default, the same evm binary as for
155-
the t8n tool is used. A different (geth) evm binary may
156-
be specified via --verify-fixtures-bin, this must be
157-
specified if filling with a non-geth t8n tool that does
158-
not support blocktest.
144+
--evm-bin EVM_BIN Path to an evm executable (or name of an executable in the PATH) that provides
145+
`t8n`. Default: `ethereum-spec-evm-resolver`.
146+
--traces Collect traces of the execution information from the transition tool.
147+
--verify-fixtures Verify generated fixture JSON files using geth's evm blocktest command. By
148+
default, the same evm binary as for the t8n tool is used. A different (geth) evm
149+
binary may be specified via --verify-fixtures-bin, this must be specified if
150+
filling with a non-geth t8n tool that does not support blocktest.
159151
--verify-fixtures-bin VERIFY_FIXTURES_BIN
160-
Path to an evm executable that provides the `blocktest`
161-
command. Default: The first (geth) 'evm' entry in PATH.
152+
Path to an evm executable that provides the `blocktest` command. Default: The
153+
first (geth) 'evm' entry in PATH.
162154
163155
Arguments defining filler location and output:
164156
--filler-path FILLER_PATH
165157
Path to filler directives
166-
--output OUTPUT Directory path to store the generated test fixtures. If
167-
the specified path ends in '.tar.gz', then the specified
168-
tarball is additionally created (the fixtures are still
169-
written to the specified path without the '.tar.gz'
170-
suffix). Can be deleted. Default: './fixtures'.
171-
--flat-output Output each test case in the directory without the folder
172-
structure.
158+
--output OUTPUT Directory path to store the generated test fixtures. If the specified path ends
159+
in '.tar.gz', then the specified tarball is additionally created (the fixtures
160+
are still written to the specified path without the '.tar.gz' suffix). Can be
161+
deleted. Default: './fixtures'.
162+
--flat-output Output each test case in the directory without the folder structure.
173163
--single-fixture-per-file
174-
Don't group fixtures in JSON files by test function;
175-
write each fixture to its own file. This can be used to
176-
increase the granularity of --verify-fixtures.
177-
--no-html Don't generate an HTML test report (in the output
178-
directory). The --html flag can be used to specify a
179-
different path.
164+
Don't group fixtures in JSON files by test function; write each fixture to its
165+
own file. This can be used to increase the granularity of --verify-fixtures.
166+
--no-html Don't generate an HTML test report (in the output directory). The --html flag can
167+
be used to specify a different path.
180168
--build-name BUILD_NAME
181-
Specify a build name for the fixtures.ini file, e.g.,
182-
'stable'.
183-
--index Generate an index file for all produced fixtures.
169+
Specify a build name for the fixtures.ini file, e.g., 'stable'.
170+
--skip-index SKIP_INDEX
171+
Skip generating an index file for all produced fixtures.
172+
--block-gas-limit BLOCK_GAS_LIMIT
173+
Default gas limit used ceiling used for blocks and tests that attempt to consume
174+
an entire block's gas. (Default: 72000000)
184175
185176
Arguments defining debug behavior:
186-
--evm-dump-dir EVM_DUMP_DIR, --t8n-dump-dir EVM_DUMP_DIR
187-
Path to dump the transition tool debug output. (Default: <repo>/logs/evm)
177+
--evm-dump-dir, --t8n-dump-dir EVM_DUMP_DIR
178+
Path to dump the transition tool debug output. (Default:
179+
<repo>/logs/evm)
180+
--skip-evm-dump, --skip-t8n-dump
181+
Skip dumping the the transition tool debug output.
188182
189183
Specify the fork range to generate fixtures for:
190184
--forks Display forks supported by the test framework and exit.
191185
--fork FORK Only fill tests for the specified fork.
192186
--from FROM Fill tests from and including the specified fork.
193187
--until UNTIL Fill tests until and including the specified fork.
194-
195-
Exit: After displaying help.
196188
```

src/ethereum_test_specs/blockchain.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Ethereum blockchain test spec definition and filler."""
22

3+
import warnings
34
from pprint import pprint
45
from typing import Any, Callable, ClassVar, Dict, Generator, List, Optional, Sequence, Tuple, Type
56

@@ -409,7 +410,15 @@ def generate_block_data(
409410
env = block.set_environment(previous_env)
410411
env = env.set_fork_requirements(fork)
411412

412-
txs = [tx.with_signature_and_sender() for tx in block.txs]
413+
txs: List[Transaction] = []
414+
for tx in block.txs:
415+
if not self.is_slow_test() and tx.gas_limit >= Environment().gas_limit:
416+
warnings.warn(
417+
f"{self.node_id()} uses a high Transaction gas_limit: {tx.gas_limit}",
418+
stacklevel=2,
419+
)
420+
421+
txs.append(tx.with_signature_and_sender())
413422

414423
if failing_tx_count := len([tx for tx in txs if tx.error]) > 0:
415424
if failing_tx_count > 1:

src/ethereum_test_specs/state.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Ethereum state test spec definition and filler."""
22

3+
import warnings
34
from pprint import pprint
45
from typing import Any, Callable, ClassVar, Dict, Generator, List, Optional, Sequence, Type
56

@@ -169,6 +170,11 @@ def make_state_test_fixture(
169170

170171
env = self.env.set_fork_requirements(fork)
171172
tx = self.tx.with_signature_and_sender(keep_secret_key=True)
173+
if not self.is_slow_test() and tx.gas_limit >= Environment().gas_limit:
174+
warnings.warn(
175+
f"{self.node_id()} uses a high Transaction gas_limit: {tx.gas_limit}",
176+
stacklevel=2,
177+
)
172178
pre_alloc = Alloc.merge(
173179
Alloc.model_validate(fork.pre_allocation()),
174180
self.pre,

src/ethereum_test_specs/tests/test_fixtures.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def test_check_helper_fixtures():
6868
],
6969
)
7070
def test_make_genesis(fork: Fork, fixture_hash: bytes, default_t8n: TransitionTool): # noqa: D103
71-
env = Environment()
71+
env = Environment(gas_limit=100_000_000_000_000_000)
7272

7373
pre = Alloc(
7474
{
@@ -479,6 +479,7 @@ def post(self): # noqa: D102
479479
@pytest.fixture
480480
def genesis_environment(self): # noqa: D102
481481
return Environment(
482+
gas_limit=100_000_000_000_000_000,
482483
base_fee_per_gas=1000,
483484
fee_recipient="0xba5e000000000000000000000000000000000000",
484485
)
@@ -869,6 +870,7 @@ def test_fill_blockchain_invalid_txs(
869870

870871
# We start genesis with a baseFee of 1000
871872
genesis_environment = Environment(
873+
gas_limit=100_000_000_000_000_000,
872874
base_fee_per_gas=1000,
873875
fee_recipient="0xba5e000000000000000000000000000000000000",
874876
)

src/ethereum_test_types/__init__.py

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
ConsolidationRequest,
1818
DepositRequest,
1919
Environment,
20+
EnvironmentDefaults,
2021
NetworkWrappedTransaction,
2122
Removable,
2223
Requests,
@@ -38,6 +39,7 @@
3839
"DepositRequest",
3940
"EmptyTrieRoot",
4041
"Environment",
42+
"EnvironmentDefaults",
4143
"EOA",
4244
"Hash",
4345
"HeaderNonce",

src/ethereum_test_types/tests/test_types.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@
44

55
import pytest
66

7-
from ethereum_test_base_types import AccessList, Address, Bytes, TestPrivateKey, to_json
7+
from ethereum_test_base_types import (
8+
AccessList,
9+
Address,
10+
Bytes,
11+
TestPrivateKey,
12+
ZeroPaddedHexNumber,
13+
to_json,
14+
)
815
from ethereum_test_base_types.pydantic import CopyValidateModel
916

1017
from ..types import (
@@ -451,7 +458,7 @@ def test_account_merge(
451458
Environment(),
452459
{
453460
"currentCoinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
454-
"currentGasLimit": "0x016345785d8a0000",
461+
"currentGasLimit": str(ZeroPaddedHexNumber(Environment().gas_limit)),
455462
"currentNumber": "0x01",
456463
"currentTimestamp": "0x03e8",
457464
"blockHashes": {},
@@ -484,7 +491,7 @@ def test_account_merge(
484491
),
485492
{
486493
"currentCoinbase": "0x0000000000000000000000000000000000001234",
487-
"currentGasLimit": "0x016345785d8a0000",
494+
"currentGasLimit": str(ZeroPaddedHexNumber(Environment().gas_limit)),
488495
"currentNumber": "0x01",
489496
"currentTimestamp": "0x03e8",
490497
"currentDifficulty": "0x05",

src/ethereum_test_types/types.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,18 @@ class Withdrawal(WithdrawalGeneric[HexNumber]):
344344

345345

346346
DEFAULT_BASE_FEE = 7
347+
CURRENT_MAINNET_BLOCK_GAS_LIMIT = 36_000_000
348+
DEFAULT_BLOCK_GAS_LIMIT = CURRENT_MAINNET_BLOCK_GAS_LIMIT * 2
349+
350+
351+
@dataclass
352+
class EnvironmentDefaults:
353+
"""Default environment values."""
354+
355+
# By default, the constant `DEFAULT_BLOCK_GAS_LIMIT` is used.
356+
# Other libraries (pytest plugins) may override this value by modifying the
357+
# `EnvironmentDefaults.gas_limit` class attribute.
358+
gas_limit: int = DEFAULT_BLOCK_GAS_LIMIT
347359

348360

349361
class EnvironmentGeneric(CamelModel, Generic[NumberBoundTypeVar]):
@@ -353,7 +365,9 @@ class EnvironmentGeneric(CamelModel, Generic[NumberBoundTypeVar]):
353365
Address("0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"),
354366
alias="currentCoinbase",
355367
)
356-
gas_limit: NumberBoundTypeVar = Field(100_000_000_000_000_000, alias="currentGasLimit") # type: ignore
368+
gas_limit: NumberBoundTypeVar = Field(
369+
default_factory=lambda: EnvironmentDefaults.gas_limit, alias="currentGasLimit"
370+
) # type: ignore
357371
number: NumberBoundTypeVar = Field(1, alias="currentNumber") # type: ignore
358372
timestamp: NumberBoundTypeVar = Field(1_000, alias="currentTimestamp") # type: ignore
359373
prev_randao: NumberBoundTypeVar | None = Field(None, alias="currentRandom")

src/pytest_plugins/execute/execute.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from ethereum_test_forks import Fork
1212
from ethereum_test_rpc import EthRPC
1313
from ethereum_test_tools import SPEC_TYPES, BaseTest
14-
from ethereum_test_types import TransactionDefaults
14+
from ethereum_test_types import EnvironmentDefaults, TransactionDefaults
1515
from pytest_plugins.spec_version_checker.spec_version_checker import EIPSpecTestItem
1616

1717
from ..shared.helpers import get_spec_format_for_item, labeled_format_parameter_set
@@ -56,6 +56,18 @@ def pytest_addoption(parser):
5656
"unless overridden by the test."
5757
),
5858
)
59+
execute_group.addoption(
60+
"--transaction-gas-limit",
61+
action="store",
62+
dest="transaction_gas_limit",
63+
default=EnvironmentDefaults.gas_limit // 4,
64+
type=int,
65+
help=(
66+
"Maximum gas used to execute a single transaction. "
67+
"Will be used as ceiling for tests that attempt to consume the entire block gas limit."
68+
f"(Default: {EnvironmentDefaults.gas_limit // 4})"
69+
),
70+
)
5971

6072
report_group = parser.getgroup("tests", "Arguments defining html report behavior")
6173
report_group.addoption(
@@ -86,6 +98,9 @@ def pytest_configure(config):
8698
called before the pytest-html plugin's pytest_configure to ensure that
8799
it uses the modified `htmlpath` option.
88100
"""
101+
# Modify the block gas limit if specified.
102+
if config.getoption("transaction_gas_limit"):
103+
EnvironmentDefaults.gas_limit = config.getoption("transaction_gas_limit")
89104
if config.option.collectonly:
90105
return
91106
if config.getoption("disable_html") and config.getoption("htmlpath") is None:

src/pytest_plugins/filler/filler.py

+15
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
generate_github_url,
3232
get_current_commit_hash_or_tag,
3333
)
34+
from ethereum_test_types import EnvironmentDefaults
3435

3536
from ..shared.helpers import get_spec_format_for_item, labeled_format_parameter_set
3637

@@ -172,6 +173,17 @@ def pytest_addoption(parser: pytest.Parser):
172173
default=True,
173174
help="Skip generating an index file for all produced fixtures.",
174175
)
176+
test_group.addoption(
177+
"--block-gas-limit",
178+
action="store",
179+
dest="block_gas_limit",
180+
default=EnvironmentDefaults.gas_limit,
181+
type=int,
182+
help=(
183+
"Default gas limit used ceiling used for blocks and tests that attempt to "
184+
f"consume an entire block's gas. (Default: {EnvironmentDefaults.gas_limit})"
185+
),
186+
)
175187

176188
debug_group = parser.getgroup("debug", "Arguments defining debug behavior")
177189
debug_group.addoption(
@@ -211,6 +223,9 @@ def pytest_configure(config):
211223
called before the pytest-html plugin's pytest_configure to ensure that
212224
it uses the modified `htmlpath` option.
213225
"""
226+
# Modify the block gas limit if specified.
227+
if config.getoption("block_gas_limit"):
228+
EnvironmentDefaults.gas_limit = config.getoption("block_gas_limit")
214229
if config.option.collectonly:
215230
return
216231
if not config.getoption("disable_html") and config.getoption("htmlpath") is None:

0 commit comments

Comments
 (0)