diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index eae0a372b5..5ce2d564ea 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -21,6 +21,7 @@ Test fixtures for use by clients are available for each release on the [Github r - ✨ `Opcodes` enum now contains docstrings with each opcode description, including parameters and return values, which show up in many development environments ([#424](https://github.com/ethereum/execution-spec-tests/pull/424)) @ThreeHrSleep. - 🔀 Locally calculate state root for the genesis blocks in the blockchain tests instead of calling t8n ([#450](https://github.com/ethereum/execution-spec-tests/pull/450)). - 🐞 Fix bug that causes an exception during test collection because the fork parameter contains `None` ([#452](https://github.com/ethereum/execution-spec-tests/pull/452)). +- ✨ The `_info` field in the test fixtures now contains a `hash` field, which is the hash of the test fixture, and a `hasher` script has been added which prints and performs calculations on top of the hashes of all fixtures (see `hasher -h`) ([#454](https://github.com/ethereum/execution-spec-tests/pull/454)). ### 🔧 EVM Tools diff --git a/docs/writing_tests/verifying_changes.md b/docs/writing_tests/verifying_changes.md index 0c62a0d8b6..04dd7ae6a3 100644 --- a/docs/writing_tests/verifying_changes.md +++ b/docs/writing_tests/verifying_changes.md @@ -88,3 +88,38 @@ Verify: ```console tox -e docs ``` + +### Verifying Fixture Changes + +When writing a PR that modifies either the framework or test cases, it is important to verify that the changes do not cause any issues with the existing test cases. + +All filled fixtures contain a `hash` field in the `_info` object, which is the hash of the json string of the fixture. This hash can be used to verify that the fixture has not changed. + +The `hasher` command can be used to bulk-verify the hashes of all fixtures in a directory. + +It has the following options: + +| Flag | Description | +|--------------|-------------| +| `--files` / `-f` | Prints a single combined hash per each JSON fixture file recursively contained in a directory. | +| `--tests` / `-t` | Prints the hash of every single test vector in every JSON fixture file recursively contained in a directory. | +| `--root` / `-r` | Prints a single combined hash for all JSON fixture files recursively contained in a directory. | + +For a quick comparison between two fixture directories, the `--root` option can be used and if the output matches, it means the fixtures in the directories are identical: + +```console +hasher --root fixtures/ +hasher --root fixtures_new/ +``` + +If the output does not match, the `--files` option can be used to identify which files are different: + +```console +diff <(hasher --files fixtures/) <(hasher --files fixtures_new/) +``` + +And the `--tests` option can be used for an even more granular comparison: + +```console +diff <(hasher --tests fixtures/) <(hasher --tests fixtures_new/) +``` diff --git a/setup.cfg b/setup.cfg index 1ba8bde67a..b4e34369bb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -51,6 +51,7 @@ console_scripts = markdownlintcli2_soft_fail = entry_points.markdownlintcli2_soft_fail:main create_whitelist_for_flake8_spelling = entry_points.create_whitelist_for_flake8_spelling:main evm_bytes_to_python = entry_points.evm_bytes_to_python:main + hasher = entry_points.hasher:main [options.extras_require] test = diff --git a/src/entry_points/hasher.py b/src/entry_points/hasher.py new file mode 100644 index 0000000000..54030357a7 --- /dev/null +++ b/src/entry_points/hasher.py @@ -0,0 +1,135 @@ +""" +Simple CLI tool to hash a directory of JSON fixtures. +""" + +import argparse +import hashlib +import json +from dataclasses import dataclass, field +from enum import IntEnum, auto +from pathlib import Path +from typing import Dict, List, Optional + + +class HashableItemType(IntEnum): + """ + Represents the type of a hashable item. + """ + + FOLDER = 0 + FILE = auto() + TEST = auto() + + +@dataclass(kw_only=True) +class HashableItem: + """ + Represents an item that can be hashed containing other items that can be hashed as well. + """ + + type: HashableItemType + parents: List[str] = field(default_factory=list) + root: Optional[bytes] = None + items: Optional[Dict[str, "HashableItem"]] = None + + def hash(self) -> bytes: + """ + Return the hash of the item. + """ + if self.root is not None: + return self.root + if self.items is None: + raise ValueError("No items to hash") + all_hash_bytes = b"" + for _, item in sorted(self.items.items()): + item_hash_bytes = item.hash() + all_hash_bytes += item_hash_bytes + return hashlib.sha256(all_hash_bytes).digest() + + def print( + self, *, name: str, level: int = 0, print_type: Optional[HashableItemType] = None + ) -> None: + """ + Print the hash of the item and sub-items. + """ + next_level = level + print_name = name + if level == 0 and self.parents: + separator = "::" if self.type == HashableItemType.TEST else "/" + print_name = f"{'/'.join(self.parents)}{separator}{name}" + if print_type is None or self.type >= print_type: + next_level += 1 + print(f"{' ' * level}{print_name}: 0x{self.hash().hex()}") + + if self.items is not None: + for key, item in sorted(self.items.items()): + item.print(name=key, level=next_level, print_type=print_type) + + @classmethod + def from_json_file(cls, *, file_path: Path, parents: List[str]) -> "HashableItem": + """ + Create a hashable item from a JSON file. + """ + items = {} + with file_path.open("r") as f: + data = json.load(f) + for key, item in sorted(data.items()): + assert isinstance(item, dict), f"Expected dict, got {type(item)}" + assert "_info" in item, f"Expected _info in {key}" + assert "hash" in item["_info"], f"Expected hash in {key}" + assert isinstance( + item["_info"]["hash"], str + ), f"Expected hash to be a string in {key}, got {type(item['_info']['hash'])}" + item_hash_bytes = bytes.fromhex(item["_info"]["hash"][2:]) + items[key] = cls( + type=HashableItemType.TEST, + root=item_hash_bytes, + parents=parents + [file_path.name], + ) + return cls(type=HashableItemType.FILE, items=items, parents=parents) + + @classmethod + def from_folder(cls, *, folder_path: Path, parents: List[str] = []) -> "HashableItem": + """ + Create a hashable item from a folder. + """ + items = {} + for file_path in sorted(folder_path.iterdir()): + if file_path.is_file() and file_path.suffix == ".json": + item = cls.from_json_file( + file_path=file_path, parents=parents + [folder_path.name] + ) + items[file_path.name] = item + elif file_path.is_dir(): + item = cls.from_folder(folder_path=file_path, parents=parents + [folder_path.name]) + items[file_path.name] = item + return cls(type=HashableItemType.FOLDER, items=items, parents=parents) + + +def main() -> None: + """ + Main function. + """ + parser = argparse.ArgumentParser(description="Hash folders of JSON fixtures.") + + parser.add_argument("folder_path", type=Path, help="The path to the JSON fixtures directory") + parser.add_argument("--files", "-f", action="store_true", help="Print hash of files") + parser.add_argument("--tests", "-t", action="store_true", help="Print hash of tests") + parser.add_argument("--root", "-r", action="store_true", help="Only print hash of root folder") + + args = parser.parse_args() + + item = HashableItem.from_folder(folder_path=args.folder_path) + + if args.root: + print(f"0x{item.hash().hex()}") + return + + print_type: Optional[HashableItemType] = None + + if args.files: + print_type = HashableItemType.FILE + elif args.tests: + print_type = HashableItemType.TEST + + item.print(name=args.folder_path.name, print_type=print_type) diff --git a/src/ethereum_test_tools/common/json.py b/src/ethereum_test_tools/common/json.py index 9503bad512..3e4e5956bf 100644 --- a/src/ethereum_test_tools/common/json.py +++ b/src/ethereum_test_tools/common/json.py @@ -1,6 +1,7 @@ """ JSON encoding and decoding for Ethereum types. """ + import json from abc import ABC, abstractmethod from dataclasses import dataclass @@ -112,8 +113,9 @@ def default(self, obj: Any) -> Any: for object_field in fields(obj): field_name = object_field.name metadata = object_field.metadata + if not metadata: + continue value = getattr(obj, field_name) - assert metadata is not None, f"Field {field_name} has no metadata" field_settings = metadata.get("json_encoder") assert isinstance(field_settings, self.Field), ( f"Field {field_name} has invalid json_encoder " f"metadata: {field_settings}" diff --git a/src/ethereum_test_tools/spec/base/base_test.py b/src/ethereum_test_tools/spec/base/base_test.py index cd436de46c..dc989d18c3 100644 --- a/src/ethereum_test_tools/spec/base/base_test.py +++ b/src/ethereum_test_tools/spec/base/base_test.py @@ -1,6 +1,9 @@ """ Base test class and helper functions for Ethereum state and blockchain tests. """ + +import hashlib +import json from abc import abstractmethod from dataclasses import dataclass, field from itertools import count @@ -15,6 +18,7 @@ from ...common.conversions import to_hex from ...common.json import JSONEncoder from ...common.json import field as json_field +from ...common.json import to_json from ...reference_spec.reference_spec import ReferenceSpec @@ -87,6 +91,8 @@ class BaseFixture: ), ) + _json: Optional[Dict[str, Any]] = None + def fill_info( self, t8n: TransitionTool, @@ -101,12 +107,22 @@ def fill_info( if ref_spec is not None: ref_spec.write_info(self.info) - @abstractmethod + def __post_init__(self): + """ + Post init hook to convert to JSON after instantiation. + """ + self._json = to_json(self) + json_str = json.dumps(self._json, sort_keys=True, separators=(",", ":")) + h = hashlib.sha256(json_str.encode("utf-8")).hexdigest() + self.info["hash"] = f"0x{h}" + def to_json(self) -> Dict[str, Any]: """ Convert to JSON. """ - pass + assert self._json is not None, "Fixture not initialized" + self._json["_info"] = self.info + return self._json @classmethod @abstractmethod diff --git a/src/ethereum_test_tools/spec/blockchain/types.py b/src/ethereum_test_tools/spec/blockchain/types.py index 61b1932d83..958adad691 100644 --- a/src/ethereum_test_tools/spec/blockchain/types.py +++ b/src/ethereum_test_tools/spec/blockchain/types.py @@ -1,6 +1,7 @@ """ BlockchainTest types """ + import json from copy import copy, deepcopy from dataclasses import dataclass, fields, replace @@ -26,7 +27,7 @@ ) from ...common.constants import AddrAA, EmptyOmmersRoot, EngineAPIError from ...common.conversions import BytesConvertible, FixedSizeBytesConvertible, NumberConvertible -from ...common.json import JSONEncoder, field, to_json +from ...common.json import JSONEncoder, field from ...common.types import ( Account, Alloc, @@ -1017,26 +1018,6 @@ class FixtureCommon(BaseFixture): name="network", ), ) - _json: Dict[str, Any] | None = field( - default=None, - json_encoder=JSONEncoder.Field( - skip=True, - ), - ) - - def __post_init__(self): - """ - Post init hook to convert to JSON after instantiation. - """ - self._json = to_json(self) - - def to_json(self) -> Dict[str, Any]: - """ - Convert to JSON. - """ - assert self._json is not None, "Fixture not initialized" - self._json["_info"] = self.info - return self._json @classmethod def collect_into_file(cls, fd: TextIO, fixtures: Dict[str, "BaseFixture"]): diff --git a/src/ethereum_test_tools/spec/state/types.py b/src/ethereum_test_tools/spec/state/types.py index 88e0d9fa13..94b26d65fa 100644 --- a/src/ethereum_test_tools/spec/state/types.py +++ b/src/ethereum_test_tools/spec/state/types.py @@ -1,6 +1,7 @@ """ StateTest types """ + import json from dataclasses import dataclass, fields from pathlib import Path @@ -10,7 +11,7 @@ from ...common.base_types import Address, Bytes, Hash, HexNumber, ZeroPaddedHexNumber from ...common.conversions import BytesConvertible, FixedSizeBytesConvertible, NumberConvertible -from ...common.json import JSONEncoder, field, to_json +from ...common.json import JSONEncoder, field from ...common.types import AccessList, Alloc, Environment, Transaction from ...exceptions import ExceptionList, TransactionException from ..base.base_test import BaseFixture @@ -287,27 +288,6 @@ class Fixture(BaseFixture): ), ) - _json: Dict[str, Any] | None = field( - default=None, - json_encoder=JSONEncoder.Field( - skip=True, - ), - ) - - def __post_init__(self): - """ - Post init hook to convert to JSON after instantiation. - """ - self._json = to_json(self) - - def to_json(self) -> Dict[str, Any]: - """ - Convert to JSON. - """ - assert self._json is not None, "Fixture not initialized" - self._json["_info"] = self.info - return self._json - @classmethod def collect_into_file(cls, fd: TextIO, fixtures: Dict[str, "BaseFixture"]): """ diff --git a/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_london_invalid_filled.json b/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_london_invalid_filled.json index 3c51d2b60a..228f06c6b4 100644 --- a/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_london_invalid_filled.json +++ b/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_london_invalid_filled.json @@ -1,6 +1,9 @@ { "solc=0.8.20": { "000/my_blockchain_test/London": { + "_info": { + "hash": "0x2c3bb32517b56a755b7433abd36d4a6b761c1d79d9fbed7dac4ea532eb739c11" + }, "network": "London", "genesisRLP": "0xf90200f901fba00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a089a5be1d3306f6f05b42678ef13ac3dbc37bef9a2a80862c21eb22eee29194c2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008088016345785d8a0000808000a000000000000000000000000000000000000000000000000000000000000000008800000000000000008203e8c0c0", "genesisBlockHeader": { @@ -541,6 +544,9 @@ }, "solc=padding_version": { "000/my_blockchain_test/London": { + "_info": { + "hash": "0x0aede6c01648a4a89633be93ad0dcc5ddb48dc27c38cddeac0629edf5ea2b7b5" + }, "network": "London", "genesisRLP": "0xf90200f901fba00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0de1557ffdf9765e61095937bf835742ca427008f33714bee743010ab2d1e0ba6a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008088016345785d8a0000808000a000000000000000000000000000000000000000000000000000000000000000008800000000000000008203e8c0c0", "genesisBlockHeader": { diff --git a/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_london_valid_filled.json b/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_london_valid_filled.json index 8f2c0126ca..35abf6f9d1 100644 --- a/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_london_valid_filled.json +++ b/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_london_valid_filled.json @@ -1,6 +1,9 @@ { "solc=0.8.20": { "000/my_blockchain_test/London": { + "_info": { + "hash": "0xf3750dd67158fb66466c4deb195073bb5a4621f3b3ee315c9d3fa443d7d8c445" + }, "network": "London", "genesisRLP": "0xf90200f901fba00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a089a5be1d3306f6f05b42678ef13ac3dbc37bef9a2a80862c21eb22eee29194c2a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008088016345785d8a0000808000a000000000000000000000000000000000000000000000000000000000000000008800000000000000008203e8c0c0", "genesisBlockHeader": { @@ -419,6 +422,9 @@ }, "solc=padding_version": { "000/my_blockchain_test/London": { + "_info": { + "hash": "0xb31303cc3ecdd1cac8b0669e43f70e1f8784aa8659f457ed4e1654935c6e986b" + }, "blocks": [ { "rlp": "0xf9026ef901fea0c552af8a2644e24df2f54d14aa70f207146dda49b746cc2e0af88e185f043d2ea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794ba5e000000000000000000000000000000000000a06bbd44292c9016cf53472d8ef579a1805a9008b898c5f159248ed106532b667ba0586f963eea0fb4726f0f91f895f2aa5d67bffb5207a529b40d781244a0c7017ba029b0562f7140574dd0d50dee8a271b22e1a0a7b78fca58f7c60370d8317ba2a9b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000188016345785d8a0000830155340c80a0000000000000000000000000000000000000000000000000000000000000000088000000000000000082036bf86ab86802f8650180018203e8830f424094cccccccccccccccccccccccccccccccccccccccc8001c080a03351b6993208fc7b03fd770c8c06440cfb0d75b29aafee0a4c64c8ba20a80e58a067817fdb3058e75c5d26e51a33d1e338346bc7d406e115447a4bb5f7ab01625bc0", diff --git a/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_shanghai_invalid_filled_hive.json b/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_shanghai_invalid_filled_hive.json index 983589a2d1..467266edf7 100644 --- a/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_shanghai_invalid_filled_hive.json +++ b/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_shanghai_invalid_filled_hive.json @@ -1,6 +1,9 @@ { "solc=0.8.20": { "000/my_blockchain_test/Shanghai": { + "_info": { + "hash": "0x7c6f019488aef8bebd4582f188e579bc5eb994790f2ac77dc4cef67229cf96d9" + }, "network": "Shanghai", "genesisBlockHeader": { "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -296,6 +299,9 @@ }, "solc=padding_version": { "000/my_blockchain_test/Shanghai": { + "_info": { + "hash": "0x55f9bcc040c2183e1f82e80ec5aeeff33c5e7454c05ab694e6e4153a59ea3a11" + }, "network": "Shanghai", "genesisBlockHeader": { "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", diff --git a/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_shanghai_valid_filled_hive.json b/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_shanghai_valid_filled_hive.json index 7b61fab984..37d2265f6a 100644 --- a/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_shanghai_valid_filled_hive.json +++ b/src/ethereum_test_tools/tests/test_filling/fixtures/blockchain_shanghai_valid_filled_hive.json @@ -1,6 +1,9 @@ { "solc=0.8.20": { "000/my_blockchain_test/Shanghai": { + "_info": { + "hash": "0x65ff879b8bfe661b2ab4cfbc45bb28d9a07110455eff98972dfba3988632cff5" + }, "network": "Shanghai", "genesisBlockHeader": { "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -248,6 +251,9 @@ }, "solc=padding_version": { "000/my_blockchain_test/Shanghai": { + "_info": { + "hash": "0xeb5c65b76f939bbd0b89d2f8b4cc075bb2c3ac6f00b07c67f8f77af160444470" + }, "network": "Shanghai", "genesisBlockHeader": { "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", diff --git a/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_istanbul_blockchain_test.json b/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_istanbul_blockchain_test.json index fdba9a80ab..ba751ade50 100644 --- a/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_istanbul_blockchain_test.json +++ b/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_istanbul_blockchain_test.json @@ -1,5 +1,8 @@ { "000/my_chain_id_test/Istanbul": { + "_info": { + "hash": "0x10c6e62b41fea4dbe1d9652536b662efdcdc54248297cf7f8aa1fa64fca9def5" + }, "network": "Istanbul", "genesisRLP": "0xf901faf901f5a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0aff9f63320a482f8c4e4f15f659e6a7ac382138fbbb6919243b0cba4c5988a5aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a00000000000000000000000000000000000000000000000000000000000000000880000000000000000c0c0", "genesisBlockHeader": { diff --git a/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_london_blockchain_test.json b/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_london_blockchain_test.json index 9574fb926b..fbea97a17c 100644 --- a/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_london_blockchain_test.json +++ b/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_london_blockchain_test.json @@ -1,5 +1,8 @@ { "000/my_chain_id_test/London": { + "_info": { + "hash": "0xe2dd2b58a176c4f55a91d96ed10e9ae7857a77f10ba5da427a27bcc24bd92d0f" + }, "network": "London", "genesisRLP": "0xf901fbf901f6a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0aff9f63320a482f8c4e4f15f659e6a7ac382138fbbb6919243b0cba4c5988a5aa056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000808502540be400808000a0000000000000000000000000000000000000000000000000000000000000000088000000000000000007c0c0", "genesisBlockHeader": { diff --git a/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_paris_blockchain_test_hive.json b/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_paris_blockchain_test_hive.json index e34b7fee39..1b01baf98c 100644 --- a/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_paris_blockchain_test_hive.json +++ b/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_paris_blockchain_test_hive.json @@ -1,5 +1,8 @@ { "000/my_chain_id_test/Paris": { + "_info": { + "hash": "0x61b10b97625c41f23bee558102248e8690f127041d1dc7262566c90e207e41d4" + }, "network": "Merge", "genesisBlockHeader": { "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", diff --git a/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_paris_state_test.json b/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_paris_state_test.json index da61b28328..7ccba7ae4b 100644 --- a/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_paris_state_test.json +++ b/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_paris_state_test.json @@ -1,5 +1,8 @@ { "000/my_chain_id_test/Paris": { + "_info": { + "hash": "0x6cbfbd0c9bd8b4739ce34df0d25047cfbdcf5b12964b824c921b159ddca4ccfe" + }, "env": { "currentCoinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentGasLimit": "0x02540be400", diff --git a/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_shanghai_blockchain_test_hive.json b/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_shanghai_blockchain_test_hive.json index 1eb9ee882e..67b0008738 100644 --- a/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_shanghai_blockchain_test_hive.json +++ b/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_shanghai_blockchain_test_hive.json @@ -1,5 +1,8 @@ { "000/my_chain_id_test/Shanghai": { + "_info": { + "hash": "0x0ae35254c197f727c0a4254d37851b95967713f80d7c57a7717f99bd036e54e5" + }, "network": "Shanghai", "genesisBlockHeader": { "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", diff --git a/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_shanghai_state_test.json b/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_shanghai_state_test.json index 5b2fcb4e56..3c56c9f6b4 100644 --- a/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_shanghai_state_test.json +++ b/src/ethereum_test_tools/tests/test_filling/fixtures/chainid_shanghai_state_test.json @@ -1,5 +1,8 @@ { "000/my_chain_id_test/Shanghai": { + "_info": { + "hash": "0x20cae66b10db3f94fafdbb343c95ade6ea4f650379d3383234709e3dbc802318" + }, "env": { "currentCoinbase": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentGasLimit": "0x02540be400", diff --git a/src/ethereum_test_tools/tests/test_filling/test_fixtures.py b/src/ethereum_test_tools/tests/test_filling/test_fixtures.py index fcd0f26eb2..61fc0a0a98 100644 --- a/src/ethereum_test_tools/tests/test_filling/test_fixtures.py +++ b/src/ethereum_test_tools/tests/test_filling/test_fixtures.py @@ -4,7 +4,7 @@ import json import os -from typing import Any, Dict, List, Mapping +from typing import Any, List, Mapping import pytest from semver import Version @@ -23,10 +23,13 @@ from ..conftest import SOLC_PADDING_VERSION -def remove_info(fixture_json: Dict[str, Any]): # noqa: D103 +def remove_info_metadata(fixture_json): # noqa: D103 for t in fixture_json: if "_info" in fixture_json[t]: - del fixture_json[t]["_info"] + info_keys = list(fixture_json[t]["_info"].keys()) + for key in info_keys: + if key != "hash": # remove keys that are not 'hash' + del fixture_json[t]["_info"][key] @pytest.fixture() @@ -171,7 +174,7 @@ def test_fill_state_test( expected = json.load(f) fixture_json = to_json(fixture) - remove_info(fixture_json) + remove_info_metadata(fixture_json) assert fixture_json == expected @@ -514,7 +517,7 @@ def test_fill_blockchain_valid_txs( # noqa: D102 expected = json.load(f) fixture_json = to_json(fixture) - remove_info(fixture_json) + remove_info_metadata(fixture_json) if solc_version >= SOLC_PADDING_VERSION: expected = expected["solc=padding_version"] @@ -888,7 +891,7 @@ def test_fill_blockchain_invalid_txs( expected = json.load(f) fixture_json = to_json(fixture) - remove_info(fixture_json) + remove_info_metadata(fixture_json) if solc_version >= SOLC_PADDING_VERSION: expected = expected["solc=padding_version"] diff --git a/whitelist.txt b/whitelist.txt index fa7a0b41f2..05108084a4 100644 --- a/whitelist.txt +++ b/whitelist.txt @@ -125,6 +125,7 @@ go-ethereum's gwei hardfork hash32 +Hashable hasher HeaderNonce hexary