From 9494cd81efc6e5cba755ed80c0c0cd5dc8a825f5 Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Mon, 30 Mar 2026 16:59:14 -0400 Subject: [PATCH 1/3] fix(specs): remove None from trie Node type (#2596) Closes: #1044 --- src/ethereum/forks/amsterdam/trie.py | 17 ++++++----------- src/ethereum/forks/arrow_glacier/trie.py | 6 ++++-- src/ethereum/forks/berlin/trie.py | 6 ++++-- src/ethereum/forks/bpo1/trie.py | 17 ++++++----------- src/ethereum/forks/bpo2/trie.py | 17 ++++++----------- src/ethereum/forks/bpo3/trie.py | 17 ++++++----------- src/ethereum/forks/bpo4/trie.py | 17 ++++++----------- src/ethereum/forks/bpo5/trie.py | 17 ++++++----------- src/ethereum/forks/byzantium/trie.py | 6 ++++-- src/ethereum/forks/cancun/trie.py | 17 ++++++----------- src/ethereum/forks/constantinople/trie.py | 6 ++++-- src/ethereum/forks/dao_fork/trie.py | 6 ++++-- src/ethereum/forks/frontier/trie.py | 11 ++++++----- src/ethereum/forks/gray_glacier/trie.py | 6 ++++-- src/ethereum/forks/homestead/trie.py | 6 ++++-- src/ethereum/forks/istanbul/trie.py | 6 ++++-- src/ethereum/forks/london/trie.py | 6 ++++-- src/ethereum/forks/muir_glacier/trie.py | 6 ++++-- src/ethereum/forks/osaka/trie.py | 17 ++++++----------- src/ethereum/forks/paris/trie.py | 6 ++++-- src/ethereum/forks/prague/trie.py | 17 ++++++----------- src/ethereum/forks/shanghai/trie.py | 17 ++++++----------- src/ethereum/forks/spurious_dragon/trie.py | 6 ++++-- src/ethereum/forks/tangerine_whistle/trie.py | 6 ++++-- 24 files changed, 118 insertions(+), 141 deletions(-) diff --git a/src/ethereum/forks/amsterdam/trie.py b/src/ethereum/forks/amsterdam/trie.py index 0f89d295832..b6b055a3c82 100644 --- a/src/ethereum/forks/amsterdam/trie.py +++ b/src/ethereum/forks/amsterdam/trie.py @@ -70,16 +70,7 @@ ) ) -Node = ( - Account - | Bytes - | LegacyTransaction - | Receipt - | Uint - | U256 - | Withdrawal - | None -) +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -148,7 +139,9 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, Withdrawal, U256)): + elif isinstance( + node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) + ): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -342,6 +335,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/arrow_glacier/trie.py b/src/ethereum/forks/arrow_glacier/trie.py index fce5af9482f..c8c2ccfb8fa 100644 --- a/src/ethereum/forks/arrow_glacier/trie.py +++ b/src/ethereum/forks/arrow_glacier/trie.py @@ -61,7 +61,7 @@ ) ) -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | None +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -179,7 +179,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, U256)): + elif isinstance(node, (LegacyTransaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -373,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/berlin/trie.py b/src/ethereum/forks/berlin/trie.py index 01e4f062098..1432406eff0 100644 --- a/src/ethereum/forks/berlin/trie.py +++ b/src/ethereum/forks/berlin/trie.py @@ -61,7 +61,7 @@ ) ) -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | None +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -179,7 +179,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, U256)): + elif isinstance(node, (LegacyTransaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -373,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/bpo1/trie.py b/src/ethereum/forks/bpo1/trie.py index 535df949e18..6f4c1708ef2 100644 --- a/src/ethereum/forks/bpo1/trie.py +++ b/src/ethereum/forks/bpo1/trie.py @@ -62,16 +62,7 @@ ) ) -Node = ( - Account - | Bytes - | LegacyTransaction - | Receipt - | Uint - | U256 - | Withdrawal - | None -) +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -190,7 +181,9 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, Withdrawal, U256)): + elif isinstance( + node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) + ): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -384,6 +377,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/bpo2/trie.py b/src/ethereum/forks/bpo2/trie.py index 8ad78603812..c48e40ec8fa 100644 --- a/src/ethereum/forks/bpo2/trie.py +++ b/src/ethereum/forks/bpo2/trie.py @@ -62,16 +62,7 @@ ) ) -Node = ( - Account - | Bytes - | LegacyTransaction - | Receipt - | Uint - | U256 - | Withdrawal - | None -) +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -190,7 +181,9 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, Withdrawal, U256)): + elif isinstance( + node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) + ): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -384,6 +377,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/bpo3/trie.py b/src/ethereum/forks/bpo3/trie.py index 3f422cfcebb..b511be0f525 100644 --- a/src/ethereum/forks/bpo3/trie.py +++ b/src/ethereum/forks/bpo3/trie.py @@ -62,16 +62,7 @@ ) ) -Node = ( - Account - | Bytes - | LegacyTransaction - | Receipt - | Uint - | U256 - | Withdrawal - | None -) +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -190,7 +181,9 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, Withdrawal, U256)): + elif isinstance( + node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) + ): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -384,6 +377,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/bpo4/trie.py b/src/ethereum/forks/bpo4/trie.py index 9e37bed4b4b..400519f411e 100644 --- a/src/ethereum/forks/bpo4/trie.py +++ b/src/ethereum/forks/bpo4/trie.py @@ -62,16 +62,7 @@ ) ) -Node = ( - Account - | Bytes - | LegacyTransaction - | Receipt - | Uint - | U256 - | Withdrawal - | None -) +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -190,7 +181,9 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, Withdrawal, U256)): + elif isinstance( + node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) + ): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -384,6 +377,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/bpo5/trie.py b/src/ethereum/forks/bpo5/trie.py index 2b0cf6bc3ed..e39160db4cb 100644 --- a/src/ethereum/forks/bpo5/trie.py +++ b/src/ethereum/forks/bpo5/trie.py @@ -62,16 +62,7 @@ ) ) -Node = ( - Account - | Bytes - | LegacyTransaction - | Receipt - | Uint - | U256 - | Withdrawal - | None -) +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -190,7 +181,9 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, Withdrawal, U256)): + elif isinstance( + node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) + ): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -384,6 +377,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/byzantium/trie.py b/src/ethereum/forks/byzantium/trie.py index 2858183a400..b7a8fc3573d 100644 --- a/src/ethereum/forks/byzantium/trie.py +++ b/src/ethereum/forks/byzantium/trie.py @@ -61,7 +61,7 @@ ) ) -Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None +Node = Account | Bytes | Transaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -179,7 +179,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256)): + elif isinstance(node, (Transaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -373,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/cancun/trie.py b/src/ethereum/forks/cancun/trie.py index bd2053ca227..768a4380894 100644 --- a/src/ethereum/forks/cancun/trie.py +++ b/src/ethereum/forks/cancun/trie.py @@ -62,16 +62,7 @@ ) ) -Node = ( - Account - | Bytes - | LegacyTransaction - | Receipt - | Uint - | U256 - | Withdrawal - | None -) +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -190,7 +181,9 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, Withdrawal, U256)): + elif isinstance( + node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) + ): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -384,6 +377,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/constantinople/trie.py b/src/ethereum/forks/constantinople/trie.py index 0ff06ea4ec7..4a3fabfdd0d 100644 --- a/src/ethereum/forks/constantinople/trie.py +++ b/src/ethereum/forks/constantinople/trie.py @@ -61,7 +61,7 @@ ) ) -Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None +Node = Account | Bytes | Transaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -179,7 +179,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256)): + elif isinstance(node, (Transaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -373,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/dao_fork/trie.py b/src/ethereum/forks/dao_fork/trie.py index 679922ff44d..82d45a0868f 100644 --- a/src/ethereum/forks/dao_fork/trie.py +++ b/src/ethereum/forks/dao_fork/trie.py @@ -61,7 +61,7 @@ ) ) -Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None +Node = Account | Bytes | Transaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -179,7 +179,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256)): + elif isinstance(node, (Transaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -373,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/frontier/trie.py b/src/ethereum/forks/frontier/trie.py index 55cb19a570d..d7665cccd86 100644 --- a/src/ethereum/forks/frontier/trie.py +++ b/src/ethereum/forks/frontier/trie.py @@ -25,6 +25,7 @@ Sequence, Tuple, TypeVar, + assert_never, assert_type, cast, ) @@ -60,7 +61,7 @@ ) ) -Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None +Node = Account | Bytes | Transaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -178,14 +179,12 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256)): + elif isinstance(node, (Transaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node else: - raise AssertionError( - f"encoding for {type(node)} is not currently implemented" - ) + assert_never(node) @dataclass @@ -374,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/gray_glacier/trie.py b/src/ethereum/forks/gray_glacier/trie.py index 21044c1a077..55dd03bc82f 100644 --- a/src/ethereum/forks/gray_glacier/trie.py +++ b/src/ethereum/forks/gray_glacier/trie.py @@ -61,7 +61,7 @@ ) ) -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | None +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -179,7 +179,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, U256)): + elif isinstance(node, (LegacyTransaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -373,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/homestead/trie.py b/src/ethereum/forks/homestead/trie.py index 331802a660b..a04cde22a4e 100644 --- a/src/ethereum/forks/homestead/trie.py +++ b/src/ethereum/forks/homestead/trie.py @@ -61,7 +61,7 @@ ) ) -Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None +Node = Account | Bytes | Transaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -179,7 +179,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256)): + elif isinstance(node, (Transaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -373,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/istanbul/trie.py b/src/ethereum/forks/istanbul/trie.py index a040432bd70..47de5debd6c 100644 --- a/src/ethereum/forks/istanbul/trie.py +++ b/src/ethereum/forks/istanbul/trie.py @@ -61,7 +61,7 @@ ) ) -Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None +Node = Account | Bytes | Transaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -179,7 +179,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256)): + elif isinstance(node, (Transaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -373,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/london/trie.py b/src/ethereum/forks/london/trie.py index 0deeb2d3c9e..04b5a365e4b 100644 --- a/src/ethereum/forks/london/trie.py +++ b/src/ethereum/forks/london/trie.py @@ -61,7 +61,7 @@ ) ) -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | None +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -179,7 +179,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, U256)): + elif isinstance(node, (LegacyTransaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -373,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/muir_glacier/trie.py b/src/ethereum/forks/muir_glacier/trie.py index 70e0ba33c2a..5acd07500f8 100644 --- a/src/ethereum/forks/muir_glacier/trie.py +++ b/src/ethereum/forks/muir_glacier/trie.py @@ -61,7 +61,7 @@ ) ) -Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None +Node = Account | Bytes | Transaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -179,7 +179,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256)): + elif isinstance(node, (Transaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -373,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/osaka/trie.py b/src/ethereum/forks/osaka/trie.py index 7ad9a10f1c9..c0cf15e0ac5 100644 --- a/src/ethereum/forks/osaka/trie.py +++ b/src/ethereum/forks/osaka/trie.py @@ -62,16 +62,7 @@ ) ) -Node = ( - Account - | Bytes - | LegacyTransaction - | Receipt - | Uint - | U256 - | Withdrawal - | None -) +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -190,7 +181,9 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, Withdrawal, U256)): + elif isinstance( + node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) + ): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -384,6 +377,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/paris/trie.py b/src/ethereum/forks/paris/trie.py index ccd84fd0c1b..2adda05edc8 100644 --- a/src/ethereum/forks/paris/trie.py +++ b/src/ethereum/forks/paris/trie.py @@ -62,7 +62,7 @@ ) ) -Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | None +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -180,7 +180,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, U256)): + elif isinstance(node, (LegacyTransaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -374,6 +374,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/prague/trie.py b/src/ethereum/forks/prague/trie.py index fd43ae154dc..8e7c9555b4c 100644 --- a/src/ethereum/forks/prague/trie.py +++ b/src/ethereum/forks/prague/trie.py @@ -62,16 +62,7 @@ ) ) -Node = ( - Account - | Bytes - | LegacyTransaction - | Receipt - | Uint - | U256 - | Withdrawal - | None -) +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -190,7 +181,9 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, Withdrawal, U256)): + elif isinstance( + node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) + ): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -384,6 +377,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/shanghai/trie.py b/src/ethereum/forks/shanghai/trie.py index 13723b29cf3..d434c63faa4 100644 --- a/src/ethereum/forks/shanghai/trie.py +++ b/src/ethereum/forks/shanghai/trie.py @@ -62,16 +62,7 @@ ) ) -Node = ( - Account - | Bytes - | LegacyTransaction - | Receipt - | Uint - | U256 - | Withdrawal - | None -) +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | Withdrawal K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -190,7 +181,9 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (LegacyTransaction, Receipt, Withdrawal, U256)): + elif isinstance( + node, (LegacyTransaction, Receipt, Withdrawal, U256, Uint) + ): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -384,6 +377,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/spurious_dragon/trie.py b/src/ethereum/forks/spurious_dragon/trie.py index fce2ff05bfd..d9d5564fb8d 100644 --- a/src/ethereum/forks/spurious_dragon/trie.py +++ b/src/ethereum/forks/spurious_dragon/trie.py @@ -61,7 +61,7 @@ ) ) -Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None +Node = Account | Bytes | Transaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -179,7 +179,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256)): + elif isinstance(node, (Transaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -373,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": diff --git a/src/ethereum/forks/tangerine_whistle/trie.py b/src/ethereum/forks/tangerine_whistle/trie.py index a7580519410..bd652ffc5d2 100644 --- a/src/ethereum/forks/tangerine_whistle/trie.py +++ b/src/ethereum/forks/tangerine_whistle/trie.py @@ -61,7 +61,7 @@ ) ) -Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None +Node = Account | Bytes | Transaction | Receipt | Uint | U256 K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -179,7 +179,7 @@ def encode_node(node: Node, storage_root: Optional[Bytes] = None) -> Bytes: if isinstance(node, Account): assert storage_root is not None return encode_account(node, storage_root) - elif isinstance(node, (Transaction, Receipt, U256)): + elif isinstance(node, (Transaction, Receipt, U256, Uint)): return rlp.encode(node) elif isinstance(node, Bytes): return node @@ -373,6 +373,8 @@ def _prepare_trie( assert get_storage_root is not None address = Address(preimage) encoded_value = encode_node(value, get_storage_root(address)) + elif value is None: + raise AssertionError("cannot encode `None`") else: encoded_value = encode_node(value) if encoded_value == b"": From 9ec843ea4c5d36d2cd6933f153463eaff85cccfd Mon Sep 17 00:00:00 2001 From: danceratopz Date: Tue, 31 Mar 2026 00:01:16 +0200 Subject: [PATCH 2/3] fix(ci): use master client builds for benchmark genesis extraction (#2597) --- .github/actions/build-benchmark-genesis/action.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/build-benchmark-genesis/action.yaml b/.github/actions/build-benchmark-genesis/action.yaml index de623da8b6c..1838ed22c91 100644 --- a/.github/actions/build-benchmark-genesis/action.yaml +++ b/.github/actions/build-benchmark-genesis/action.yaml @@ -55,7 +55,7 @@ runs: uses: ./.github/actions/start-hive-dev with: clients: besu,go-ethereum,nethermind - client-file: .github/configs/hive/latest.yaml + client-file: .github/configs/hive/master.yaml hive-path: hive - name: Extract genesis configs From 35fd28331387601906ade0f74b5029674710471a Mon Sep 17 00:00:00 2001 From: danceratopz Date: Tue, 31 Mar 2026 00:31:58 +0200 Subject: [PATCH 3/3] chore(ci): add configurable client and verbose logging to hive-consume workflow (#2590) * fix(ci): add configurable client and verbose logging to hive-consume workflow Enable debugging Besu startup failures (#2553) by parameterizing the hive client and config file via workflow_dispatch inputs, adding verbose logging flags, and uploading hive workspace logs as artifacts. * ci: trigger hive-consume workflow --- .github/workflows/hive-consume.yaml | 43 +++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/.github/workflows/hive-consume.yaml b/.github/workflows/hive-consume.yaml index a2e50d79be8..d57778086f4 100644 --- a/.github/workflows/hive-consume.yaml +++ b/.github/workflows/hive-consume.yaml @@ -31,6 +31,14 @@ on: description: "Space-separated list of Docker images to cache" required: false default: "docker.io/ethereum/client-go:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" + client: + description: "Hive client to test (e.g., go-ethereum, besu)" + required: false + default: "go-ethereum" + client_file: + description: "Client config file name under .github/configs/hive/ (e.g., latest.yaml, master.yaml)" + required: false + default: "latest.yaml" workflow_call: inputs: docker_images: @@ -38,6 +46,16 @@ on: required: false type: string default: "docker.io/ethereum/client-go:latest docker.io/alpine:latest docker.io/library/golang:1-alpine" + client: + description: "Hive client to test (e.g., go-ethereum, besu)" + required: false + type: string + default: "go-ethereum" + client_file: + description: "Client config file name under .github/configs/hive/ (e.g., latest.yaml, master.yaml)" + required: false + type: string + default: "latest.yaml" concurrency: group: hive-consume-${{ github.workflow }}-${{ github.ref || github.run_id }} @@ -64,6 +82,9 @@ jobs: name: ${{ matrix.name }} needs: cache-docker-images runs-on: [self-hosted-ghr, size-l-x64] + env: + CLIENT: ${{ inputs.client || 'go-ethereum' }} + CLIENT_FILE: ${{ inputs.client_file || 'latest.yaml' }} strategy: fail-fast: true matrix: @@ -133,10 +154,12 @@ jobs: cd hive ./hive --sim '${{ matrix.simulator }}' \ --sim.parallelism=1 \ - --client go-ethereum \ - --client-file ../execution-specs/.github/configs/hive/latest.yaml \ + --client ${{ env.CLIENT }} \ + --client-file ../execution-specs/.github/configs/hive/${{ env.CLIENT_FILE }} \ --sim.buildarg fixtures=${{ env.FIXTURES_URL }} \ --sim.limit="${{ matrix.sim_limit }}" \ + --sim.loglevel=5 \ + --docker.buildoutput \ --docker.output - name: Build Hive client images @@ -144,8 +167,8 @@ jobs: run: | cd hive ./hive \ - --client go-ethereum \ - --client-file ../execution-specs/.github/configs/hive/latest.yaml \ + --client ${{ env.CLIENT }} \ + --client-file ../execution-specs/.github/configs/hive/${{ env.CLIENT_FILE }} \ --docker.buildoutput timeout-minutes: 10 @@ -154,8 +177,8 @@ jobs: id: start-hive uses: ./execution-specs/.github/actions/start-hive-dev with: - clients: go-ethereum - client-file: execution-specs/.github/configs/hive/latest.yaml + clients: ${{ env.CLIENT }} + client-file: execution-specs/.github/configs/hive/${{ env.CLIENT_FILE }} hive-path: hive timeout: "30" @@ -167,3 +190,11 @@ jobs: run: | uv sync --all-extras uv run consume ${{ matrix.consume_command }} --input ${{ env.FIXTURES_URL }} -k "${{ matrix.test_filter }}" + + - name: Upload Hive logs + if: always() + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: hive-logs-${{ matrix.name }} + path: hive/workspace/ + retention-days: 7