diff --git a/src/ethereum_test_fixtures/blockchain.py b/src/ethereum_test_fixtures/blockchain.py index 3a00484eca..e14287145a 100644 --- a/src/ethereum_test_fixtures/blockchain.py +++ b/src/ethereum_test_fixtures/blockchain.py @@ -229,7 +229,7 @@ def from_fixture_header( EngineNewPayloadV1Parameters = Tuple[FixtureExecutionPayload] EngineNewPayloadV3Parameters = Tuple[FixtureExecutionPayload, List[Hash], Hash] -EngineNewPayloadV4Parameters = Tuple[FixtureExecutionPayload, List[Hash], Hash, List[Bytes]] +EngineNewPayloadV4Parameters = Tuple[FixtureExecutionPayload, List[Hash], Hash, List[Bytes], HexNumber] # Important: We check EngineNewPayloadV3Parameters first as it has more fields, and pydantic # has a weird behavior when the smaller tuple is checked first. @@ -291,32 +291,34 @@ def from_fixture_header( transactions=transactions, withdrawals=withdrawals, ) - params: EngineNewPayloadParameters - if ( - fork.engine_new_payload_requests(header.number, header.timestamp) - and requests is not None - ): - parent_beacon_block_root = header.parent_beacon_block_root - assert parent_beacon_block_root is not None - params = ( - execution_payload, - Transaction.list_blob_versioned_hashes(transactions), - parent_beacon_block_root, - requests, - ) - elif fork.engine_new_payload_blob_hashes(header.number, header.timestamp): - parent_beacon_block_root = header.parent_beacon_block_root - assert parent_beacon_block_root is not None - params = ( - execution_payload, - Transaction.list_blob_versioned_hashes(transactions), - parent_beacon_block_root, - ) - else: - params = (execution_payload,) + params: List[Any] = [execution_payload] + if fork.engine_new_payload_blob_hashes(header.number, header.timestamp): + blob_hashes = Transaction.list_blob_versioned_hashes(transactions) + if blob_hashes is None: + raise ValueError(f"Blob hashes are required for ${fork}.") + params.append(blob_hashes) + + if fork.engine_new_payload_beacon_root(header.number, header.timestamp): + parent_beacon_block_root = header.parent_beacon_block_root + if parent_beacon_block_root is None: + raise ValueError(f"Parent beacon block root is required for ${fork}.") + params.append(parent_beacon_block_root) + + if fork.engine_new_payload_requests(header.number, header.timestamp): + if requests is None: + raise ValueError(f"Requests are required for ${fork}.") + params.append(requests) + + if fork.engine_new_payload_target_blob_count(header.number, header.timestamp): + target_blob_count = header.target_blob_count + if target_blob_count is None: + raise ValueError(f"Target blob count is required for ${fork}.") + params.append(target_blob_count) + + payload_params: EngineNewPayloadParameters = tuple(params) new_payload = cls( - params=params, + params=payload_params, new_payload_version=new_payload_version, forkchoice_updated_version=forkchoice_updated_version, **kwargs, diff --git a/src/ethereum_test_forks/base_fork.py b/src/ethereum_test_forks/base_fork.py index c19d6141c2..c2d5b6f711 100644 --- a/src/ethereum_test_forks/base_fork.py +++ b/src/ethereum_test_forks/base_fork.py @@ -281,7 +281,15 @@ def engine_new_payload_beacon_root(cls, block_number: int = 0, timestamp: int = @abstractmethod def engine_new_payload_requests(cls, block_number: int = 0, timestamp: int = 0) -> bool: """ - Returns true if the engine api version requires new payload calls to include requests. + returns true if the engine api version requires new payload calls to include requests. + """ + pass + + @classmethod + @abstractmethod + def engine_new_payload_target_blob_count(cls, block_number: int = 0, timestamp: int = 0) -> bool: + """ + returns true if the engine api version requires new payload calls to include target blob count. """ pass diff --git a/src/ethereum_test_forks/forks/forks.py b/src/ethereum_test_forks/forks/forks.py index 67599a448c..40f36d96ab 100644 --- a/src/ethereum_test_forks/forks/forks.py +++ b/src/ethereum_test_forks/forks/forks.py @@ -961,9 +961,9 @@ def engine_new_payload_requests(cls, block_number: int = 0, timestamp: int = 0) return True @classmethod - def engine_new_payload_blob_hashes(cls, block_number: int = 0, timestamp: int = 0) -> bool: + def engine_new_payload_target_blob_count(cls, block_number: int = 0, timestamp: int = 0) -> bool: """ - Starting at Prague, new payload directives must contain requests as parameter. + Starting at Prague, new payloads include the target blob count as a parameter. """ return True