From 1050c028d0a8537a1f6d85bf005807a3f4cc1eaa Mon Sep 17 00:00:00 2001 From: spencer-tb Date: Wed, 6 Sep 2023 11:50:33 +0200 Subject: [PATCH 1/3] src: Only add fcu version to fixture for hive. --- src/ethereum_test_forks/base_fork.py | 10 ++++++++++ src/ethereum_test_forks/forks/forks.py | 9 +++++++++ src/ethereum_test_tools/common/types.py | 5 +++++ src/ethereum_test_tools/filling/fill.py | 5 +++++ whitelist.txt | 1 + 5 files changed, 30 insertions(+) diff --git a/src/ethereum_test_forks/base_fork.py b/src/ethereum_test_forks/base_fork.py index 1bc51683fc..2ddfbe13c2 100644 --- a/src/ethereum_test_forks/base_fork.py +++ b/src/ethereum_test_forks/base_fork.py @@ -174,6 +174,16 @@ def engine_new_payload_beacon_root(cls, block_number: int = 0, timestamp: int = """ pass + @classmethod + @abstractmethod + def engine_forkchoice_updated_version( + cls, block_number: int = 0, timestamp: int = 0 + ) -> Optional[int]: + """ + Returns `None` if the forks canonical chain cannot be set using the forkchoice method. + """ + pass + # Meta information about the fork @classmethod def name(cls) -> str: diff --git a/src/ethereum_test_forks/forks/forks.py b/src/ethereum_test_forks/forks/forks.py index b943677536..d2f32250e9 100644 --- a/src/ethereum_test_forks/forks/forks.py +++ b/src/ethereum_test_forks/forks/forks.py @@ -91,6 +91,15 @@ def engine_new_payload_beacon_root(cls, block_number: int = 0, timestamp: int = """ return False + @classmethod + def engine_forkchoice_updated_version( + cls, block_number: int = 0, timestamp: int = 0 + ) -> Optional[int]: + """ + At genesis, forkchoice updates cannot be sent through the engine API. + """ + return cls.engine_new_payload_version(block_number, timestamp) + @classmethod def get_reward(cls, block_number: int = 0, timestamp: int = 0) -> int: """ diff --git a/src/ethereum_test_tools/common/types.py b/src/ethereum_test_tools/common/types.py index d152f9b19f..254a24add4 100644 --- a/src/ethereum_test_tools/common/types.py +++ b/src/ethereum_test_tools/common/types.py @@ -2707,6 +2707,11 @@ class Fixture: to_json=True, ), ) + fcu_version: Optional[int] = field( + json_encoder=JSONEncoder.Field( + name="engineFcuVersion", + ), + ) genesis: FixtureHeader = field( json_encoder=JSONEncoder.Field( name="genesisBlockHeader", diff --git a/src/ethereum_test_tools/filling/fill.py b/src/ethereum_test_tools/filling/fill.py index 9a4d5e9435..2169239cf3 100644 --- a/src/ethereum_test_tools/filling/fill.py +++ b/src/ethereum_test_tools/filling/fill.py @@ -44,6 +44,11 @@ def fill_test( pre_state=pre, post_state=alloc_to_accounts(alloc), seal_engine=engine, + fcu_version=fork.engine_forkchoice_updated_version( + blocks[-1].block_header.number, blocks[-1].block_header.timestamp + ) + if not test_spec.base_test_config.disable_hive and blocks[-1].block_header + else None, name=test_spec.tag, ) fixture.fill_info(t8n, spec) diff --git a/whitelist.txt b/whitelist.txt index 637cc77350..287b658776 100644 --- a/whitelist.txt +++ b/whitelist.txt @@ -84,6 +84,7 @@ extcodesize fn fname forkchoice +fcu formatOnSave formatter fromhex From b363ee8d3d4a20da22a7ff0e6217ef0aab01916b Mon Sep 17 00:00:00 2001 From: spencer-tb Date: Wed, 6 Sep 2023 15:17:35 +0200 Subject: [PATCH 2/3] src: Only add fcuVersion based on last valid block. --- src/ethereum_test_tools/filling/fill.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/ethereum_test_tools/filling/fill.py b/src/ethereum_test_tools/filling/fill.py index 2169239cf3..fed0ad7171 100644 --- a/src/ethereum_test_tools/filling/fill.py +++ b/src/ethereum_test_tools/filling/fill.py @@ -34,6 +34,20 @@ def fill_test( eips=eips, ) + fcu_version: int | None = None + if not test_spec.base_test_config.disable_hive: + last_valid_block = next( + (block.block_header for block in reversed(blocks) if block.expected_exception is None), + None, + ) + fcu_version = ( + fork.engine_forkchoice_updated_version( + last_valid_block.number, last_valid_block.timestamp + ) + if last_valid_block + else None + ) + fork_name = fork.name() fixture = Fixture( blocks=blocks, @@ -44,12 +58,8 @@ def fill_test( pre_state=pre, post_state=alloc_to_accounts(alloc), seal_engine=engine, - fcu_version=fork.engine_forkchoice_updated_version( - blocks[-1].block_header.number, blocks[-1].block_header.timestamp - ) - if not test_spec.base_test_config.disable_hive and blocks[-1].block_header - else None, name=test_spec.tag, + fcu_version=fcu_version, ) fixture.fill_info(t8n, spec) From 150d8cbd4285369bd66e675e98e9f1065fe1f222 Mon Sep 17 00:00:00 2001 From: spencer-tb Date: Tue, 19 Sep 2023 18:30:46 -0400 Subject: [PATCH 3/3] src/ethereum_test_tools: move fcuVersion last valid block logic to spec. --- src/ethereum_test_tools/filling/fill.py | 16 +--------------- src/ethereum_test_tools/spec/base_test.py | 2 +- src/ethereum_test_tools/spec/blockchain_test.py | 15 +++++++++++++-- src/ethereum_test_tools/spec/state_test.py | 8 ++++++-- 4 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/ethereum_test_tools/filling/fill.py b/src/ethereum_test_tools/filling/fill.py index fed0ad7171..b675d701a2 100644 --- a/src/ethereum_test_tools/filling/fill.py +++ b/src/ethereum_test_tools/filling/fill.py @@ -26,7 +26,7 @@ def fill_test( pre, genesis_rlp, genesis = test_spec.make_genesis(t8n, fork) - (blocks, head, alloc) = test_spec.make_blocks( + (blocks, head, alloc, fcu_version) = test_spec.make_blocks( t8n, genesis, pre, @@ -34,20 +34,6 @@ def fill_test( eips=eips, ) - fcu_version: int | None = None - if not test_spec.base_test_config.disable_hive: - last_valid_block = next( - (block.block_header for block in reversed(blocks) if block.expected_exception is None), - None, - ) - fcu_version = ( - fork.engine_forkchoice_updated_version( - last_valid_block.number, last_valid_block.timestamp - ) - if last_valid_block - else None - ) - fork_name = fork.name() fixture = Fixture( blocks=blocks, diff --git a/src/ethereum_test_tools/spec/base_test.py b/src/ethereum_test_tools/spec/base_test.py index 76c7b95c3e..bbad9fa7ce 100644 --- a/src/ethereum_test_tools/spec/base_test.py +++ b/src/ethereum_test_tools/spec/base_test.py @@ -127,7 +127,7 @@ def make_blocks( fork: Fork, chain_id: int = 1, eips: Optional[List[int]] = None, - ) -> Tuple[List[FixtureBlock], Hash, Dict[str, Any]]: + ) -> Tuple[List[FixtureBlock], Hash, Dict[str, Any], Optional[int]]: """ Generate the blockchain that must be executed sequentially during test. """ diff --git a/src/ethereum_test_tools/spec/blockchain_test.py b/src/ethereum_test_tools/spec/blockchain_test.py index a8a63a700f..0ec70fceba 100644 --- a/src/ethereum_test_tools/spec/blockchain_test.py +++ b/src/ethereum_test_tools/spec/blockchain_test.py @@ -264,7 +264,7 @@ def make_blocks( fork: Fork, chain_id=1, eips: Optional[List[int]] = None, - ) -> Tuple[List[FixtureBlock], Hash, Dict[str, Any]]: + ) -> Tuple[List[FixtureBlock], Hash, Dict[str, Any], Optional[int]]: """ Create a block list from the blockchain test definition. Performs checks against the expected behavior of the test. @@ -273,6 +273,9 @@ def make_blocks( alloc = to_json(pre) env = Environment.from_parent_header(genesis) blocks: List[FixtureBlock] = [] + fcu_version: Optional[int] = None + last_valid: Optional[FixtureHeader] = None + head = genesis.hash if genesis.hash is not None else Hash(0) for block in self.blocks: fixture_block, env, alloc, head = self.make_block( @@ -286,6 +289,14 @@ def make_blocks( eips=eips, ) blocks.append(fixture_block) + if block.exception is None: + last_valid = fixture_block.block_header + + if not self.base_test_config.disable_hive and last_valid is not None: + fcu_version = fork.engine_forkchoice_updated_version( + block_number=last_valid.number, + timestamp=last_valid.timestamp, + ) try: verify_post_alloc(self.post, alloc) @@ -293,7 +304,7 @@ def make_blocks( print_traces(t8n.get_traces()) raise e - return (blocks, head, alloc) + return (blocks, head, alloc, fcu_version) BlockchainTestSpec = Callable[[str], Generator[BlockchainTest, None, None]] diff --git a/src/ethereum_test_tools/spec/state_test.py b/src/ethereum_test_tools/spec/state_test.py index 64476e6b10..9e7145ccc1 100644 --- a/src/ethereum_test_tools/spec/state_test.py +++ b/src/ethereum_test_tools/spec/state_test.py @@ -127,7 +127,7 @@ def make_blocks( fork: Fork, chain_id=1, eips: Optional[List[int]] = None, - ) -> Tuple[List[FixtureBlock], Hash, Dict[str, Any]]: + ) -> Tuple[List[FixtureBlock], Hash, Dict[str, Any], Optional[int]]: """ Create a block from the state test definition. Performs checks against the expected behavior of the test. @@ -178,15 +178,18 @@ def make_blocks( withdrawals=env.withdrawals, ) + # Hive specific fields new_payload: FixtureEngineNewPayload | None = None + fcu_version: int | None = None if not self.base_test_config.disable_hive: new_payload = FixtureEngineNewPayload.from_fixture_header( fork=fork, header=header, transactions=txs, withdrawals=env.withdrawals, - error_code=self.engine_api_error_code, + error_code=None, ) + fcu_version = fork.engine_forkchoice_updated_version(header.number, header.timestamp) return ( [ @@ -201,6 +204,7 @@ def make_blocks( ], header.hash, alloc, + fcu_version, )