Skip to content

tests: add specific exceptions on tests #1286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 9, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ Some clarifications were enabled without protocol releases:
| [EIP-2681](https://eips.ethereum.org/EIPS/eip-2681) | 0 |
| [EIP-3607](https://eips.ethereum.org/EIPS/eip-3607) | 0 |
| [EIP-7523](https://eips.ethereum.org/EIPS/eip-7523) | 15537394 |
| [EIP-7610](https://github.com/ethereum/EIPs/pull/8161) | 0 |
| [EIP-7610](https://eips.ethereum.org/EIPS/eip-7610) | 0 |


## Execution Specification (work-in-progress)
14 changes: 10 additions & 4 deletions src/ethereum/arrow_glacier/transactions.py
Original file line number Diff line number Diff line change
@@ -13,7 +13,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .exceptions import TransactionTypeError
from .fork_types import Address
@@ -337,15 +341,17 @@ def validate_transaction(tx: Transaction) -> Uint:

This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.

[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


14 changes: 10 additions & 4 deletions src/ethereum/berlin/transactions.py
Original file line number Diff line number Diff line change
@@ -13,7 +13,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .exceptions import TransactionTypeError
from .fork_types import Address
@@ -254,15 +258,17 @@ def validate_transaction(tx: Transaction) -> Uint:

This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.

[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


14 changes: 10 additions & 4 deletions src/ethereum/byzantium/transactions.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .fork_types import Address

@@ -110,15 +114,17 @@ def validate_transaction(tx: Transaction) -> Uint:

This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.

[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


6 changes: 6 additions & 0 deletions src/ethereum/cancun/exceptions.py
Original file line number Diff line number Diff line change
@@ -101,3 +101,9 @@ class PriorityFeeGreaterThanMaxFeeError(InvalidTransaction):
"""
The priority fee is greater than the maximum fee per gas.
"""


class InitCodeTooLargeError(InvalidTransaction):
"""
The init code of the transaction is too large.
"""
24 changes: 16 additions & 8 deletions src/ethereum/cancun/transactions.py
Original file line number Diff line number Diff line change
@@ -13,9 +13,13 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .exceptions import TransactionTypeError
from .exceptions import InitCodeTooLargeError, TransactionTypeError
from .fork_types import Address, VersionedHash

TX_BASE_COST = Uint(21000)
@@ -439,19 +443,23 @@ def validate_transaction(tx: Transaction) -> Uint:

This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`. It also raises an
`InitCodeTooLargeError` if the code size of a contract creation transaction
exceeds the maximum allowed size.

[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
from .vm.interpreter import MAX_CODE_SIZE
from .vm.interpreter import MAX_INIT_CODE_SIZE

intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
if tx.to == Bytes0(b"") and len(tx.data) > 2 * MAX_CODE_SIZE:
raise InvalidTransaction("Code size too large")
raise NonceOverflowError("Nonce too high")
if tx.to == Bytes0(b"") and len(tx.data) > MAX_INIT_CODE_SIZE:
raise InitCodeTooLargeError("Code size too large")

return intrinsic_gas

4 changes: 2 additions & 2 deletions src/ethereum/cancun/vm/instructions/system.py
Original file line number Diff line number Diff line change
@@ -72,15 +72,15 @@ def generic_create(
# This import causes a circular import error
# if it's not moved inside this method
from ...vm.interpreter import (
MAX_CODE_SIZE,
MAX_INIT_CODE_SIZE,
STACK_DEPTH_LIMIT,
process_create_message,
)

call_data = memory_read_bytes(
evm.memory, memory_start_position, memory_size
)
if len(call_data) > 2 * MAX_CODE_SIZE:
if len(call_data) > MAX_INIT_CODE_SIZE:
raise OutOfGasError

create_message_gas = max_message_call_gas(Uint(evm.gas_left))
1 change: 1 addition & 0 deletions src/ethereum/cancun/vm/interpreter.py
Original file line number Diff line number Diff line change
@@ -62,6 +62,7 @@

STACK_DEPTH_LIMIT = Uint(1024)
MAX_CODE_SIZE = 0x6000
MAX_INIT_CODE_SIZE = 2 * MAX_CODE_SIZE


@dataclass
14 changes: 10 additions & 4 deletions src/ethereum/constantinople/transactions.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .fork_types import Address

@@ -110,15 +114,17 @@ def validate_transaction(tx: Transaction) -> Uint:

This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.

[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


14 changes: 10 additions & 4 deletions src/ethereum/dao_fork/transactions.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .fork_types import Address

@@ -110,15 +114,17 @@ def validate_transaction(tx: Transaction) -> Uint:

This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.

[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


13 changes: 13 additions & 0 deletions src/ethereum/exceptions.py
Original file line number Diff line number Diff line change
@@ -60,3 +60,16 @@ class GasUsedExceedsLimitError(InvalidTransaction):
Thrown when a transaction's gas usage exceeds the gas available in the
block.
"""


class InsufficientTransactionGasError(InvalidTransaction):
"""
Thrown when a transaction does not provide enough gas to cover its
intrinsic cost.
"""


class NonceOverflowError(InvalidTransaction):
"""
Thrown when a transaction's nonce is greater than `2**64 - 2`.
"""
14 changes: 10 additions & 4 deletions src/ethereum/frontier/transactions.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .fork_types import Address

@@ -105,15 +109,17 @@ def validate_transaction(tx: Transaction) -> Uint:

This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.

[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


14 changes: 10 additions & 4 deletions src/ethereum/gray_glacier/transactions.py
Original file line number Diff line number Diff line change
@@ -13,7 +13,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .exceptions import TransactionTypeError
from .fork_types import Address
@@ -337,15 +341,17 @@ def validate_transaction(tx: Transaction) -> Uint:

This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.

[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


14 changes: 10 additions & 4 deletions src/ethereum/homestead/transactions.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .fork_types import Address

@@ -110,15 +114,17 @@ def validate_transaction(tx: Transaction) -> Uint:

This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.

[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


14 changes: 10 additions & 4 deletions src/ethereum/istanbul/transactions.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .fork_types import Address

@@ -110,15 +114,17 @@ def validate_transaction(tx: Transaction) -> Uint:
This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.
[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


14 changes: 10 additions & 4 deletions src/ethereum/london/transactions.py
Original file line number Diff line number Diff line change
@@ -13,7 +13,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .exceptions import TransactionTypeError
from .fork_types import Address
@@ -337,15 +341,17 @@ def validate_transaction(tx: Transaction) -> Uint:
This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.
[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


14 changes: 10 additions & 4 deletions src/ethereum/muir_glacier/transactions.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .fork_types import Address

@@ -110,15 +114,17 @@ def validate_transaction(tx: Transaction) -> Uint:
This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.
[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


16 changes: 16 additions & 0 deletions src/ethereum/osaka/exceptions.py
Original file line number Diff line number Diff line change
@@ -107,3 +107,19 @@ class EmptyAuthorizationListError(InvalidTransaction):
"""
The authorization list in the transaction is empty.
"""


class InitCodeTooLargeError(InvalidTransaction):
"""
The init code of the transaction is too large.
"""


class TransactionGasLimitExceededError(InvalidTransaction):
"""
The transaction has specified a gas limit that is greater than the allowed
maximum.
Note that this is _not_ the exception thrown when bytecode execution runs
out of gas.
"""
27 changes: 19 additions & 8 deletions src/ethereum/osaka/transactions.py
Original file line number Diff line number Diff line change
@@ -13,9 +13,17 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .exceptions import TransactionTypeError
from .exceptions import (
InitCodeTooLargeError,
TransactionGasLimitExceededError,
TransactionTypeError,
)
from .fork_types import Address, Authorization, VersionedHash

TX_BASE_COST = Uint(21000)
@@ -536,8 +544,11 @@ def validate_transaction(tx: Transaction) -> Tuple[Uint, Uint]:
This function takes a transaction as a parameter and returns the intrinsic
gas cost and the minimum calldata gas cost for the transaction after
validation. It throws an `InvalidTransaction` exception
if the transaction is invalid.
validation. It throws an `InsufficientTransactionGasError` exception if
the transaction does not provide enough gas to cover the intrinsic cost,
and a `NonceOverflowError` exception if the nonce is greater than
`2**64 - 2`. It also raises an `InitCodeTooLargeError` if the code size of
a contract creation transaction exceeds the maximum allowed size.
[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623
@@ -546,13 +557,13 @@ def validate_transaction(tx: Transaction) -> Tuple[Uint, Uint]:

intrinsic_gas, calldata_floor_gas_cost = calculate_intrinsic_cost(tx)
if max(intrinsic_gas, calldata_floor_gas_cost) > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
if tx.to == Bytes0(b"") and len(tx.data) > MAX_INIT_CODE_SIZE:
raise InvalidTransaction("Code size too large")
raise InitCodeTooLargeError("Code size too large")
if tx.gas > TX_MAX_GAS_LIMIT:
raise InvalidTransaction("Gas limit too high")
raise TransactionGasLimitExceededError("Gas limit too high")

return intrinsic_gas, calldata_floor_gas_cost

14 changes: 10 additions & 4 deletions src/ethereum/paris/transactions.py
Original file line number Diff line number Diff line change
@@ -13,7 +13,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .exceptions import TransactionTypeError
from .fork_types import Address
@@ -337,15 +341,17 @@ def validate_transaction(tx: Transaction) -> Uint:
This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.
[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


6 changes: 6 additions & 0 deletions src/ethereum/prague/exceptions.py
Original file line number Diff line number Diff line change
@@ -107,3 +107,9 @@ class EmptyAuthorizationListError(InvalidTransaction):
"""
The authorization list in the transaction is empty.
"""


class InitCodeTooLargeError(InvalidTransaction):
"""
The init code of the transaction is too large.
"""
25 changes: 16 additions & 9 deletions src/ethereum/prague/transactions.py
Original file line number Diff line number Diff line change
@@ -13,9 +13,13 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .exceptions import TransactionTypeError
from .exceptions import InitCodeTooLargeError, TransactionTypeError
from .fork_types import Address, Authorization, VersionedHash

TX_BASE_COST = Uint(21000)
@@ -534,21 +538,24 @@ def validate_transaction(tx: Transaction) -> Tuple[Uint, Uint]:
This function takes a transaction as a parameter and returns the intrinsic
gas cost and the minimum calldata gas cost for the transaction after
validation. It throws an `InvalidTransaction` exception
if the transaction is invalid.
validation. It throws an `InsufficientTransactionGasError` exception if
the transaction does not provide enough gas to cover the intrinsic cost,
and a `NonceOverflowError` exception if the nonce is greater than
`2**64 - 2`. It also raises an `InitCodeTooLargeError` if the code size of
a contract creation transaction exceeds the maximum allowed size.
[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
[EIP-7623]: https://eips.ethereum.org/EIPS/eip-7623
"""
from .vm.interpreter import MAX_CODE_SIZE
from .vm.interpreter import MAX_INIT_CODE_SIZE

intrinsic_gas, calldata_floor_gas_cost = calculate_intrinsic_cost(tx)
if max(intrinsic_gas, calldata_floor_gas_cost) > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
if tx.to == Bytes0(b"") and len(tx.data) > 2 * MAX_CODE_SIZE:
raise InvalidTransaction("Code size too large")
raise NonceOverflowError("Nonce too high")
if tx.to == Bytes0(b"") and len(tx.data) > MAX_INIT_CODE_SIZE:
raise InitCodeTooLargeError("Code size too large")

return intrinsic_gas, calldata_floor_gas_cost

4 changes: 2 additions & 2 deletions src/ethereum/prague/vm/instructions/system.py
Original file line number Diff line number Diff line change
@@ -73,15 +73,15 @@ def generic_create(
# This import causes a circular import error
# if it's not moved inside this method
from ...vm.interpreter import (
MAX_CODE_SIZE,
MAX_INIT_CODE_SIZE,
STACK_DEPTH_LIMIT,
process_create_message,
)

call_data = memory_read_bytes(
evm.memory, memory_start_position, memory_size
)
if len(call_data) > 2 * MAX_CODE_SIZE:
if len(call_data) > MAX_INIT_CODE_SIZE:
raise OutOfGasError

create_message_gas = max_message_call_gas(Uint(evm.gas_left))
1 change: 1 addition & 0 deletions src/ethereum/prague/vm/interpreter.py
Original file line number Diff line number Diff line change
@@ -64,6 +64,7 @@

STACK_DEPTH_LIMIT = Uint(1024)
MAX_CODE_SIZE = 0x6000
MAX_INIT_CODE_SIZE = 2 * MAX_CODE_SIZE


@dataclass
6 changes: 6 additions & 0 deletions src/ethereum/shanghai/exceptions.py
Original file line number Diff line number Diff line change
@@ -56,3 +56,9 @@ class PriorityFeeGreaterThanMaxFeeError(InvalidTransaction):
"""
The priority fee is greater than the maximum fee per gas.
"""


class InitCodeTooLargeError(InvalidTransaction):
"""
The init code of the transaction is too large.
"""
24 changes: 16 additions & 8 deletions src/ethereum/shanghai/transactions.py
Original file line number Diff line number Diff line change
@@ -13,9 +13,13 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .exceptions import TransactionTypeError
from .exceptions import InitCodeTooLargeError, TransactionTypeError
from .fork_types import Address

TX_BASE_COST = Uint(21000)
@@ -340,19 +344,23 @@ def validate_transaction(tx: Transaction) -> Uint:
This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`. It also raises an
`InitCodeTooLargeError` if the code size of a contract creation transaction
exceeds the maximum allowed size.
[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
from .vm.interpreter import MAX_CODE_SIZE
from .vm.interpreter import MAX_INIT_CODE_SIZE

intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
if tx.to == Bytes0(b"") and len(tx.data) > 2 * MAX_CODE_SIZE:
raise InvalidTransaction("Code size too large")
raise NonceOverflowError("Nonce too high")
if tx.to == Bytes0(b"") and len(tx.data) > MAX_INIT_CODE_SIZE:
raise InitCodeTooLargeError("Code size too large")

return intrinsic_gas

4 changes: 2 additions & 2 deletions src/ethereum/shanghai/vm/instructions/system.py
Original file line number Diff line number Diff line change
@@ -71,15 +71,15 @@ def generic_create(
# This import causes a circular import error
# if it's not moved inside this method
from ...vm.interpreter import (
MAX_CODE_SIZE,
MAX_INIT_CODE_SIZE,
STACK_DEPTH_LIMIT,
process_create_message,
)

call_data = memory_read_bytes(
evm.memory, memory_start_position, memory_size
)
if len(call_data) > 2 * MAX_CODE_SIZE:
if len(call_data) > MAX_INIT_CODE_SIZE:
raise OutOfGasError

create_message_gas = max_message_call_gas(Uint(evm.gas_left))
1 change: 1 addition & 0 deletions src/ethereum/shanghai/vm/interpreter.py
Original file line number Diff line number Diff line change
@@ -62,6 +62,7 @@

STACK_DEPTH_LIMIT = Uint(1024)
MAX_CODE_SIZE = 0x6000
MAX_INIT_CODE_SIZE = 2 * MAX_CODE_SIZE


@dataclass
14 changes: 10 additions & 4 deletions src/ethereum/spurious_dragon/transactions.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .fork_types import Address

@@ -110,15 +114,17 @@ def validate_transaction(tx: Transaction) -> Uint:
This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.
[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


14 changes: 10 additions & 4 deletions src/ethereum/tangerine_whistle/transactions.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,11 @@

from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.exceptions import InvalidSignatureError, InvalidTransaction
from ethereum.exceptions import (
InsufficientTransactionGasError,
InvalidSignatureError,
NonceOverflowError,
)

from .fork_types import Address

@@ -110,15 +114,17 @@ def validate_transaction(tx: Transaction) -> Uint:
This function takes a transaction as a parameter and returns the intrinsic
gas cost of the transaction after validation. It throws an
`InvalidTransaction` exception if the transaction is invalid.
`InsufficientTransactionGasError` exception if the transaction does not
provide enough gas to cover the intrinsic cost, and a `NonceOverflowError`
exception if the nonce is greater than `2**64 - 2`.
[EIP-2681]: https://eips.ethereum.org/EIPS/eip-2681
"""
intrinsic_gas = calculate_intrinsic_cost(tx)
if intrinsic_gas > tx.gas:
raise InvalidTransaction("Insufficient gas")
raise InsufficientTransactionGasError("Insufficient gas")
if U256(tx.nonce) >= U256(U64.MAX_VALUE):
raise InvalidTransaction("Nonce too high")
raise NonceOverflowError("Nonce too high")
return intrinsic_gas


4 changes: 2 additions & 2 deletions tests/berlin/test_transaction.py
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
LegacyTransaction,
validate_transaction,
)
from ethereum.exceptions import InvalidTransaction
from ethereum.exceptions import NonceOverflowError
from ethereum.utils.hexadecimal import hex_to_uint
from tests.helpers import TEST_FIXTURES

@@ -33,7 +33,7 @@ def test_high_nonce(test_file_high_nonce: str) -> None:

tx = rlp.decode_to(LegacyTransaction, test["tx_rlp"])

with pytest.raises(InvalidTransaction):
with pytest.raises(NonceOverflowError):
validate_transaction(tx)


4 changes: 2 additions & 2 deletions tests/byzantium/test_transaction.py
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
from ethereum_rlp import rlp

from ethereum.byzantium.transactions import Transaction, validate_transaction
from ethereum.exceptions import InvalidTransaction
from ethereum.exceptions import NonceOverflowError
from ethereum.utils.hexadecimal import hex_to_uint
from tests.helpers import TEST_FIXTURES

@@ -32,7 +32,7 @@ def test_high_nonce(test_file_high_nonce: str) -> None:

tx = rlp.decode_to(Transaction, test["tx_rlp"])

with pytest.raises(InvalidTransaction):
with pytest.raises(NonceOverflowError):
validate_transaction(tx)


4 changes: 2 additions & 2 deletions tests/constantinople/test_transaction.py
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
Transaction,
validate_transaction,
)
from ethereum.exceptions import InvalidTransaction
from ethereum.exceptions import NonceOverflowError
from ethereum.utils.hexadecimal import hex_to_uint
from tests.helpers import TEST_FIXTURES

@@ -35,7 +35,7 @@ def test_high_nonce(test_file_high_nonce: str) -> None:

tx = rlp.decode_to(Transaction, test["tx_rlp"])

with pytest.raises(InvalidTransaction):
with pytest.raises(NonceOverflowError):
validate_transaction(tx)


4 changes: 2 additions & 2 deletions tests/frontier/test_transaction.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
import pytest
from ethereum_rlp import rlp

from ethereum.exceptions import InvalidTransaction
from ethereum.exceptions import NonceOverflowError
from ethereum.frontier.transactions import Transaction, validate_transaction
from ethereum.utils.hexadecimal import hex_to_uint
from tests.helpers import TEST_FIXTURES
@@ -30,7 +30,7 @@ def test_high_nonce(test_file_high_nonce: str) -> None:

tx = rlp.decode_to(Transaction, test["tx_rlp"])

with pytest.raises(InvalidTransaction):
with pytest.raises(NonceOverflowError):
validate_transaction(tx)


4 changes: 2 additions & 2 deletions tests/homestead/test_transaction.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
import pytest
from ethereum_rlp import rlp

from ethereum.exceptions import InvalidTransaction
from ethereum.exceptions import NonceOverflowError
from ethereum.homestead.transactions import Transaction, validate_transaction
from ethereum.utils.hexadecimal import hex_to_uint
from tests.helpers import TEST_FIXTURES
@@ -32,7 +32,7 @@ def test_high_nonce(test_file_high_nonce: str) -> None:

tx = rlp.decode_to(Transaction, test["tx_rlp"])

with pytest.raises(InvalidTransaction):
with pytest.raises(NonceOverflowError):
validate_transaction(tx)


4 changes: 2 additions & 2 deletions tests/istanbul/test_transaction.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
import pytest
from ethereum_rlp import rlp

from ethereum.exceptions import InvalidTransaction
from ethereum.exceptions import NonceOverflowError
from ethereum.istanbul.transactions import Transaction, validate_transaction
from ethereum.utils.hexadecimal import hex_to_uint
from tests.helpers import TEST_FIXTURES
@@ -30,7 +30,7 @@ def test_high_nonce(test_file_high_nonce: str) -> None:

tx = rlp.decode_to(Transaction, test["tx_rlp"])

with pytest.raises(InvalidTransaction):
with pytest.raises(NonceOverflowError):
validate_transaction(tx)


4 changes: 2 additions & 2 deletions tests/london/test_transaction.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
import pytest
from ethereum_rlp import rlp

from ethereum.exceptions import InvalidTransaction
from ethereum.exceptions import NonceOverflowError
from ethereum.london.transactions import (
LegacyTransaction,
validate_transaction,
@@ -33,7 +33,7 @@ def test_high_nonce(test_file_high_nonce: str) -> None:

tx = rlp.decode_to(LegacyTransaction, test["tx_rlp"])

with pytest.raises(InvalidTransaction):
with pytest.raises(NonceOverflowError):
validate_transaction(tx)


4 changes: 2 additions & 2 deletions tests/spurious_dragon/test_transaction.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
import pytest
from ethereum_rlp import rlp

from ethereum.exceptions import InvalidTransaction
from ethereum.exceptions import NonceOverflowError
from ethereum.spurious_dragon.transactions import (
Transaction,
validate_transaction,
@@ -35,7 +35,7 @@ def test_high_nonce(test_file_high_nonce: str) -> None:

tx = rlp.decode_to(Transaction, test["tx_rlp"])

with pytest.raises(InvalidTransaction):
with pytest.raises(NonceOverflowError):
validate_transaction(tx)


4 changes: 2 additions & 2 deletions tests/tangerine_whistle/test_transaction.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
import pytest
from ethereum_rlp import rlp

from ethereum.exceptions import InvalidTransaction
from ethereum.exceptions import NonceOverflowError
from ethereum.tangerine_whistle.transactions import (
Transaction,
validate_transaction,
@@ -35,7 +35,7 @@ def test_high_nonce(test_file_high_nonce: str) -> None:

tx = rlp.decode_to(Transaction, test["tx_rlp"])

with pytest.raises(InvalidTransaction):
with pytest.raises(NonceOverflowError):
validate_transaction(tx)