From bf3789ceedc5e7a0d042e1f2063174d8296c612c Mon Sep 17 00:00:00 2001 From: carsons-eels Date: Thu, 20 Mar 2025 20:24:18 -0400 Subject: [PATCH] Python 3.11 refactors - refactored assert_type import from typing_extensions to typing - refactored Union to use primitive type offered by 3.10 --- src/ethereum/arrow_glacier/blocks.py | 8 +- src/ethereum/arrow_glacier/fork.py | 6 +- src/ethereum/arrow_glacier/transactions.py | 18 +- src/ethereum/arrow_glacier/trie.py | 11 +- src/ethereum/arrow_glacier/utils/address.py | 4 +- src/ethereum/arrow_glacier/vm/__init__.py | 8 +- src/ethereum/berlin/blocks.py | 8 +- src/ethereum/berlin/fork.py | 6 +- src/ethereum/berlin/transactions.py | 14 +- src/ethereum/berlin/trie.py | 11 +- src/ethereum/berlin/utils/address.py | 4 +- src/ethereum/berlin/vm/__init__.py | 8 +- src/ethereum/byzantium/transactions.py | 3 +- src/ethereum/byzantium/trie.py | 7 +- src/ethereum/byzantium/utils/address.py | 4 +- src/ethereum/byzantium/vm/__init__.py | 4 +- src/ethereum/cancun/blocks.py | 8 +- src/ethereum/cancun/fork.py | 6 +- src/ethereum/cancun/transactions.py | 26 +- src/ethereum/cancun/trie.py | 24 +- src/ethereum/cancun/utils/address.py | 4 +- src/ethereum/cancun/vm/__init__.py | 10 +- src/ethereum/constantinople/transactions.py | 3 +- src/ethereum/constantinople/trie.py | 12 +- src/ethereum/constantinople/utils/address.py | 4 +- src/ethereum/constantinople/vm/__init__.py | 4 +- src/ethereum/crypto/finite_field.py | 403 ++++++++++++++++++ src/ethereum/dao_fork/transactions.py | 3 +- src/ethereum/dao_fork/trie.py | 7 +- src/ethereum/dao_fork/utils/address.py | 4 +- src/ethereum/dao_fork/vm/__init__.py | 4 +- src/ethereum/ethash.py | 4 +- src/ethereum/frontier/transactions.py | 3 +- src/ethereum/frontier/trie.py | 7 +- src/ethereum/frontier/utils/address.py | 4 +- src/ethereum/frontier/vm/__init__.py | 4 +- src/ethereum/gray_glacier/blocks.py | 8 +- src/ethereum/gray_glacier/fork.py | 6 +- src/ethereum/gray_glacier/transactions.py | 18 +- src/ethereum/gray_glacier/trie.py | 12 +- src/ethereum/gray_glacier/utils/address.py | 4 +- src/ethereum/gray_glacier/vm/__init__.py | 8 +- src/ethereum/homestead/transactions.py | 3 +- src/ethereum/homestead/trie.py | 7 +- src/ethereum/homestead/utils/address.py | 4 +- src/ethereum/homestead/vm/__init__.py | 4 +- src/ethereum/istanbul/transactions.py | 3 +- src/ethereum/istanbul/trie.py | 7 +- src/ethereum/istanbul/utils/address.py | 4 +- src/ethereum/istanbul/vm/__init__.py | 4 +- src/ethereum/london/blocks.py | 8 +- src/ethereum/london/fork.py | 6 +- src/ethereum/london/transactions.py | 18 +- src/ethereum/london/trie.py | 11 +- src/ethereum/london/utils/address.py | 4 +- src/ethereum/london/vm/__init__.py | 8 +- src/ethereum/muir_glacier/transactions.py | 3 +- src/ethereum/muir_glacier/trie.py | 7 +- src/ethereum/muir_glacier/utils/address.py | 4 +- src/ethereum/muir_glacier/vm/__init__.py | 4 +- src/ethereum/paris/blocks.py | 8 +- src/ethereum/paris/fork.py | 6 +- src/ethereum/paris/transactions.py | 18 +- src/ethereum/paris/trie.py | 11 +- src/ethereum/paris/utils/address.py | 4 +- src/ethereum/paris/vm/__init__.py | 8 +- src/ethereum/prague/blocks.py | 8 +- src/ethereum/prague/fork.py | 6 +- src/ethereum/prague/transactions.py | 28 +- src/ethereum/prague/trie.py | 22 +- src/ethereum/prague/utils/address.py | 4 +- src/ethereum/prague/vm/__init__.py | 10 +- .../bls12_381/__init__.py | 14 +- src/ethereum/shanghai/blocks.py | 8 +- src/ethereum/shanghai/fork.py | 6 +- src/ethereum/shanghai/transactions.py | 18 +- src/ethereum/shanghai/trie.py | 24 +- src/ethereum/shanghai/utils/address.py | 4 +- src/ethereum/shanghai/vm/__init__.py | 10 +- src/ethereum/spurious_dragon/transactions.py | 3 +- src/ethereum/spurious_dragon/trie.py | 7 +- src/ethereum/spurious_dragon/utils/address.py | 4 +- src/ethereum/spurious_dragon/vm/__init__.py | 4 +- .../tangerine_whistle/transactions.py | 3 +- src/ethereum/tangerine_whistle/trie.py | 7 +- .../tangerine_whistle/utils/address.py | 4 +- src/ethereum/tangerine_whistle/vm/__init__.py | 4 +- src/ethereum/trace.py | 24 +- src/ethereum/utils/byte.py | 6 +- tests/helpers/load_state_tests.py | 4 +- tests/test_rlp.py | 6 +- 91 files changed, 733 insertions(+), 393 deletions(-) create mode 100644 src/ethereum/crypto/finite_field.py diff --git a/src/ethereum/arrow_glacier/blocks.py b/src/ethereum/arrow_glacier/blocks.py index 2d75a2aa1b..c37a5630d6 100644 --- a/src/ethereum/arrow_glacier/blocks.py +++ b/src/ethereum/arrow_glacier/blocks.py @@ -9,7 +9,7 @@ chain. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes8, Bytes32 @@ -59,7 +59,7 @@ class Block: """ header: Header - transactions: Tuple[Union[Bytes, LegacyTransaction], ...] + transactions: Tuple[Bytes | LegacyTransaction, ...] ommers: Tuple[Header, ...] @@ -88,7 +88,7 @@ class Receipt: logs: Tuple[Log, ...] -def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: +def encode_receipt(tx: Transaction, receipt: Receipt) -> Bytes | Receipt: """ Encodes a receipt. """ @@ -100,7 +100,7 @@ def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: return receipt -def decode_receipt(receipt: Union[Bytes, Receipt]) -> Receipt: +def decode_receipt(receipt: Bytes | Receipt) -> Receipt: """ Decodes a receipt. """ diff --git a/src/ethereum/arrow_glacier/fork.py b/src/ethereum/arrow_glacier/fork.py index effbcaebec..02b1a8ca56 100644 --- a/src/ethereum/arrow_glacier/fork.py +++ b/src/ethereum/arrow_glacier/fork.py @@ -13,7 +13,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -482,7 +482,7 @@ def make_receipt( error: Optional[EthereumException], cumulative_gas_used: Uint, logs: Tuple[Log, ...], -) -> Union[Bytes, Receipt]: +) -> Bytes | Receipt: """ Make the receipt for a transaction that was executed. @@ -515,7 +515,7 @@ def make_receipt( def apply_body( block_env: vm.BlockEnvironment, - transactions: Tuple[Union[LegacyTransaction, Bytes], ...], + transactions: Tuple[LegacyTransaction | Bytes, ...], ommers: Tuple[Header, ...], ) -> vm.BlockOutput: """ diff --git a/src/ethereum/arrow_glacier/transactions.py b/src/ethereum/arrow_glacier/transactions.py index 285a7257c0..84907bd3ea 100644 --- a/src/ethereum/arrow_glacier/transactions.py +++ b/src/ethereum/arrow_glacier/transactions.py @@ -4,7 +4,7 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0, Bytes32 @@ -36,7 +36,7 @@ class LegacyTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 @@ -67,7 +67,7 @@ class AccessListTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -88,7 +88,7 @@ class FeeMarketTransaction: max_priority_fee_per_gas: Uint max_fee_per_gas: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -97,12 +97,10 @@ class FeeMarketTransaction: s: U256 -Transaction = Union[ - LegacyTransaction, AccessListTransaction, FeeMarketTransaction -] +Transaction = LegacyTransaction | AccessListTransaction | FeeMarketTransaction -def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: +def encode_transaction(tx: Transaction) -> LegacyTransaction | Bytes: """ Encode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -116,7 +114,7 @@ def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: raise Exception(f"Unable to encode transaction of type {type(tx)}") -def decode_transaction(tx: Union[LegacyTransaction, Bytes]) -> Transaction: +def decode_transaction(tx: LegacyTransaction | Bytes) -> Transaction: """ Decode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -400,7 +398,7 @@ def signing_hash_1559(tx: FeeMarketTransaction) -> Hash32: ) -def get_transaction_hash(tx: Union[Bytes, LegacyTransaction]) -> Hash32: +def get_transaction_hash(tx: Bytes | LegacyTransaction) -> Hash32: """ Parameters ---------- diff --git a/src/ethereum/arrow_glacier/trie.py b/src/ethereum/arrow_glacier/trie.py index 2b09d4c771..e44d1dcdc6 100644 --- a/src/ethereum/arrow_glacier/trie.py +++ b/src/ethereum/arrow_glacier/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.crypto.hash import keccak256 from ethereum.london import trie as previous_trie @@ -63,15 +62,15 @@ ) ) -Node = Union[Account, Bytes, LegacyTransaction, Receipt, Uint, U256, None] +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", Optional[Account], Optional[Bytes], Bytes, - Optional[Union[LegacyTransaction, Bytes]], - Optional[Union[Receipt, Bytes]], + Optional[LegacyTransaction | Bytes], + Optional[Receipt | Bytes], Uint, U256, ) @@ -124,7 +123,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/arrow_glacier/utils/address.py b/src/ethereum/arrow_glacier/utils/address.py index a19077d4ea..78001d7167 100644 --- a/src/ethereum/arrow_glacier/utils/address.py +++ b/src/ethereum/arrow_glacier/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this arrow_glacier version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.bytes import Bytes32 from ethereum_types.numeric import U256, Uint @@ -24,7 +22,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/arrow_glacier/vm/__init__.py b/src/ethereum/arrow_glacier/vm/__init__.py index ce60ea1105..ca51283db1 100644 --- a/src/ethereum/arrow_glacier/vm/__init__.py +++ b/src/ethereum/arrow_glacier/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0, Bytes32 from ethereum_types.numeric import U64, U256, Uint @@ -71,9 +71,9 @@ class BlockOutput: block_gas_used: Uint = Uint(0) transactions_trie: Trie[ - Bytes, Optional[Union[Bytes, LegacyTransaction]] + Bytes, Optional[Bytes | LegacyTransaction] ] = field(default_factory=lambda: Trie(secured=False, default=None)) - receipts_trie: Trie[Bytes, Optional[Union[Bytes, Receipt]]] = field( + receipts_trie: Trie[Bytes, Optional[Bytes | Receipt]] = field( default_factory=lambda: Trie(secured=False, default=None) ) receipt_keys: Tuple[Bytes, ...] = field(default_factory=tuple) @@ -105,7 +105,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/berlin/blocks.py b/src/ethereum/berlin/blocks.py index 17b3ebe909..46c47683a0 100644 --- a/src/ethereum/berlin/blocks.py +++ b/src/ethereum/berlin/blocks.py @@ -9,7 +9,7 @@ chain. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes8, Bytes32 @@ -53,7 +53,7 @@ class Block: """ header: Header - transactions: Tuple[Union[Bytes, LegacyTransaction], ...] + transactions: Tuple[Bytes | LegacyTransaction, ...] ommers: Tuple[Header, ...] @@ -82,7 +82,7 @@ class Receipt: logs: Tuple[Log, ...] -def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: +def encode_receipt(tx: Transaction, receipt: Receipt) -> Bytes | Receipt: """ Encodes a receipt. """ @@ -92,7 +92,7 @@ def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: return receipt -def decode_receipt(receipt: Union[Bytes, Receipt]) -> Receipt: +def decode_receipt(receipt: Bytes | Receipt) -> Receipt: """ Decodes a receipt. """ diff --git a/src/ethereum/berlin/fork.py b/src/ethereum/berlin/fork.py index 40530aa165..41a970e508 100644 --- a/src/ethereum/berlin/fork.py +++ b/src/ethereum/berlin/fork.py @@ -12,7 +12,7 @@ Entry point for the Ethereum specification. """ from dataclasses import dataclass -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -389,7 +389,7 @@ def make_receipt( error: Optional[EthereumException], cumulative_gas_used: Uint, logs: Tuple[Log, ...], -) -> Union[Bytes, Receipt]: +) -> Bytes | Receipt: """ Make the receipt for a transaction that was executed. @@ -422,7 +422,7 @@ def make_receipt( def apply_body( block_env: vm.BlockEnvironment, - transactions: Tuple[Union[LegacyTransaction, Bytes], ...], + transactions: Tuple[LegacyTransaction | Bytes, ...], ommers: Tuple[Header, ...], ) -> vm.BlockOutput: """ diff --git a/src/ethereum/berlin/transactions.py b/src/ethereum/berlin/transactions.py index 0a756caad1..31e55cb42d 100644 --- a/src/ethereum/berlin/transactions.py +++ b/src/ethereum/berlin/transactions.py @@ -4,7 +4,7 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0, Bytes32 @@ -36,7 +36,7 @@ class LegacyTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 @@ -67,7 +67,7 @@ class AccessListTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -76,10 +76,10 @@ class AccessListTransaction: s: U256 -Transaction = Union[LegacyTransaction, AccessListTransaction] +Transaction = LegacyTransaction | AccessListTransaction -def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: +def encode_transaction(tx: Transaction) -> LegacyTransaction | Bytes: """ Encode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -91,7 +91,7 @@ def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: raise Exception(f"Unable to encode transaction of type {type(tx)}") -def decode_transaction(tx: Union[LegacyTransaction, Bytes]) -> Transaction: +def decode_transaction(tx: LegacyTransaction | Bytes) -> Transaction: """ Decode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -334,7 +334,7 @@ def signing_hash_2930(tx: AccessListTransaction) -> Hash32: ) -def get_transaction_hash(tx: Union[Bytes, LegacyTransaction]) -> Hash32: +def get_transaction_hash(tx: Bytes | LegacyTransaction) -> Hash32: """ Parameters ---------- diff --git a/src/ethereum/berlin/trie.py b/src/ethereum/berlin/trie.py index 306e930c4b..bdcbb7358f 100644 --- a/src/ethereum/berlin/trie.py +++ b/src/ethereum/berlin/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.crypto.hash import keccak256 from ethereum.muir_glacier import trie as previous_trie @@ -63,15 +62,15 @@ ) ) -Node = Union[Account, Bytes, LegacyTransaction, Receipt, Uint, U256, None] +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", Optional[Account], Optional[Bytes], Bytes, - Optional[Union[LegacyTransaction, Bytes]], - Optional[Union[Receipt, Bytes]], + Optional[LegacyTransaction | Bytes], + Optional[Receipt | Bytes], Uint, U256, ) @@ -124,7 +123,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/berlin/utils/address.py b/src/ethereum/berlin/utils/address.py index c77bd34d99..b34265ed7b 100644 --- a/src/ethereum/berlin/utils/address.py +++ b/src/ethereum/berlin/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this berlin version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.bytes import Bytes32 from ethereum_types.numeric import U256, Uint @@ -24,7 +22,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/berlin/vm/__init__.py b/src/ethereum/berlin/vm/__init__.py index 568cd21785..9ba1fcbe2d 100644 --- a/src/ethereum/berlin/vm/__init__.py +++ b/src/ethereum/berlin/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0, Bytes32 from ethereum_types.numeric import U64, U256, Uint @@ -70,9 +70,9 @@ class BlockOutput: block_gas_used: Uint = Uint(0) transactions_trie: Trie[ - Bytes, Optional[Union[Bytes, LegacyTransaction]] + Bytes, Optional[Bytes | LegacyTransaction] ] = field(default_factory=lambda: Trie(secured=False, default=None)) - receipts_trie: Trie[Bytes, Optional[Union[Bytes, Receipt]]] = field( + receipts_trie: Trie[Bytes, Optional[Bytes | Receipt]] = field( default_factory=lambda: Trie(secured=False, default=None) ) receipt_keys: Tuple[Bytes, ...] = field(default_factory=tuple) @@ -104,7 +104,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/byzantium/transactions.py b/src/ethereum/byzantium/transactions.py index 65e622b5e1..2e2fbca845 100644 --- a/src/ethereum/byzantium/transactions.py +++ b/src/ethereum/byzantium/transactions.py @@ -4,7 +4,6 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Union from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0 @@ -33,7 +32,7 @@ class Transaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 diff --git a/src/ethereum/byzantium/trie.py b/src/ethereum/byzantium/trie.py index 8f618e0026..3d22558d12 100644 --- a/src/ethereum/byzantium/trie.py +++ b/src/ethereum/byzantium/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.crypto.hash import keccak256 from ethereum.spurious_dragon import trie as previous_trie @@ -63,7 +62,7 @@ ) ) -Node = Union[Account, Bytes, Transaction, Receipt, Uint, U256, None] +Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -124,7 +123,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/byzantium/utils/address.py b/src/ethereum/byzantium/utils/address.py index 386c13bff2..0ec3d5d532 100644 --- a/src/ethereum/byzantium/utils/address.py +++ b/src/ethereum/byzantium/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this byzantium version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.numeric import U256, Uint @@ -23,7 +21,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/byzantium/vm/__init__.py b/src/ethereum/byzantium/vm/__init__.py index 89d41710a9..afaa32ec28 100644 --- a/src/ethereum/byzantium/vm/__init__.py +++ b/src/ethereum/byzantium/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U64, U256, Uint @@ -102,7 +102,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/cancun/blocks.py b/src/ethereum/cancun/blocks.py index 1c600aae0d..966e0055e7 100644 --- a/src/ethereum/cancun/blocks.py +++ b/src/ethereum/cancun/blocks.py @@ -9,7 +9,7 @@ chain. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes8, Bytes32 @@ -77,7 +77,7 @@ class Block: """ header: Header - transactions: Tuple[Union[Bytes, LegacyTransaction], ...] + transactions: Tuple[Bytes | LegacyTransaction, ...] ommers: Tuple[Header, ...] withdrawals: Tuple[Withdrawal, ...] @@ -107,7 +107,7 @@ class Receipt: logs: Tuple[Log, ...] -def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: +def encode_receipt(tx: Transaction, receipt: Receipt) -> Bytes | Receipt: """ Encodes a receipt. """ @@ -121,7 +121,7 @@ def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: return receipt -def decode_receipt(receipt: Union[Bytes, Receipt]) -> Receipt: +def decode_receipt(receipt: Bytes | Receipt) -> Receipt: """ Decodes a receipt. """ diff --git a/src/ethereum/cancun/fork.py b/src/ethereum/cancun/fork.py index 09796505a8..7d3d436ec8 100644 --- a/src/ethereum/cancun/fork.py +++ b/src/ethereum/cancun/fork.py @@ -13,7 +13,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple, Union +from typing import List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -448,7 +448,7 @@ def make_receipt( error: Optional[EthereumException], cumulative_gas_used: Uint, logs: Tuple[Log, ...], -) -> Union[Bytes, Receipt]: +) -> Bytes | Receipt: """ Make the receipt for a transaction that was executed. @@ -578,7 +578,7 @@ def process_unchecked_system_transaction( def apply_body( block_env: vm.BlockEnvironment, - transactions: Tuple[Union[LegacyTransaction, Bytes], ...], + transactions: Tuple[LegacyTransaction | Bytes, ...], withdrawals: Tuple[Withdrawal, ...], ) -> vm.BlockOutput: """ diff --git a/src/ethereum/cancun/transactions.py b/src/ethereum/cancun/transactions.py index ae97ee26d8..e53d95f973 100644 --- a/src/ethereum/cancun/transactions.py +++ b/src/ethereum/cancun/transactions.py @@ -4,7 +4,7 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0, Bytes32 @@ -36,7 +36,7 @@ class LegacyTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 @@ -67,7 +67,7 @@ class AccessListTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -88,7 +88,7 @@ class FeeMarketTransaction: max_priority_fee_per_gas: Uint max_fee_per_gas: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -120,15 +120,15 @@ class BlobTransaction: s: U256 -Transaction = Union[ - LegacyTransaction, - AccessListTransaction, - FeeMarketTransaction, - BlobTransaction, -] +Transaction = ( + LegacyTransaction + | AccessListTransaction + | FeeMarketTransaction + | BlobTransaction +) -def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: +def encode_transaction(tx: Transaction) -> LegacyTransaction | Bytes: """ Encode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -144,7 +144,7 @@ def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: raise Exception(f"Unable to encode transaction of type {type(tx)}") -def decode_transaction(tx: Union[LegacyTransaction, Bytes]) -> Transaction: +def decode_transaction(tx: LegacyTransaction | Bytes) -> Transaction: """ Decode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -479,7 +479,7 @@ def signing_hash_4844(tx: BlobTransaction) -> Hash32: ) -def get_transaction_hash(tx: Union[Bytes, LegacyTransaction]) -> Hash32: +def get_transaction_hash(tx: Bytes | LegacyTransaction) -> Hash32: """ Parameters ---------- diff --git a/src/ethereum/cancun/trie.py b/src/ethereum/cancun/trie.py index 8afe1281c0..838020342f 100644 --- a/src/ethereum/cancun/trie.py +++ b/src/ethereum/cancun/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.crypto.hash import keccak256 from ethereum.shanghai import trie as previous_trie @@ -63,18 +62,25 @@ ) ) -Node = Union[ - Account, Bytes, LegacyTransaction, Receipt, Uint, U256, Withdrawal, None -] +Node = ( + Account + | Bytes + | LegacyTransaction + | Receipt + | Uint + | U256 + | Withdrawal + | None +) K = TypeVar("K", bound=Bytes) V = TypeVar( "V", Optional[Account], Optional[Bytes], Bytes, - Optional[Union[LegacyTransaction, Bytes]], - Optional[Union[Receipt, Bytes]], - Optional[Union[Withdrawal, Bytes]], + Optional[LegacyTransaction | Bytes], + Optional[Receipt | Bytes], + Optional[Withdrawal | Bytes], Uint, U256, ) @@ -127,7 +133,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/cancun/utils/address.py b/src/ethereum/cancun/utils/address.py index 1bfbd2326c..6e0e553dbe 100644 --- a/src/ethereum/cancun/utils/address.py +++ b/src/ethereum/cancun/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this cancun version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.bytes import Bytes32 from ethereum_types.numeric import U256, Uint @@ -24,7 +22,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/cancun/vm/__init__.py b/src/ethereum/cancun/vm/__init__.py index d73c4f8cde..734d6acfb2 100644 --- a/src/ethereum/cancun/vm/__init__.py +++ b/src/ethereum/cancun/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0, Bytes32 from ethereum_types.numeric import U64, U256, Uint @@ -76,14 +76,14 @@ class BlockOutput: block_gas_used: Uint = Uint(0) transactions_trie: Trie[ - Bytes, Optional[Union[Bytes, LegacyTransaction]] + Bytes, Optional[Bytes | LegacyTransaction] ] = field(default_factory=lambda: Trie(secured=False, default=None)) - receipts_trie: Trie[Bytes, Optional[Union[Bytes, Receipt]]] = field( + receipts_trie: Trie[Bytes, Optional[Bytes | Receipt]] = field( default_factory=lambda: Trie(secured=False, default=None) ) receipt_keys: Tuple[Bytes, ...] = field(default_factory=tuple) block_logs: Tuple[Log, ...] = field(default_factory=tuple) - withdrawals_trie: Trie[Bytes, Optional[Union[Bytes, Withdrawal]]] = field( + withdrawals_trie: Trie[Bytes, Optional[Bytes | Withdrawal]] = field( default_factory=lambda: Trie(secured=False, default=None) ) blob_gas_used: U64 = U64(0) @@ -116,7 +116,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/constantinople/transactions.py b/src/ethereum/constantinople/transactions.py index 65e622b5e1..2e2fbca845 100644 --- a/src/ethereum/constantinople/transactions.py +++ b/src/ethereum/constantinople/transactions.py @@ -4,7 +4,6 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Union from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0 @@ -33,7 +32,7 @@ class Transaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 diff --git a/src/ethereum/constantinople/trie.py b/src/ethereum/constantinople/trie.py index 9999eefb76..1c684c2122 100644 --- a/src/ethereum/constantinople/trie.py +++ b/src/ethereum/constantinople/trie.py @@ -26,16 +26,10 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) -from ethereum_rlp import Extended, rlp -from ethereum_types.bytes import Bytes -from ethereum_types.frozen import slotted_freezable -from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type - from ethereum.byzantium import trie as previous_trie from ethereum.crypto.hash import keccak256 from ethereum.utils.hexadecimal import hex_to_bytes @@ -63,7 +57,7 @@ ) ) -Node = Union[Account, Bytes, Transaction, Receipt, Uint, U256, None] +Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -124,7 +118,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/constantinople/utils/address.py b/src/ethereum/constantinople/utils/address.py index 96c72cbc85..93df9485f4 100644 --- a/src/ethereum/constantinople/utils/address.py +++ b/src/ethereum/constantinople/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this constantinople version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.bytes import Bytes32 from ethereum_types.numeric import U256, Uint @@ -24,7 +22,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/constantinople/vm/__init__.py b/src/ethereum/constantinople/vm/__init__.py index 89d41710a9..afaa32ec28 100644 --- a/src/ethereum/constantinople/vm/__init__.py +++ b/src/ethereum/constantinople/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U64, U256, Uint @@ -102,7 +102,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/crypto/finite_field.py b/src/ethereum/crypto/finite_field.py new file mode 100644 index 0000000000..1e1fc6d5df --- /dev/null +++ b/src/ethereum/crypto/finite_field.py @@ -0,0 +1,403 @@ +""" +Finite Fields +^^^^^^^^^^^^^ +""" + +# flake8: noqa: D102, D105 + +from typing import Iterable, List, Tuple, Type, TypeVar, cast + +from ethereum_types.bytes import Bytes, Bytes32 +from typing_extensions import Protocol + +F = TypeVar("F", bound="Field") + + +class Field(Protocol): + """ + A type protocol for defining fields. + """ + + __slots__ = () + + @classmethod + def zero(cls: Type[F]) -> F: + ... + + @classmethod + def from_int(cls: Type[F], n: int) -> F: + ... + + def __radd__(self: F, left: F) -> F: + ... + + def __add__(self: F, right: F) -> F: + ... + + def __iadd__(self: F, right: F) -> F: + ... + + def __sub__(self: F, right: F) -> F: + ... + + def __rsub__(self: F, left: F) -> F: + ... + + def __mul__(self: F, right: F) -> F: + ... + + def __rmul__(self: F, left: F) -> F: + ... + + def __imul__(self: F, right: F) -> F: + ... + + def __pow__(self: F, exponent: int) -> F: + ... + + def __ipow__(self: F, right: int) -> F: + ... + + def __neg__(self: F) -> F: + ... + + def __truediv__(self: F, right: F) -> F: + ... + + +T = TypeVar("T", bound="PrimeField") + + +class PrimeField(int, Field): + """ + Superclass for integers modulo a prime. Not intended to be used + directly, but rather to be subclassed. + """ + + __slots__ = () + PRIME: int + + @classmethod + def from_be_bytes(cls: Type[T], buffer: "Bytes") -> T: + """ + Converts a sequence of bytes into a element of the field. + Parameters + ---------- + buffer : + Bytes to decode. + Returns + ------- + self : `T` + Unsigned integer decoded from `buffer`. + """ + return cls(int.from_bytes(buffer, "big")) + + @classmethod + def zero(cls: Type[T]) -> T: + return cls.__new__(cls, 0) + + @classmethod + def from_int(cls: Type[T], n: int) -> T: + return cls(n) + + def __new__(cls: Type[T], value: int) -> T: + return int.__new__(cls, value % cls.PRIME) + + def __radd__(self: T, left: T) -> T: # type: ignore[override] + return self.__add__(left) + + def __add__(self: T, right: T) -> T: # type: ignore[override] + if not isinstance(right, int): + return NotImplemented + + return self.__new__(type(self), int.__add__(self, right)) + + def __iadd__(self: T, right: T) -> T: # type: ignore[override] + return self.__add__(right) + + def __sub__(self: T, right: T) -> T: # type: ignore[override] + if not isinstance(right, int): + return NotImplemented + + return self.__new__(type(self), int.__sub__(self, right)) + + def __rsub__(self: T, left: T) -> T: # type: ignore[override] + if not isinstance(left, int): + return NotImplemented + + return self.__new__(type(self), int.__rsub__(self, left)) + + def __mul__(self: T, right: T) -> T: # type: ignore[override] + if not isinstance(right, int): + return NotImplemented + + return self.__new__(type(self), int.__mul__(self, right)) + + def __rmul__(self: T, left: T) -> T: # type: ignore[override] + return self.__mul__(left) + + def __imul__(self: T, right: T) -> T: # type: ignore[override] + return self.__mul__(right) + + __floordiv__ = None # type: ignore + __rfloordiv__ = None # type: ignore + __ifloordiv__ = None + __divmod__ = None # type: ignore + __rdivmod__ = None # type: ignore + + def __pow__(self: T, exponent: int) -> T: # type: ignore[override] + # For reasons that are unclear, self must be cast to int here under + # PyPy. + return self.__new__( + type(self), int.__pow__(int(self), exponent, self.PRIME) + ) + + __rpow__ = None # type: ignore + + def __ipow__(self: T, right: int) -> T: # type: ignore[override] + return self.__pow__(right) + + __and__ = None # type: ignore + __or__ = None # type: ignore + __xor__ = None # type: ignore + __rxor__ = None # type: ignore + __ixor__ = None + __rshift__ = None # type: ignore + __lshift__ = None # type: ignore + __irshift__ = None + __ilshift__ = None + + def __neg__(self: T) -> T: + return self.__new__(type(self), int.__neg__(self)) + + def __truediv__(self: T, right: T) -> T: # type: ignore[override] + return self * right.multiplicative_inverse() + + def multiplicative_inverse(self: T) -> T: + return self ** (-1) + + def to_be_bytes32(self) -> "Bytes32": + """ + Converts this arbitrarily sized unsigned integer into its big endian + representation with exactly 32 bytes. + Returns + ------- + big_endian : `Bytes32` + Big endian (most significant bits first) representation. + """ + return Bytes32(self.to_bytes(32, "big")) + + +U = TypeVar("U", bound="GaloisField") + + +class GaloisField(tuple, Field): + """ + Superclass for defining finite fields. Not intended to be used + directly, but rather to be subclassed. + + Fields are represented as `F_p[x]/(x^n + ...)` where the `MODULUS` is a + tuple of the non-leading coefficients of the defining polynomial. For + example `x^3 + 2x^2 + 3x + 4` is `(2, 3, 4)`. + + In practice the polynomial is likely to be sparse and you should overload + the `__mul__()` function to take advantage of this fact. + """ + + __slots__ = () + + PRIME: int + MODULUS: Tuple[int, ...] + FROBENIUS_COEFFICIENTS: Tuple["GaloisField", ...] + + @classmethod + def zero(cls: Type[U]) -> U: + return cls.__new__(cls, [0] * len(cls.MODULUS)) + + @classmethod + def from_int(cls: Type[U], n: int) -> U: + return cls.__new__(cls, [n] + [0] * (len(cls.MODULUS) - 1)) + + def __new__(cls: Type[U], iterable: Iterable[int]) -> U: + self = tuple.__new__(cls, (x % cls.PRIME for x in iterable)) + assert len(self) == len(cls.MODULUS) + return self + + def __add__(self: U, right: U) -> U: # type: ignore[override] + if not isinstance(right, type(self)): + return NotImplemented + + return self.__new__( + type(self), + ( + x + y + for (x, y) in cast(Iterable[Tuple[int, int]], zip(self, right)) + ), + ) + + def __radd__(self: U, left: U) -> U: + return self.__add__(left) + + def __iadd__(self: U, right: U) -> U: # type: ignore[override] + return self.__add__(right) + + def __sub__(self: U, right: U) -> U: + if not isinstance(right, type(self)): + return NotImplemented + + x: int + y: int + return self.__new__( + type(self), + ( + x - y + for (x, y) in cast(Iterable[Tuple[int, int]], zip(self, right)) + ), + ) + + def __rsub__(self: U, left: U) -> U: + if not isinstance(left, type(self)): + return NotImplemented + + return self.__new__( + type(self), + ( + x - y + for (x, y) in cast(Iterable[Tuple[int, int]], zip(left, self)) + ), + ) + + def __mul__(self: U, right: U) -> U: # type: ignore[override] + modulus = self.MODULUS + degree = len(modulus) + prime = self.PRIME + mul = [0] * (degree * 2) + + for i in range(degree): + for j in range(degree): + mul[i + j] += self[i] * right[j] + + for i in range(degree * 2 - 1, degree - 1, -1): + for j in range(i - degree, i): + mul[j] -= (mul[i] * modulus[degree - (i - j)]) % prime + + return self.__new__( + type(self), + mul[:degree], + ) + + def __rmul__(self: U, left: U) -> U: # type: ignore[override] + return self.__mul__(left) + + def __imul__(self: U, right: U) -> U: # type: ignore[override] + return self.__mul__(right) + + def __truediv__(self: U, right: U) -> U: + return self * right.multiplicative_inverse() + + def __neg__(self: U) -> U: + return self.__new__(type(self), (-a for a in self)) + + def scalar_mul(self: U, x: int) -> U: + """ + Multiply a field element by a integer. This is faster than using + `from_int()` and field multiplication. + """ + return self.__new__(type(self), (x * n for n in self)) + + def deg(self: U) -> int: + """ + This is a support function for `multiplicative_inverse()`. + """ + for i in range(len(self.MODULUS) - 1, -1, -1): + if self[i] != 0: + return i + raise ValueError("deg() does not support zero") + + def multiplicative_inverse(self: U) -> U: + """ + Calculate the multiplicative inverse. Uses the Euclidean algorithm. + """ + x2: List[int] + p = self.PRIME + x1, f1 = list(self.MODULUS), [0] * len(self) + x2, f2, d2 = list(self), [1] + [0] * (len(self) - 1), self.deg() + q_0 = pow(x2[d2], -1, p) + for i in range(d2): + x1[i + len(x1) - d2] = (x1[i + len(x1) - d2] - q_0 * x2[i]) % p + f1[i + len(x1) - d2] = (f1[i + len(x1) - d2] - q_0 * f2[i]) % p + for i in range(len(self.MODULUS) - 1, -1, -1): + if x1[i] != 0: + d1 = i + break + while True: + if d1 == 0: + ans = f1 + q = pow(x1[0], -1, self.PRIME) + for i in range(len(ans)): + ans[i] *= q + break + elif d2 == 0: + ans = f2 + q = pow(x2[0], -1, self.PRIME) + for i in range(len(ans)): + ans *= q + break + if d1 < d2: + q = x2[d2] * pow(x1[d1], -1, self.PRIME) + for i in range(len(self.MODULUS) - (d2 - d1)): + x2[i + (d2 - d1)] = (x2[i + (d2 - d1)] - q * x1[i]) % p + f2[i + (d2 - d1)] = (f2[i + (d2 - d1)] - q * f1[i]) % p + while x2[d2] == 0: + d2 -= 1 + else: + q = x1[d1] * pow(x2[d2], -1, self.PRIME) + for i in range(len(self.MODULUS) - (d1 - d2)): + x1[i + (d1 - d2)] = (x1[i + (d1 - d2)] - q * x2[i]) % p + f1[i + (d1 - d2)] = (f1[i + (d1 - d2)] - q * f2[i]) % p + while x1[d1] == 0: + d1 -= 1 + return self.__new__(type(self), ans) + + def __pow__(self: U, exponent: int) -> U: + degree = len(self.MODULUS) + if exponent < 0: + self = self.multiplicative_inverse() + exponent = -exponent + + res = self.__new__(type(self), [1] + [0] * (degree - 1)) + s = self + while exponent != 0: + if exponent % 2 == 1: + res *= s + s *= s + exponent //= 2 + return res + + def __ipow__(self: U, right: int) -> U: + return self.__pow__(right) + + @classmethod + def calculate_frobenius_coefficients(cls: Type[U]) -> Tuple[U, ...]: + """ + Calculate the coefficients needed by `frobenius()`. + """ + coefficients = [] + for i in range(len(cls.MODULUS)): + x = [0] * len(cls.MODULUS) + x[i] = 1 + coefficients.append(cls.__new__(cls, x) ** cls.PRIME) + return tuple(coefficients) + + def frobenius(self: U) -> U: + """ + Returns `self ** p`. This function is known as the Frobenius + endomorphism and has many special mathematical properties. In + particular it is extremely cheap to compute compared to other + exponentiations. + """ + ans = self.from_int(0) + a: int + for i, a in enumerate(self): + ans += cast(U, self.FROBENIUS_COEFFICIENTS[i]).scalar_mul(a) + return ans diff --git a/src/ethereum/dao_fork/transactions.py b/src/ethereum/dao_fork/transactions.py index 6761b34ca9..bb003b7673 100644 --- a/src/ethereum/dao_fork/transactions.py +++ b/src/ethereum/dao_fork/transactions.py @@ -4,7 +4,6 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Union from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0 @@ -33,7 +32,7 @@ class Transaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 diff --git a/src/ethereum/dao_fork/trie.py b/src/ethereum/dao_fork/trie.py index 83623062c5..29e1f963f0 100644 --- a/src/ethereum/dao_fork/trie.py +++ b/src/ethereum/dao_fork/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.crypto.hash import keccak256 from ethereum.homestead import trie as previous_trie @@ -63,7 +62,7 @@ ) ) -Node = Union[Account, Bytes, Transaction, Receipt, Uint, U256, None] +Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -124,7 +123,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/dao_fork/utils/address.py b/src/ethereum/dao_fork/utils/address.py index f9434e1dd0..68e3d97695 100644 --- a/src/ethereum/dao_fork/utils/address.py +++ b/src/ethereum/dao_fork/utils/address.py @@ -11,8 +11,6 @@ Address specific functions used in this Dao Fork version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.numeric import U256, Uint @@ -22,7 +20,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/dao_fork/vm/__init__.py b/src/ethereum/dao_fork/vm/__init__.py index 9485cdc84b..cf061104d0 100644 --- a/src/ethereum/dao_fork/vm/__init__.py +++ b/src/ethereum/dao_fork/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U64, U256, Uint @@ -101,7 +101,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/ethash.py b/src/ethereum/ethash.py index 490d729d20..0edffef602 100644 --- a/src/ethereum/ethash.py +++ b/src/ethereum/ethash.py @@ -26,7 +26,7 @@ [mem-hard]: https://en.wikipedia.org/wiki/Memory-hard_function """ -from typing import Callable, Tuple, Union +from typing import Callable, Tuple from ethereum_types.bytes import Bytes, Bytes8 from ethereum_types.numeric import U32, Uint, ulen @@ -249,7 +249,7 @@ def generate_cache(block_number: Uint) -> Tuple[Tuple[U32, ...], ...]: ) -def fnv(a: Union[Uint, U32], b: Union[Uint, U32]) -> U32: +def fnv(a: Uint | U32, b: Uint | U32) -> U32: """ A non-associative substitute for XOR, inspired by the [FNV] hash by Fowler, Noll, and Vo. See [`fnv_hash`], [`generate_dataset_item`], and diff --git a/src/ethereum/frontier/transactions.py b/src/ethereum/frontier/transactions.py index 99e6a6bb05..3f7bc2d5ac 100644 --- a/src/ethereum/frontier/transactions.py +++ b/src/ethereum/frontier/transactions.py @@ -4,7 +4,6 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Union from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0 @@ -32,7 +31,7 @@ class Transaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 diff --git a/src/ethereum/frontier/trie.py b/src/ethereum/frontier/trie.py index c7dec95462..f50f1cdd72 100644 --- a/src/ethereum/frontier/trie.py +++ b/src/ethereum/frontier/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.crypto.hash import keccak256 from ethereum.utils.hexadecimal import hex_to_bytes @@ -62,7 +61,7 @@ ) ) -Node = Union[Account, Bytes, Transaction, Receipt, Uint, U256, None] +Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -123,7 +122,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/frontier/utils/address.py b/src/ethereum/frontier/utils/address.py index aee29af13d..f33c2fd2bd 100644 --- a/src/ethereum/frontier/utils/address.py +++ b/src/ethereum/frontier/utils/address.py @@ -11,8 +11,6 @@ Address specific functions used in this frontier version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.numeric import U256, Uint @@ -22,7 +20,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/frontier/vm/__init__.py b/src/ethereum/frontier/vm/__init__.py index ca107b25a5..da80960de2 100644 --- a/src/ethereum/frontier/vm/__init__.py +++ b/src/ethereum/frontier/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U64, U256, Uint @@ -101,7 +101,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/gray_glacier/blocks.py b/src/ethereum/gray_glacier/blocks.py index 2d75a2aa1b..c37a5630d6 100644 --- a/src/ethereum/gray_glacier/blocks.py +++ b/src/ethereum/gray_glacier/blocks.py @@ -9,7 +9,7 @@ chain. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes8, Bytes32 @@ -59,7 +59,7 @@ class Block: """ header: Header - transactions: Tuple[Union[Bytes, LegacyTransaction], ...] + transactions: Tuple[Bytes | LegacyTransaction, ...] ommers: Tuple[Header, ...] @@ -88,7 +88,7 @@ class Receipt: logs: Tuple[Log, ...] -def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: +def encode_receipt(tx: Transaction, receipt: Receipt) -> Bytes | Receipt: """ Encodes a receipt. """ @@ -100,7 +100,7 @@ def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: return receipt -def decode_receipt(receipt: Union[Bytes, Receipt]) -> Receipt: +def decode_receipt(receipt: Bytes | Receipt) -> Receipt: """ Decodes a receipt. """ diff --git a/src/ethereum/gray_glacier/fork.py b/src/ethereum/gray_glacier/fork.py index 014aeca53e..4ab7c797ac 100644 --- a/src/ethereum/gray_glacier/fork.py +++ b/src/ethereum/gray_glacier/fork.py @@ -13,7 +13,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -482,7 +482,7 @@ def make_receipt( error: Optional[EthereumException], cumulative_gas_used: Uint, logs: Tuple[Log, ...], -) -> Union[Bytes, Receipt]: +) -> Bytes | Receipt: """ Make the receipt for a transaction that was executed. @@ -515,7 +515,7 @@ def make_receipt( def apply_body( block_env: vm.BlockEnvironment, - transactions: Tuple[Union[LegacyTransaction, Bytes], ...], + transactions: Tuple[LegacyTransaction | Bytes, ...], ommers: Tuple[Header, ...], ) -> vm.BlockOutput: """ diff --git a/src/ethereum/gray_glacier/transactions.py b/src/ethereum/gray_glacier/transactions.py index 285a7257c0..84907bd3ea 100644 --- a/src/ethereum/gray_glacier/transactions.py +++ b/src/ethereum/gray_glacier/transactions.py @@ -4,7 +4,7 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0, Bytes32 @@ -36,7 +36,7 @@ class LegacyTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 @@ -67,7 +67,7 @@ class AccessListTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -88,7 +88,7 @@ class FeeMarketTransaction: max_priority_fee_per_gas: Uint max_fee_per_gas: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -97,12 +97,10 @@ class FeeMarketTransaction: s: U256 -Transaction = Union[ - LegacyTransaction, AccessListTransaction, FeeMarketTransaction -] +Transaction = LegacyTransaction | AccessListTransaction | FeeMarketTransaction -def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: +def encode_transaction(tx: Transaction) -> LegacyTransaction | Bytes: """ Encode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -116,7 +114,7 @@ def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: raise Exception(f"Unable to encode transaction of type {type(tx)}") -def decode_transaction(tx: Union[LegacyTransaction, Bytes]) -> Transaction: +def decode_transaction(tx: LegacyTransaction | Bytes) -> Transaction: """ Decode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -400,7 +398,7 @@ def signing_hash_1559(tx: FeeMarketTransaction) -> Hash32: ) -def get_transaction_hash(tx: Union[Bytes, LegacyTransaction]) -> Hash32: +def get_transaction_hash(tx: Bytes | LegacyTransaction) -> Hash32: """ Parameters ---------- diff --git a/src/ethereum/gray_glacier/trie.py b/src/ethereum/gray_glacier/trie.py index 881f87aaec..f2978d2401 100644 --- a/src/ethereum/gray_glacier/trie.py +++ b/src/ethereum/gray_glacier/trie.py @@ -26,15 +26,13 @@ Sequence, Tuple, TypeVar, - Union, - cast, + assert_type, ) from ethereum_rlp import Extended, rlp from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.arrow_glacier import trie as previous_trie from ethereum.crypto.hash import keccak256 @@ -63,15 +61,15 @@ ) ) -Node = Union[Account, Bytes, LegacyTransaction, Receipt, Uint, U256, None] +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", Optional[Account], Optional[Bytes], Bytes, - Optional[Union[LegacyTransaction, Bytes]], - Optional[Union[Receipt, Bytes]], + Optional[LegacyTransaction | Bytes], + Optional[Receipt | Bytes], Uint, U256, ) @@ -124,7 +122,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/gray_glacier/utils/address.py b/src/ethereum/gray_glacier/utils/address.py index 35b219756c..f0c848a45b 100644 --- a/src/ethereum/gray_glacier/utils/address.py +++ b/src/ethereum/gray_glacier/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this gray_glacier version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.bytes import Bytes32 from ethereum_types.numeric import U256, Uint @@ -24,7 +22,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/gray_glacier/vm/__init__.py b/src/ethereum/gray_glacier/vm/__init__.py index ce60ea1105..ca51283db1 100644 --- a/src/ethereum/gray_glacier/vm/__init__.py +++ b/src/ethereum/gray_glacier/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0, Bytes32 from ethereum_types.numeric import U64, U256, Uint @@ -71,9 +71,9 @@ class BlockOutput: block_gas_used: Uint = Uint(0) transactions_trie: Trie[ - Bytes, Optional[Union[Bytes, LegacyTransaction]] + Bytes, Optional[Bytes | LegacyTransaction] ] = field(default_factory=lambda: Trie(secured=False, default=None)) - receipts_trie: Trie[Bytes, Optional[Union[Bytes, Receipt]]] = field( + receipts_trie: Trie[Bytes, Optional[Bytes | Receipt]] = field( default_factory=lambda: Trie(secured=False, default=None) ) receipt_keys: Tuple[Bytes, ...] = field(default_factory=tuple) @@ -105,7 +105,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/homestead/transactions.py b/src/ethereum/homestead/transactions.py index 6761b34ca9..bb003b7673 100644 --- a/src/ethereum/homestead/transactions.py +++ b/src/ethereum/homestead/transactions.py @@ -4,7 +4,6 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Union from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0 @@ -33,7 +32,7 @@ class Transaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 diff --git a/src/ethereum/homestead/trie.py b/src/ethereum/homestead/trie.py index 16e4cfcf92..0b8a8fb5f8 100644 --- a/src/ethereum/homestead/trie.py +++ b/src/ethereum/homestead/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.crypto.hash import keccak256 from ethereum.frontier import trie as previous_trie @@ -63,7 +62,7 @@ ) ) -Node = Union[Account, Bytes, Transaction, Receipt, Uint, U256, None] +Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -124,7 +123,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/homestead/utils/address.py b/src/ethereum/homestead/utils/address.py index a545a94d91..0d464921de 100644 --- a/src/ethereum/homestead/utils/address.py +++ b/src/ethereum/homestead/utils/address.py @@ -11,8 +11,6 @@ Address specific functions used in this homestead version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.numeric import U256, Uint @@ -22,7 +20,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/homestead/vm/__init__.py b/src/ethereum/homestead/vm/__init__.py index 9485cdc84b..cf061104d0 100644 --- a/src/ethereum/homestead/vm/__init__.py +++ b/src/ethereum/homestead/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U64, U256, Uint @@ -101,7 +101,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/istanbul/transactions.py b/src/ethereum/istanbul/transactions.py index 4f2f9efe6d..4501359874 100644 --- a/src/ethereum/istanbul/transactions.py +++ b/src/ethereum/istanbul/transactions.py @@ -4,7 +4,6 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Union from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0 @@ -33,7 +32,7 @@ class Transaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 diff --git a/src/ethereum/istanbul/trie.py b/src/ethereum/istanbul/trie.py index 902e723197..c9d7732c02 100644 --- a/src/ethereum/istanbul/trie.py +++ b/src/ethereum/istanbul/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.constantinople import trie as previous_trie from ethereum.crypto.hash import keccak256 @@ -63,7 +62,7 @@ ) ) -Node = Union[Account, Bytes, Transaction, Receipt, Uint, U256, None] +Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -124,7 +123,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/istanbul/utils/address.py b/src/ethereum/istanbul/utils/address.py index 8501d2066c..27a80c1931 100644 --- a/src/ethereum/istanbul/utils/address.py +++ b/src/ethereum/istanbul/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this istanbul version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.bytes import Bytes32 from ethereum_types.numeric import U256, Uint @@ -24,7 +22,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/istanbul/vm/__init__.py b/src/ethereum/istanbul/vm/__init__.py index 89d41710a9..afaa32ec28 100644 --- a/src/ethereum/istanbul/vm/__init__.py +++ b/src/ethereum/istanbul/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U64, U256, Uint @@ -102,7 +102,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/london/blocks.py b/src/ethereum/london/blocks.py index 2d75a2aa1b..c37a5630d6 100644 --- a/src/ethereum/london/blocks.py +++ b/src/ethereum/london/blocks.py @@ -9,7 +9,7 @@ chain. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes8, Bytes32 @@ -59,7 +59,7 @@ class Block: """ header: Header - transactions: Tuple[Union[Bytes, LegacyTransaction], ...] + transactions: Tuple[Bytes | LegacyTransaction, ...] ommers: Tuple[Header, ...] @@ -88,7 +88,7 @@ class Receipt: logs: Tuple[Log, ...] -def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: +def encode_receipt(tx: Transaction, receipt: Receipt) -> Bytes | Receipt: """ Encodes a receipt. """ @@ -100,7 +100,7 @@ def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: return receipt -def decode_receipt(receipt: Union[Bytes, Receipt]) -> Receipt: +def decode_receipt(receipt: Bytes | Receipt) -> Receipt: """ Decodes a receipt. """ diff --git a/src/ethereum/london/fork.py b/src/ethereum/london/fork.py index 5f82fc8713..e5b5a6aca5 100644 --- a/src/ethereum/london/fork.py +++ b/src/ethereum/london/fork.py @@ -13,7 +13,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -488,7 +488,7 @@ def make_receipt( error: Optional[EthereumException], cumulative_gas_used: Uint, logs: Tuple[Log, ...], -) -> Union[Bytes, Receipt]: +) -> Bytes | Receipt: """ Make the receipt for a transaction that was executed. @@ -521,7 +521,7 @@ def make_receipt( def apply_body( block_env: vm.BlockEnvironment, - transactions: Tuple[Union[LegacyTransaction, Bytes], ...], + transactions: Tuple[LegacyTransaction | Bytes, ...], ommers: Tuple[Header, ...], ) -> vm.BlockOutput: """ diff --git a/src/ethereum/london/transactions.py b/src/ethereum/london/transactions.py index 285a7257c0..84907bd3ea 100644 --- a/src/ethereum/london/transactions.py +++ b/src/ethereum/london/transactions.py @@ -4,7 +4,7 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0, Bytes32 @@ -36,7 +36,7 @@ class LegacyTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 @@ -67,7 +67,7 @@ class AccessListTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -88,7 +88,7 @@ class FeeMarketTransaction: max_priority_fee_per_gas: Uint max_fee_per_gas: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -97,12 +97,10 @@ class FeeMarketTransaction: s: U256 -Transaction = Union[ - LegacyTransaction, AccessListTransaction, FeeMarketTransaction -] +Transaction = LegacyTransaction | AccessListTransaction | FeeMarketTransaction -def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: +def encode_transaction(tx: Transaction) -> LegacyTransaction | Bytes: """ Encode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -116,7 +114,7 @@ def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: raise Exception(f"Unable to encode transaction of type {type(tx)}") -def decode_transaction(tx: Union[LegacyTransaction, Bytes]) -> Transaction: +def decode_transaction(tx: LegacyTransaction | Bytes) -> Transaction: """ Decode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -400,7 +398,7 @@ def signing_hash_1559(tx: FeeMarketTransaction) -> Hash32: ) -def get_transaction_hash(tx: Union[Bytes, LegacyTransaction]) -> Hash32: +def get_transaction_hash(tx: Bytes | LegacyTransaction) -> Hash32: """ Parameters ---------- diff --git a/src/ethereum/london/trie.py b/src/ethereum/london/trie.py index 8d13a6ab46..15eda739e5 100644 --- a/src/ethereum/london/trie.py +++ b/src/ethereum/london/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.berlin import trie as previous_trie from ethereum.crypto.hash import keccak256 @@ -63,15 +62,15 @@ ) ) -Node = Union[Account, Bytes, LegacyTransaction, Receipt, Uint, U256, None] +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", Optional[Account], Optional[Bytes], Bytes, - Optional[Union[LegacyTransaction, Bytes]], - Optional[Union[Receipt, Bytes]], + Optional[LegacyTransaction | Bytes], + Optional[Receipt | Bytes], Uint, U256, ) @@ -124,7 +123,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/london/utils/address.py b/src/ethereum/london/utils/address.py index 54c000069e..573c7c2187 100644 --- a/src/ethereum/london/utils/address.py +++ b/src/ethereum/london/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this london version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.bytes import Bytes32 from ethereum_types.numeric import U256, Uint @@ -24,7 +22,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/london/vm/__init__.py b/src/ethereum/london/vm/__init__.py index ce60ea1105..ca51283db1 100644 --- a/src/ethereum/london/vm/__init__.py +++ b/src/ethereum/london/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0, Bytes32 from ethereum_types.numeric import U64, U256, Uint @@ -71,9 +71,9 @@ class BlockOutput: block_gas_used: Uint = Uint(0) transactions_trie: Trie[ - Bytes, Optional[Union[Bytes, LegacyTransaction]] + Bytes, Optional[Bytes | LegacyTransaction] ] = field(default_factory=lambda: Trie(secured=False, default=None)) - receipts_trie: Trie[Bytes, Optional[Union[Bytes, Receipt]]] = field( + receipts_trie: Trie[Bytes, Optional[Bytes | Receipt]] = field( default_factory=lambda: Trie(secured=False, default=None) ) receipt_keys: Tuple[Bytes, ...] = field(default_factory=tuple) @@ -105,7 +105,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/muir_glacier/transactions.py b/src/ethereum/muir_glacier/transactions.py index 4f2f9efe6d..4501359874 100644 --- a/src/ethereum/muir_glacier/transactions.py +++ b/src/ethereum/muir_glacier/transactions.py @@ -4,7 +4,6 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Union from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0 @@ -33,7 +32,7 @@ class Transaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 diff --git a/src/ethereum/muir_glacier/trie.py b/src/ethereum/muir_glacier/trie.py index 1fe5248ff7..3bfdcb187e 100644 --- a/src/ethereum/muir_glacier/trie.py +++ b/src/ethereum/muir_glacier/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.crypto.hash import keccak256 from ethereum.istanbul import trie as previous_trie @@ -63,7 +62,7 @@ ) ) -Node = Union[Account, Bytes, Transaction, Receipt, Uint, U256, None] +Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -124,7 +123,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/muir_glacier/utils/address.py b/src/ethereum/muir_glacier/utils/address.py index 5e6515f8b1..e2b2770e33 100644 --- a/src/ethereum/muir_glacier/utils/address.py +++ b/src/ethereum/muir_glacier/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this muir_glacier version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.bytes import Bytes32 from ethereum_types.numeric import U256, Uint @@ -24,7 +22,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/muir_glacier/vm/__init__.py b/src/ethereum/muir_glacier/vm/__init__.py index 89d41710a9..afaa32ec28 100644 --- a/src/ethereum/muir_glacier/vm/__init__.py +++ b/src/ethereum/muir_glacier/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U64, U256, Uint @@ -102,7 +102,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/paris/blocks.py b/src/ethereum/paris/blocks.py index 6ad5119f5f..5bb9c787ad 100644 --- a/src/ethereum/paris/blocks.py +++ b/src/ethereum/paris/blocks.py @@ -9,7 +9,7 @@ chain. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes8, Bytes32 @@ -59,7 +59,7 @@ class Block: """ header: Header - transactions: Tuple[Union[Bytes, LegacyTransaction], ...] + transactions: Tuple[Bytes | LegacyTransaction, ...] ommers: Tuple[Header, ...] @@ -88,7 +88,7 @@ class Receipt: logs: Tuple[Log, ...] -def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: +def encode_receipt(tx: Transaction, receipt: Receipt) -> Bytes | Receipt: """ Encodes a receipt. """ @@ -100,7 +100,7 @@ def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: return receipt -def decode_receipt(receipt: Union[Bytes, Receipt]) -> Receipt: +def decode_receipt(receipt: Bytes | Receipt) -> Receipt: """ Decodes a receipt. """ diff --git a/src/ethereum/paris/fork.py b/src/ethereum/paris/fork.py index add7ad0189..2d123d78aa 100644 --- a/src/ethereum/paris/fork.py +++ b/src/ethereum/paris/fork.py @@ -13,7 +13,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple, Union +from typing import List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -383,7 +383,7 @@ def make_receipt( error: Optional[EthereumException], cumulative_gas_used: Uint, logs: Tuple[Log, ...], -) -> Union[Bytes, Receipt]: +) -> Bytes | Receipt: """ Make the receipt for a transaction that was executed. @@ -416,7 +416,7 @@ def make_receipt( def apply_body( block_env: vm.BlockEnvironment, - transactions: Tuple[Union[LegacyTransaction, Bytes], ...], + transactions: Tuple[LegacyTransaction | Bytes, ...], ) -> vm.BlockOutput: """ Executes a block. diff --git a/src/ethereum/paris/transactions.py b/src/ethereum/paris/transactions.py index 285a7257c0..84907bd3ea 100644 --- a/src/ethereum/paris/transactions.py +++ b/src/ethereum/paris/transactions.py @@ -4,7 +4,7 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0, Bytes32 @@ -36,7 +36,7 @@ class LegacyTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 @@ -67,7 +67,7 @@ class AccessListTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -88,7 +88,7 @@ class FeeMarketTransaction: max_priority_fee_per_gas: Uint max_fee_per_gas: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -97,12 +97,10 @@ class FeeMarketTransaction: s: U256 -Transaction = Union[ - LegacyTransaction, AccessListTransaction, FeeMarketTransaction -] +Transaction = LegacyTransaction | AccessListTransaction | FeeMarketTransaction -def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: +def encode_transaction(tx: Transaction) -> LegacyTransaction | Bytes: """ Encode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -116,7 +114,7 @@ def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: raise Exception(f"Unable to encode transaction of type {type(tx)}") -def decode_transaction(tx: Union[LegacyTransaction, Bytes]) -> Transaction: +def decode_transaction(tx: LegacyTransaction | Bytes) -> Transaction: """ Decode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -400,7 +398,7 @@ def signing_hash_1559(tx: FeeMarketTransaction) -> Hash32: ) -def get_transaction_hash(tx: Union[Bytes, LegacyTransaction]) -> Hash32: +def get_transaction_hash(tx: Bytes | LegacyTransaction) -> Hash32: """ Parameters ---------- diff --git a/src/ethereum/paris/trie.py b/src/ethereum/paris/trie.py index 65ee9ea8ae..ce2d3eb50c 100644 --- a/src/ethereum/paris/trie.py +++ b/src/ethereum/paris/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.crypto.hash import keccak256 from ethereum.gray_glacier import trie as previous_trie @@ -63,15 +62,15 @@ ) ) -Node = Union[Account, Bytes, LegacyTransaction, Receipt, Uint, U256, None] +Node = Account | Bytes | LegacyTransaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", Optional[Account], Optional[Bytes], Bytes, - Optional[Union[LegacyTransaction, Bytes]], - Optional[Union[Receipt, Bytes]], + Optional[LegacyTransaction | Bytes], + Optional[Receipt | Bytes], Uint, U256, ) @@ -124,7 +123,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/paris/utils/address.py b/src/ethereum/paris/utils/address.py index 1f26a8f723..3f1163547e 100644 --- a/src/ethereum/paris/utils/address.py +++ b/src/ethereum/paris/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this paris version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.bytes import Bytes32 from ethereum_types.numeric import U256, Uint @@ -24,7 +22,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/paris/vm/__init__.py b/src/ethereum/paris/vm/__init__.py index 8d0d881741..dc3763b936 100644 --- a/src/ethereum/paris/vm/__init__.py +++ b/src/ethereum/paris/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0, Bytes32 from ethereum_types.numeric import U64, U256, Uint @@ -70,9 +70,9 @@ class BlockOutput: block_gas_used: Uint = Uint(0) transactions_trie: Trie[ - Bytes, Optional[Union[Bytes, LegacyTransaction]] + Bytes, Optional[Bytes | LegacyTransaction] ] = field(default_factory=lambda: Trie(secured=False, default=None)) - receipts_trie: Trie[Bytes, Optional[Union[Bytes, Receipt]]] = field( + receipts_trie: Trie[Bytes, Optional[Bytes | Receipt]] = field( default_factory=lambda: Trie(secured=False, default=None) ) receipt_keys: Tuple[Bytes, ...] = field(default_factory=tuple) @@ -104,7 +104,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/prague/blocks.py b/src/ethereum/prague/blocks.py index 80b29087e9..7823271e7c 100644 --- a/src/ethereum/prague/blocks.py +++ b/src/ethereum/prague/blocks.py @@ -9,7 +9,7 @@ chain. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes8, Bytes32 @@ -79,7 +79,7 @@ class Block: """ header: Header - transactions: Tuple[Union[Bytes, LegacyTransaction], ...] + transactions: Tuple[Bytes | LegacyTransaction, ...] ommers: Tuple[Header, ...] withdrawals: Tuple[Withdrawal, ...] @@ -109,7 +109,7 @@ class Receipt: logs: Tuple[Log, ...] -def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: +def encode_receipt(tx: Transaction, receipt: Receipt) -> Bytes | Receipt: """ Encodes a receipt. """ @@ -125,7 +125,7 @@ def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: return receipt -def decode_receipt(receipt: Union[Bytes, Receipt]) -> Receipt: +def decode_receipt(receipt: Bytes | Receipt) -> Receipt: """ Decodes a receipt. """ diff --git a/src/ethereum/prague/fork.py b/src/ethereum/prague/fork.py index 70f5578dd8..c1941ad860 100644 --- a/src/ethereum/prague/fork.py +++ b/src/ethereum/prague/fork.py @@ -13,7 +13,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple, Union +from typing import List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -480,7 +480,7 @@ def make_receipt( error: Optional[EthereumException], cumulative_gas_used: Uint, logs: Tuple[Log, ...], -) -> Union[Bytes, Receipt]: +) -> Bytes | Receipt: """ Make the receipt for a transaction that was executed. @@ -661,7 +661,7 @@ def process_unchecked_system_transaction( def apply_body( block_env: vm.BlockEnvironment, - transactions: Tuple[Union[LegacyTransaction, Bytes], ...], + transactions: Tuple[LegacyTransaction | Bytes, ...], withdrawals: Tuple[Withdrawal, ...], ) -> vm.BlockOutput: """ diff --git a/src/ethereum/prague/transactions.py b/src/ethereum/prague/transactions.py index d88cdcea00..a50153395d 100644 --- a/src/ethereum/prague/transactions.py +++ b/src/ethereum/prague/transactions.py @@ -4,7 +4,7 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0, Bytes32 @@ -36,7 +36,7 @@ class LegacyTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 @@ -67,7 +67,7 @@ class AccessListTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -88,7 +88,7 @@ class FeeMarketTransaction: max_priority_fee_per_gas: Uint max_fee_per_gas: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -142,16 +142,16 @@ class SetCodeTransaction: s: U256 -Transaction = Union[ - LegacyTransaction, - AccessListTransaction, - FeeMarketTransaction, - BlobTransaction, - SetCodeTransaction, -] +Transaction = ( + LegacyTransaction + | AccessListTransaction + | FeeMarketTransaction + | BlobTransaction + | SetCodeTransaction +) -def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: +def encode_transaction(tx: Transaction) -> LegacyTransaction | Bytes: """ Encode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -169,7 +169,7 @@ def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: raise Exception(f"Unable to encode transaction of type {type(tx)}") -def decode_transaction(tx: Union[LegacyTransaction, Bytes]) -> Transaction: +def decode_transaction(tx: LegacyTransaction | Bytes) -> Transaction: """ Decode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -574,7 +574,7 @@ def signing_hash_7702(tx: SetCodeTransaction) -> Hash32: ) -def get_transaction_hash(tx: Union[Bytes, LegacyTransaction]) -> Hash32: +def get_transaction_hash(tx: Bytes | LegacyTransaction) -> Hash32: """ Parameters ---------- diff --git a/src/ethereum/prague/trie.py b/src/ethereum/prague/trie.py index 0c6cbdba30..1cabd496e9 100644 --- a/src/ethereum/prague/trie.py +++ b/src/ethereum/prague/trie.py @@ -26,7 +26,6 @@ Sequence, Tuple, TypeVar, - Union, cast, ) @@ -63,18 +62,25 @@ ) ) -Node = Union[ - Account, Bytes, LegacyTransaction, Receipt, Uint, U256, Withdrawal, None -] +Node = ( + Account + | Bytes + | LegacyTransaction + | Receipt + | Uint + | U256 + | Withdrawal + | None +) K = TypeVar("K", bound=Bytes) V = TypeVar( "V", Optional[Account], Optional[Bytes], Bytes, - Optional[Union[LegacyTransaction, Bytes]], - Optional[Union[Receipt, Bytes]], - Optional[Union[Withdrawal, Bytes]], + Optional[LegacyTransaction | Bytes], + Optional[Receipt | Bytes], + Optional[Withdrawal | Bytes], Uint, U256, ) @@ -127,7 +133,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/prague/utils/address.py b/src/ethereum/prague/utils/address.py index 3120d7a2c2..69c2ce52df 100644 --- a/src/ethereum/prague/utils/address.py +++ b/src/ethereum/prague/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this prague version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.bytes import Bytes32 from ethereum_types.numeric import U256, Uint @@ -24,7 +22,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/prague/vm/__init__.py b/src/ethereum/prague/vm/__init__.py index 2211cfcb3e..df75f66a6e 100644 --- a/src/ethereum/prague/vm/__init__.py +++ b/src/ethereum/prague/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0, Bytes32 from ethereum_types.numeric import U64, U256, Uint @@ -78,14 +78,14 @@ class BlockOutput: block_gas_used: Uint = Uint(0) transactions_trie: Trie[ - Bytes, Optional[Union[Bytes, LegacyTransaction]] + Bytes, Optional[Bytes | LegacyTransaction] ] = field(default_factory=lambda: Trie(secured=False, default=None)) - receipts_trie: Trie[Bytes, Optional[Union[Bytes, Receipt]]] = field( + receipts_trie: Trie[Bytes, Optional[Bytes | Receipt]] = field( default_factory=lambda: Trie(secured=False, default=None) ) receipt_keys: Tuple[Bytes, ...] = field(default_factory=tuple) block_logs: Tuple[Log, ...] = field(default_factory=tuple) - withdrawals_trie: Trie[Bytes, Optional[Union[Bytes, Withdrawal]]] = field( + withdrawals_trie: Trie[Bytes, Optional[Bytes | Withdrawal]] = field( default_factory=lambda: Trie(secured=False, default=None) ) blob_gas_used: U64 = U64(0) @@ -120,7 +120,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/prague/vm/precompiled_contracts/bls12_381/__init__.py b/src/ethereum/prague/vm/precompiled_contracts/bls12_381/__init__.py index 2126a6ab39..49421bec50 100644 --- a/src/ethereum/prague/vm/precompiled_contracts/bls12_381/__init__.py +++ b/src/ethereum/prague/vm/precompiled_contracts/bls12_381/__init__.py @@ -11,7 +11,7 @@ Precompile for BLS12-381 curve operations. """ -from typing import Tuple, Union +from typing import Tuple from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint @@ -398,9 +398,7 @@ def decode_G1_scalar_pair(data: Bytes) -> Tuple[Point2D, int]: return p, m -def bytes_to_FQ( - data: Bytes, optimized: bool = False -) -> Union[FQ, OPTIMIZED_FQ]: +def bytes_to_FQ(data: Bytes, optimized: bool = False) -> FQ | OPTIMIZED_FQ: """ Decode 64 bytes to a FQ element. @@ -413,7 +411,7 @@ def bytes_to_FQ( Returns ------- - fq : Union[FQ, OPTIMIZED_FQ] + fq : FQ | OPTIMIZED_FQ The FQ element. Raises @@ -435,9 +433,7 @@ def bytes_to_FQ( return FQ(c) -def bytes_to_FQ2( - data: Bytes, optimized: bool = False -) -> Union[FQ2, OPTIMIZED_FQ2]: +def bytes_to_FQ2(data: Bytes, optimized: bool = False) -> FQ2 | OPTIMIZED_FQ2: """ Decode 128 bytes to a FQ2 element. @@ -450,7 +446,7 @@ def bytes_to_FQ2( Returns ------- - fq2 : Union[FQ2, OPTIMIZED_FQ2] + fq2 : FQ2 | OPTIMIZED_FQ2 The FQ2 element. Raises diff --git a/src/ethereum/shanghai/blocks.py b/src/ethereum/shanghai/blocks.py index b37e2fd921..05252ce69e 100644 --- a/src/ethereum/shanghai/blocks.py +++ b/src/ethereum/shanghai/blocks.py @@ -9,7 +9,7 @@ chain. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes8, Bytes32 @@ -73,7 +73,7 @@ class Block: """ header: Header - transactions: Tuple[Union[Bytes, LegacyTransaction], ...] + transactions: Tuple[Bytes | LegacyTransaction, ...] ommers: Tuple[Header, ...] withdrawals: Tuple[Withdrawal, ...] @@ -103,7 +103,7 @@ class Receipt: logs: Tuple[Log, ...] -def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: +def encode_receipt(tx: Transaction, receipt: Receipt) -> Bytes | Receipt: """ Encodes a receipt. """ @@ -115,7 +115,7 @@ def encode_receipt(tx: Transaction, receipt: Receipt) -> Union[Bytes, Receipt]: return receipt -def decode_receipt(receipt: Union[Bytes, Receipt]) -> Receipt: +def decode_receipt(receipt: Bytes | Receipt) -> Receipt: """ Decodes a receipt. """ diff --git a/src/ethereum/shanghai/fork.py b/src/ethereum/shanghai/fork.py index 17ef7363b5..215d505c73 100644 --- a/src/ethereum/shanghai/fork.py +++ b/src/ethereum/shanghai/fork.py @@ -13,7 +13,7 @@ """ from dataclasses import dataclass -from typing import List, Optional, Tuple, Union +from typing import List, Optional, Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes @@ -388,7 +388,7 @@ def make_receipt( error: Optional[EthereumException], cumulative_gas_used: Uint, logs: Tuple[Log, ...], -) -> Union[Bytes, Receipt]: +) -> Bytes | Receipt: """ Make the receipt for a transaction that was executed. @@ -421,7 +421,7 @@ def make_receipt( def apply_body( block_env: vm.BlockEnvironment, - transactions: Tuple[Union[LegacyTransaction, Bytes], ...], + transactions: Tuple[LegacyTransaction | Bytes, ...], withdrawals: Tuple[Withdrawal, ...], ) -> vm.BlockOutput: """ diff --git a/src/ethereum/shanghai/transactions.py b/src/ethereum/shanghai/transactions.py index ea7d657e88..685ee18ea2 100644 --- a/src/ethereum/shanghai/transactions.py +++ b/src/ethereum/shanghai/transactions.py @@ -4,7 +4,7 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Tuple, Union +from typing import Tuple from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0, Bytes32 @@ -36,7 +36,7 @@ class LegacyTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 @@ -67,7 +67,7 @@ class AccessListTransaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -88,7 +88,7 @@ class FeeMarketTransaction: max_priority_fee_per_gas: Uint max_fee_per_gas: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes access_list: Tuple[Access, ...] @@ -97,12 +97,10 @@ class FeeMarketTransaction: s: U256 -Transaction = Union[ - LegacyTransaction, AccessListTransaction, FeeMarketTransaction -] +Transaction = LegacyTransaction | AccessListTransaction | FeeMarketTransaction -def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: +def encode_transaction(tx: Transaction) -> LegacyTransaction | Bytes: """ Encode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -116,7 +114,7 @@ def encode_transaction(tx: Transaction) -> Union[LegacyTransaction, Bytes]: raise Exception(f"Unable to encode transaction of type {type(tx)}") -def decode_transaction(tx: Union[LegacyTransaction, Bytes]) -> Transaction: +def decode_transaction(tx: LegacyTransaction | Bytes) -> Transaction: """ Decode a transaction. Needed because non-legacy transactions aren't RLP. """ @@ -407,7 +405,7 @@ def signing_hash_1559(tx: FeeMarketTransaction) -> Hash32: ) -def get_transaction_hash(tx: Union[Bytes, LegacyTransaction]) -> Hash32: +def get_transaction_hash(tx: Bytes | LegacyTransaction) -> Hash32: """ Parameters ---------- diff --git a/src/ethereum/shanghai/trie.py b/src/ethereum/shanghai/trie.py index f1c9e1d11f..f79466fac3 100644 --- a/src/ethereum/shanghai/trie.py +++ b/src/ethereum/shanghai/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.crypto.hash import keccak256 from ethereum.paris import trie as previous_trie @@ -63,18 +62,25 @@ ) ) -Node = Union[ - Account, Bytes, LegacyTransaction, Receipt, Uint, U256, Withdrawal, None -] +Node = ( + Account + | Bytes + | LegacyTransaction + | Receipt + | Uint + | U256 + | Withdrawal + | None +) K = TypeVar("K", bound=Bytes) V = TypeVar( "V", Optional[Account], Optional[Bytes], Bytes, - Optional[Union[LegacyTransaction, Bytes]], - Optional[Union[Receipt, Bytes]], - Optional[Union[Withdrawal, Bytes]], + Optional[LegacyTransaction | Bytes], + Optional[Receipt | Bytes], + Optional[Withdrawal | Bytes], Uint, U256, ) @@ -127,7 +133,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/shanghai/utils/address.py b/src/ethereum/shanghai/utils/address.py index 57d049acc2..454157e402 100644 --- a/src/ethereum/shanghai/utils/address.py +++ b/src/ethereum/shanghai/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this shanghai version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.bytes import Bytes32 from ethereum_types.numeric import U256, Uint @@ -24,7 +22,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/shanghai/vm/__init__.py b/src/ethereum/shanghai/vm/__init__.py index 4f57e478b5..1f6d9d100a 100644 --- a/src/ethereum/shanghai/vm/__init__.py +++ b/src/ethereum/shanghai/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0, Bytes32 from ethereum_types.numeric import U64, U256, Uint @@ -72,14 +72,14 @@ class BlockOutput: block_gas_used: Uint = Uint(0) transactions_trie: Trie[ - Bytes, Optional[Union[Bytes, LegacyTransaction]] + Bytes, Optional[Bytes | LegacyTransaction] ] = field(default_factory=lambda: Trie(secured=False, default=None)) - receipts_trie: Trie[Bytes, Optional[Union[Bytes, Receipt]]] = field( + receipts_trie: Trie[Bytes, Optional[Bytes | Receipt]] = field( default_factory=lambda: Trie(secured=False, default=None) ) receipt_keys: Tuple[Bytes, ...] = field(default_factory=tuple) block_logs: Tuple[Log, ...] = field(default_factory=tuple) - withdrawals_trie: Trie[Bytes, Optional[Union[Bytes, Withdrawal]]] = field( + withdrawals_trie: Trie[Bytes, Optional[Bytes | Withdrawal]] = field( default_factory=lambda: Trie(secured=False, default=None) ) @@ -109,7 +109,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/spurious_dragon/transactions.py b/src/ethereum/spurious_dragon/transactions.py index 65e622b5e1..2e2fbca845 100644 --- a/src/ethereum/spurious_dragon/transactions.py +++ b/src/ethereum/spurious_dragon/transactions.py @@ -4,7 +4,6 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Union from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0 @@ -33,7 +32,7 @@ class Transaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 diff --git a/src/ethereum/spurious_dragon/trie.py b/src/ethereum/spurious_dragon/trie.py index 7e6747f410..56f6f9561e 100644 --- a/src/ethereum/spurious_dragon/trie.py +++ b/src/ethereum/spurious_dragon/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.crypto.hash import keccak256 from ethereum.tangerine_whistle import trie as previous_trie @@ -63,7 +62,7 @@ ) ) -Node = Union[Account, Bytes, Transaction, Receipt, Uint, U256, None] +Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -124,7 +123,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/spurious_dragon/utils/address.py b/src/ethereum/spurious_dragon/utils/address.py index 8f8c9ea503..7d77d0ada9 100644 --- a/src/ethereum/spurious_dragon/utils/address.py +++ b/src/ethereum/spurious_dragon/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this spurious dragon version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.numeric import U256, Uint @@ -23,7 +21,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/spurious_dragon/vm/__init__.py b/src/ethereum/spurious_dragon/vm/__init__.py index c892577a74..9955b7200b 100644 --- a/src/ethereum/spurious_dragon/vm/__init__.py +++ b/src/ethereum/spurious_dragon/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U64, U256, Uint @@ -102,7 +102,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/tangerine_whistle/transactions.py b/src/ethereum/tangerine_whistle/transactions.py index 6761b34ca9..bb003b7673 100644 --- a/src/ethereum/tangerine_whistle/transactions.py +++ b/src/ethereum/tangerine_whistle/transactions.py @@ -4,7 +4,6 @@ transactions are the events that move between states. """ from dataclasses import dataclass -from typing import Union from ethereum_rlp import rlp from ethereum_types.bytes import Bytes, Bytes0 @@ -33,7 +32,7 @@ class Transaction: nonce: U256 gas_price: Uint gas: Uint - to: Union[Bytes0, Address] + to: Bytes0 | Address value: U256 data: Bytes v: U256 diff --git a/src/ethereum/tangerine_whistle/trie.py b/src/ethereum/tangerine_whistle/trie.py index 037bc516df..e0a803d026 100644 --- a/src/ethereum/tangerine_whistle/trie.py +++ b/src/ethereum/tangerine_whistle/trie.py @@ -26,7 +26,7 @@ Sequence, Tuple, TypeVar, - Union, + assert_type, cast, ) @@ -34,7 +34,6 @@ from ethereum_types.bytes import Bytes from ethereum_types.frozen import slotted_freezable from ethereum_types.numeric import U256, Uint -from typing_extensions import assert_type from ethereum.crypto.hash import keccak256 from ethereum.dao_fork import trie as previous_trie @@ -63,7 +62,7 @@ ) ) -Node = Union[Account, Bytes, Transaction, Receipt, Uint, U256, None] +Node = Account | Bytes | Transaction | Receipt | Uint | U256 | None K = TypeVar("K", bound=Bytes) V = TypeVar( "V", @@ -124,7 +123,7 @@ class BranchNode: value: Extended -InternalNode = Union[LeafNode, ExtensionNode, BranchNode] +InternalNode = LeafNode | ExtensionNode | BranchNode def encode_internal_node(node: Optional[InternalNode]) -> Extended: diff --git a/src/ethereum/tangerine_whistle/utils/address.py b/src/ethereum/tangerine_whistle/utils/address.py index 8853e91c9b..b553057e76 100644 --- a/src/ethereum/tangerine_whistle/utils/address.py +++ b/src/ethereum/tangerine_whistle/utils/address.py @@ -12,8 +12,6 @@ Address specific functions used in this tangerine whistle version of specification. """ -from typing import Union - from ethereum_rlp import rlp from ethereum_types.numeric import U256, Uint @@ -23,7 +21,7 @@ from ..fork_types import Address -def to_address(data: Union[Uint, U256]) -> Address: +def to_address(data: Uint | U256) -> Address: """ Convert a Uint or U256 value to a valid address (20 bytes). diff --git a/src/ethereum/tangerine_whistle/vm/__init__.py b/src/ethereum/tangerine_whistle/vm/__init__.py index 9485cdc84b..cf061104d0 100644 --- a/src/ethereum/tangerine_whistle/vm/__init__.py +++ b/src/ethereum/tangerine_whistle/vm/__init__.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass, field -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Set, Tuple from ethereum_types.bytes import Bytes, Bytes0 from ethereum_types.numeric import U64, U256, Uint @@ -101,7 +101,7 @@ class Message: block_env: BlockEnvironment tx_env: TransactionEnvironment caller: Address - target: Union[Bytes0, Address] + target: Bytes0 | Address current_target: Address gas: Uint value: U256 diff --git a/src/ethereum/trace.py b/src/ethereum/trace.py index 3b12eb9374..7b374ec3f6 100644 --- a/src/ethereum/trace.py +++ b/src/ethereum/trace.py @@ -18,7 +18,7 @@ import enum from dataclasses import dataclass -from typing import Optional, Protocol, Union +from typing import Optional, Protocol from ethereum_types.bytes import Bytes @@ -151,17 +151,17 @@ class GasAndRefund: """ -TraceEvent = Union[ - TransactionStart, - TransactionEnd, - PrecompileStart, - PrecompileEnd, - OpStart, - OpEnd, - OpException, - EvmStop, - GasAndRefund, -] +TraceEvent = ( + TransactionStart + | TransactionEnd + | PrecompileStart + | PrecompileEnd + | OpStart + | OpEnd + | OpException + | EvmStop + | GasAndRefund +) """ All possible types of events that an [`EvmTracer`] is expected to handle. diff --git a/src/ethereum/utils/byte.py b/src/ethereum/utils/byte.py index a30c5ff8c2..30039be686 100644 --- a/src/ethereum/utils/byte.py +++ b/src/ethereum/utils/byte.py @@ -11,14 +11,12 @@ Byte specific utility functions used in this specification. """ -from typing import Union - from ethereum_types.bytes import Bytes from ethereum_types.numeric import FixedUnsigned, Uint def left_pad_zero_bytes( - value: Bytes, size: Union[int, FixedUnsigned, Uint] + value: Bytes, size: int | FixedUnsigned | Uint ) -> Bytes: """ Left pad zeroes to `value` if its length is less than the given `size`. @@ -39,7 +37,7 @@ def left_pad_zero_bytes( def right_pad_zero_bytes( - value: Bytes, size: Union[int, FixedUnsigned, Uint] + value: Bytes, size: int | FixedUnsigned | Uint ) -> Bytes: """ Right pad zeroes to `value` if its length is less than the given `size`. diff --git a/tests/helpers/load_state_tests.py b/tests/helpers/load_state_tests.py index 5a0aa147a8..3e95e41bd4 100644 --- a/tests/helpers/load_state_tests.py +++ b/tests/helpers/load_state_tests.py @@ -3,7 +3,7 @@ import os.path import re from glob import glob -from typing import Any, Dict, Generator, Tuple, Union +from typing import Any, Dict, Generator, Tuple from unittest.mock import call, patch import pytest @@ -162,7 +162,7 @@ def fetch_state_test_files( slow_list: Tuple[str, ...] = (), big_memory_list: Tuple[str, ...] = (), ignore_list: Tuple[str, ...] = (), -) -> Generator[Union[Dict, ParameterSet], None, None]: +) -> Generator[Dict | ParameterSet, None, None]: all_slow = [re.compile(x) for x in slow_list] all_big_memory = [re.compile(x) for x in big_memory_list] all_ignore = [re.compile(x) for x in ignore_list] diff --git a/tests/test_rlp.py b/tests/test_rlp.py index 5e914c8402..de7d8ccaa9 100644 --- a/tests/test_rlp.py +++ b/tests/test_rlp.py @@ -1,6 +1,6 @@ import json import os -from typing import List, Sequence, Tuple, Union +from typing import List, Sequence, Tuple import pytest from ethereum_rlp import Extended, rlp @@ -17,9 +17,7 @@ # -def convert_to_rlp_native( - obj: Union[str, int, Sequence[Union[str, int]]] -) -> Extended: +def convert_to_rlp_native(obj: str | int | Sequence[str | int]) -> Extended: if isinstance(obj, str): return bytes(obj, "utf-8") elif isinstance(obj, int):