Skip to content

Commit bdd29dd

Browse files
spencer-tbmarioevz
andauthored
feat(consume): add consume engine hive simulator (#691)
* feat(consume): add consume engine to the framework. * feat(consume): engine hack for errors. * fix(spec): Add last_block_hash to hive blockchain fixture * fix(fw): tests * fix(fw): Consume/RPC typing * feat(consume): refactor the consume pytest plugin. * chore: add tox fixes for framework. * refactor(plugins): move common fixtures into `consume/hive_simulators/conftest.py` * feat(consume): small refactor, timing for engine. * chore(consume): update to latest hive.py * feat(consume): only use one ini file, hive.py fix. * docs: add changelog. --------- Co-authored-by: Mario Vega <[email protected]>
1 parent 832ab75 commit bdd29dd

39 files changed

+1323
-569
lines changed

docs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Test fixtures for use by clients are available for each release on the [Github r
5252
- 🔀 Refactor `gentest` to use `ethereum_test_tools.rpc.rpc` by adding to `get_transaction_by_hash`, `debug_trace_call` to `EthRPC` ([#568](https://github.com/ethereum/execution-spec-tests/pull/568)).
5353
- ✨ Write a properties file to the output directory and enable direct generation of a fixture tarball from `fill` via `--output=fixtures.tgz`([#627](https://github.com/ethereum/execution-spec-tests/pull/627)).
5454
- 🔀 `ethereum_test_tools` library has been split into multiple libraries ([#645](https://github.com/ethereum/execution-spec-tests/pull/645)).
55+
- ✨ Add the consume engine simulator and refactor the consume simulator suite. ([#691](https://github.com/ethereum/execution-spec-tests/pull/691)).
5556

5657
### 🔧 EVM Tools
5758

pytest-consume.ini

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[pytest]
2+
console_output_style = count
3+
minversion = 7.0
4+
python_files = test_*
5+
addopts =
6+
-rxXs
7+
--tb short
8+
-p pytest_plugins.consume.consume
9+
-p pytest_plugins.test_help.test_help

pytest-framework.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ testpaths =
77
src
88
addopts =
99
-p pytester
10-
--ignore=src/pytest_plugins/test_filler/test_filler.py
10+
--ignore=src/pytest_plugins/test_filler/test_filler.py
11+
--ignore=src/pytest_plugins/consume/direct/test_direct.py
12+
--ignore=src/pytest_plugins/consume/hive_simulators/engine/test_via_engine.py
13+
--ignore=src/pytest_plugins/consume/hive_simulators/rlp/test_via_rlp.py

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ python_requires = >=3.10
3131
install_requires =
3232
click>=8.1.0,<9
3333
ethereum@git+https://github.com/ethereum/execution-specs
34-
hive.py@git+https://github.com/danceratopz/hive.py@chore/setup.cfg/move-mypy-deps-to-lint-extras
34+
hive.py@git+https://github.com/marioevz/hive.py
3535
setuptools
3636
types-setuptools
3737
gitpython>=3.1.31,<4

src/cli/gen_index.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""
22
Generate an index file of all the json fixtures in the specified directory.
33
"""
4+
45
import datetime
56
import json
67
import os
@@ -179,8 +180,6 @@ def generate_fixtures_index(
179180
for file in input_path.rglob("*.json"):
180181
if file.name == "index.json":
181182
continue
182-
if "blockchain_tests_hive" in file.parts:
183-
continue
184183
if any(fixture in str(file) for fixture in fixtures_to_skip):
185184
rich.print(f"Skipping '{file}'")
186185
continue

src/cli/gentest.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
import click
6161

6262
from ethereum_test_base_types import Account, Address, ZeroPaddedHexNumber
63-
from ethereum_test_tools.rpc.rpc import BlockNumberType, EthRPC
63+
from ethereum_test_tools.rpc import BlockNumberType, DebugRPC, EthRPC
6464
from ethereum_test_types import Transaction
6565

6666

@@ -289,6 +289,7 @@ def __init__(self, node_config: Config.RemoteNode):
289289
"CF-Access-Client-Secret": node_config.secret,
290290
}
291291
self.rpc = EthRPC(node_config.node_url, extra_headers=headers)
292+
self.debug_rpc = DebugRPC(node_config.node_url, extra_headers=headers)
292293

293294
def eth_get_transaction_by_hash(self, transaction_hash: str) -> RemoteTransaction:
294295
"""
@@ -337,7 +338,7 @@ def debug_trace_call(self, tr: RemoteTransaction) -> Dict[Address, Account]:
337338
"""
338339
Get pre-state required for transaction
339340
"""
340-
return self.rpc.debug_trace_call(
341+
return self.debug_rpc.trace_call(
341342
{
342343
"from": f"{str(tr.transaction.sender)}",
343344
"to": f"{str(tr.transaction.to)}",

src/cli/pytest_commands.py

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import os
3838
import sys
3939
import warnings
40-
from typing import Any, Callable, List, Literal
40+
from typing import Any, Callable, List, Literal, get_args
4141

4242
import click
4343
import pytest
@@ -166,14 +166,25 @@ def get_hive_flags_from_env():
166166
return pytest_args
167167

168168

169-
ConsumeCommands = Literal["dirct", "rlp", "engine", "all"]
169+
ConsumeCommands = Literal["direct", "rlp", "engine"]
170170

171171

172-
def consume_ini_path(consume_command: ConsumeCommands) -> str:
172+
def consume_test_paths(consume_command: ConsumeCommands) -> str:
173173
"""
174-
Get the path to the ini file for the specified consume command.
174+
Get the test path for the specified consume command.
175175
"""
176-
return f"src/pytest_plugins/consume/ini_files/pytest-consume-{consume_command}.ini"
176+
consume_path = "src/pytest_plugins/consume"
177+
if consume_command == "direct":
178+
return f"{consume_path}/{consume_command}/test_{consume_command}.py"
179+
else: # rlp or engine
180+
return f"{consume_path}/hive_simulators/{consume_command}/test_via_{consume_command}.py"
181+
182+
183+
def all_consume_test_paths() -> list:
184+
"""
185+
Get all test paths within the consume suite.
186+
"""
187+
return [consume_test_paths(command) for command in get_args(ConsumeCommands)]
177188

178189

179190
@click.group()
@@ -191,7 +202,7 @@ def consume_direct(pytest_args, help_flag, pytest_help_flag):
191202
Clients consume directly via the `blocktest` interface.
192203
"""
193204
args = handle_help_flags(pytest_args, help_flag, pytest_help_flag)
194-
args += ["-c", consume_ini_path("direct"), "--rootdir", "./"]
205+
args += ["-c", "pytest-consume.ini", "--rootdir", "./", consume_test_paths("direct")]
195206
if not sys.stdin.isatty(): # the command is receiving input on stdin
196207
args.extend(["-s", "--input=stdin"])
197208
pytest.main(args)
@@ -204,7 +215,15 @@ def consume_via_rlp(pytest_args, help_flag, pytest_help_flag):
204215
Clients consume RLP-encoded blocks on startup.
205216
"""
206217
args = handle_help_flags(pytest_args, help_flag, pytest_help_flag)
207-
args += ["-c", consume_ini_path("rlp"), "--rootdir", "./"]
218+
args += [
219+
"-c",
220+
"pytest-consume.ini",
221+
"--rootdir",
222+
"./",
223+
consume_test_paths("rlp"),
224+
"-p",
225+
"pytest_plugins.pytest_hive.pytest_hive",
226+
]
208227
args += get_hive_flags_from_env()
209228
if not sys.stdin.isatty(): # the command is receiving input on stdin
210229
args.extend(["-s", "--input=stdin"])
@@ -218,7 +237,15 @@ def consume_via_engine_api(pytest_args, help_flag, pytest_help_flag):
218237
Clients consume via the Engine API.
219238
"""
220239
args = handle_help_flags(pytest_args, help_flag, pytest_help_flag)
221-
args += ["-c", consume_ini_path("engine"), "--rootdir", "./"]
240+
args += [
241+
"-c",
242+
"pytest-consume.ini",
243+
"--rootdir",
244+
"./",
245+
consume_test_paths("engine"),
246+
"-p",
247+
"pytest_plugins.pytest_hive.pytest_hive",
248+
]
222249
args += get_hive_flags_from_env()
223250
if not sys.stdin.isatty(): # the command is receiving input on stdin
224251
args.extend(["-s", "--input=stdin"])
@@ -232,7 +259,14 @@ def consume_all(pytest_args, help_flag, pytest_help_flag):
232259
Clients consume via all available methods (direct, rlp, engine).
233260
"""
234261
args = handle_help_flags(pytest_args, help_flag, pytest_help_flag)
235-
args += ["-c", consume_ini_path("all"), "--rootdir", "./"]
262+
args += [
263+
"-c",
264+
"pytest-consume.ini",
265+
"--rootdir",
266+
"./",
267+
"-p",
268+
"pytest_plugins.pytest_hive.pytest_hive",
269+
] + all_consume_test_paths()
236270
args += get_hive_flags_from_env()
237271
if not sys.stdin.isatty(): # the command is receiving input on stdin
238272
args.extend(["-s", "--input=stdin"])

src/ethereum_test_fixtures/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from .base import BaseFixture
88
from .blockchain import Fixture as BlockchainFixture
9+
from .blockchain import FixtureCommon as BlockchainFixtureCommon
910
from .blockchain import HiveFixture as BlockchainHiveFixture
1011
from .collector import FixtureCollector, TestInfo
1112
from .eof import Fixture as EOFFixture
@@ -23,6 +24,7 @@
2324
"FIXTURE_TYPES",
2425
"BaseFixture",
2526
"BlockchainFixture",
27+
"BlockchainFixtureCommon",
2628
"BlockchainHiveFixture",
2729
"EOFFixture",
2830
"FixtureCollector",

src/ethereum_test_fixtures/blockchain.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
Number,
2424
ZeroPaddedHexNumber,
2525
)
26+
from ethereum_test_base_types.json import to_json
2627
from ethereum_test_exceptions import EngineAPIError, ExceptionInstanceOrList
2728
from ethereum_test_forks import Fork
2829
from ethereum_test_types.types import (
@@ -255,6 +256,23 @@ class FixtureEngineNewPayload(CamelModel):
255256
| None
256257
) = None
257258

259+
def args(self) -> List[Any]:
260+
"""
261+
Returns the arguments to be used when calling the Engine API.
262+
"""
263+
args: List[Any] = [to_json(self.execution_payload)]
264+
if self.blob_versioned_hashes is not None:
265+
args.append([str(versioned_hash) for versioned_hash in self.blob_versioned_hashes])
266+
if self.parent_beacon_block_root is not None:
267+
args.append(str(self.parent_beacon_block_root))
268+
return args
269+
270+
def valid(self) -> bool:
271+
"""
272+
Returns whether the payload is valid.
273+
"""
274+
return self.validation_error is None
275+
258276
@classmethod
259277
def from_fixture_header(
260278
cls,
@@ -420,6 +438,7 @@ class FixtureCommon(BaseFixture):
420438
genesis: FixtureHeader = Field(..., alias="genesisBlockHeader")
421439
pre: Alloc
422440
post_state: Optional[Alloc] = Field(None)
441+
last_block_hash: Hash = Field(..., alias="lastblockhash") # FIXME: lastBlockHash
423442

424443
def get_fork(self) -> str:
425444
"""
@@ -435,7 +454,6 @@ class Fixture(FixtureCommon):
435454

436455
genesis_rlp: Bytes = Field(..., alias="genesisRLP")
437456
blocks: List[FixtureBlock | InvalidFixtureBlock]
438-
last_block_hash: Hash = Field(..., alias="lastblockhash")
439457
seal_engine: Literal["NoProof"] = Field("NoProof")
440458

441459
format: ClassVar[FixtureFormats] = FixtureFormats.BLOCKCHAIN_TEST

src/ethereum_test_specs/blockchain.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,7 @@ def make_hive_fixture(
698698
pre=pre,
699699
post_state=alloc,
700700
sync_payload=sync_payload,
701+
last_block_hash=head_hash,
701702
)
702703

703704
def generate(

0 commit comments

Comments
 (0)