From 7fbc70bc9a2bd0ff7341ea8afd79525757e48b6e Mon Sep 17 00:00:00 2001 From: ilitteri Date: Sat, 10 Oct 2026 15:10:02 -0300 Subject: [PATCH 1/2] fix(client-clis): map ethrex's too-wide EIP-8250 nonce fields to TYPE_6_INVALID_FRAME_FORMAT ethrex rejects a frame transaction field too wide for its type while decoding, and the ethrex mapper labels the frames and signatures cases TYPE_6_INVALID_FRAME_FORMAT. EIP-8250 adds two more such fields, nonce_keys and nonce_seq, whose decode errors only matched the generic RLP_STRUCTURES_ENCODING pattern. test_static_validity's key_beyond_width and seq_beyond_width cases, which expect TYPE_6_INVALID_FRAME_FORMAT, therefore failed in hive's consume-engine run for ethrex although ethrex rejects the payload as INVALID. The pattern now covers all four fields. The new mapper test pins ethrex's verbatim messages, including the two from that run, and checks the label does not reach a legacy transaction's nonce field. --- .../client_clis/clis/ethrex.py | 9 ++-- .../tests/test_ethrex_exception_mapper.py | 53 +++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 packages/testing/src/execution_testing/client_clis/tests/test_ethrex_exception_mapper.py diff --git a/packages/testing/src/execution_testing/client_clis/clis/ethrex.py b/packages/testing/src/execution_testing/client_clis/clis/ethrex.py index 29cd0e30c66..50e40d8ab5a 100644 --- a/packages/testing/src/execution_testing/client_clis/clis/ethrex.py +++ b/packages/testing/src/execution_testing/client_clis/clis/ethrex.py @@ -217,12 +217,13 @@ class EthrexExceptionMapper(ExceptionMapper): # `validate_static_constraints` names the EIP-8141 rule it failed, so # the reason follows the prefix. Two other shapes reach the same # conclusion: ethrex checks signature-entry structure inside signature - # validation rather than static validation, and a frame or signature - # field too wide for its type is rejected while decoding. + # validation rather than static validation, and a frame, signature or + # EIP-8250 nonce field too wide for its type is rejected while + # decoding. TransactionException.TYPE_6_INVALID_FRAME_FORMAT: ( r"Invalid frame transaction format: .*|" r"Invalid frame transaction: signature validation failed|" - r"Error decoding field 'frames' of type .*|" - r"Error decoding field 'signatures' of type .*" + r"Error decoding field " + r"'(frames|signatures|nonce_keys|nonce_seq)' of type .*" ), } diff --git a/packages/testing/src/execution_testing/client_clis/tests/test_ethrex_exception_mapper.py b/packages/testing/src/execution_testing/client_clis/tests/test_ethrex_exception_mapper.py new file mode 100644 index 00000000000..5bd76f5ca5e --- /dev/null +++ b/packages/testing/src/execution_testing/client_clis/tests/test_ethrex_exception_mapper.py @@ -0,0 +1,53 @@ +"""Tests for the frame transaction entries in EthrexExceptionMapper.""" + +from typing import Set + +import pytest + +from execution_testing.client_clis.clis.ethrex import EthrexExceptionMapper +from execution_testing.exceptions import ( + ExceptionBase, + TransactionException, + UndefinedException, +) + +FORMAT = TransactionException.TYPE_6_INVALID_FRAME_FORMAT + + +def matched(message: str) -> Set[ExceptionBase]: + """Return the exceptions the mapper reports for a client message.""" + exceptions = EthrexExceptionMapper().message_to_exception(message) + assert not isinstance(exceptions, UndefinedException), message + return set(exceptions) + + +@pytest.mark.parametrize( + "message", + [ + "Error decoding field 'frames' of type alloc::vec::Vec<" + "ethrex_common::types::transaction::Frame>: InvalidLength", + "Error decoding field 'signatures' of type alloc::vec::Vec<" + "ethrex_common::types::transaction::FrameSignature>: InvalidLength", + "Error decoding field 'nonce_keys' of type alloc::vec::Vec<" + "primitive_types::U256>: InvalidLength", + "Error decoding field 'nonce_seq' of type u64: InvalidLength", + ], +) +def test_frame_field_too_wide_maps_to_invalid_frame_format( + message: str, +) -> None: + """ + A frame transaction field too wide for its type, which ethrex rejects + while decoding, maps to the frame format label. + + The messages are ethrex's verbatim, including the EIP-8250 nonce key + set and nonce sequence of `test_static_validity`'s `key_beyond_width` + and `seq_beyond_width` cases. + """ + assert FORMAT in matched(message) + + +def test_other_field_too_wide_is_not_a_frame_format_error() -> None: + """The frame label does not leak onto other transaction types' fields.""" + message = "Error decoding field 'nonce' of type u64: InvalidLength" + assert FORMAT not in matched(message) From b2d7ece22ea4a991a7a837bf05fe57f6f4eab062 Mon Sep 17 00:00:00 2001 From: ilitteri Date: Sat, 10 Oct 2026 15:16:58 -0300 Subject: [PATCH 2/2] chore(client-clis): drop the ethrex mapper unit test The test restated the mapper's regex against copies of ethrex's messages, so it could not catch the failure that matters, ethrex rewording a message, and hive's consume-engine run already covers the mapping against the client itself. The fix is the mapper change alone, as for the other client mappers. --- .../tests/test_ethrex_exception_mapper.py | 53 ------------------- 1 file changed, 53 deletions(-) delete mode 100644 packages/testing/src/execution_testing/client_clis/tests/test_ethrex_exception_mapper.py diff --git a/packages/testing/src/execution_testing/client_clis/tests/test_ethrex_exception_mapper.py b/packages/testing/src/execution_testing/client_clis/tests/test_ethrex_exception_mapper.py deleted file mode 100644 index 5bd76f5ca5e..00000000000 --- a/packages/testing/src/execution_testing/client_clis/tests/test_ethrex_exception_mapper.py +++ /dev/null @@ -1,53 +0,0 @@ -"""Tests for the frame transaction entries in EthrexExceptionMapper.""" - -from typing import Set - -import pytest - -from execution_testing.client_clis.clis.ethrex import EthrexExceptionMapper -from execution_testing.exceptions import ( - ExceptionBase, - TransactionException, - UndefinedException, -) - -FORMAT = TransactionException.TYPE_6_INVALID_FRAME_FORMAT - - -def matched(message: str) -> Set[ExceptionBase]: - """Return the exceptions the mapper reports for a client message.""" - exceptions = EthrexExceptionMapper().message_to_exception(message) - assert not isinstance(exceptions, UndefinedException), message - return set(exceptions) - - -@pytest.mark.parametrize( - "message", - [ - "Error decoding field 'frames' of type alloc::vec::Vec<" - "ethrex_common::types::transaction::Frame>: InvalidLength", - "Error decoding field 'signatures' of type alloc::vec::Vec<" - "ethrex_common::types::transaction::FrameSignature>: InvalidLength", - "Error decoding field 'nonce_keys' of type alloc::vec::Vec<" - "primitive_types::U256>: InvalidLength", - "Error decoding field 'nonce_seq' of type u64: InvalidLength", - ], -) -def test_frame_field_too_wide_maps_to_invalid_frame_format( - message: str, -) -> None: - """ - A frame transaction field too wide for its type, which ethrex rejects - while decoding, maps to the frame format label. - - The messages are ethrex's verbatim, including the EIP-8250 nonce key - set and nonce sequence of `test_static_validity`'s `key_beyond_width` - and `seq_beyond_width` cases. - """ - assert FORMAT in matched(message) - - -def test_other_field_too_wide_is_not_a_frame_format_error() -> None: - """The frame label does not leak onto other transaction types' fields.""" - message = "Error decoding field 'nonce' of type u64: InvalidLength" - assert FORMAT not in matched(message)