Skip to content

Commit

Permalink
Re-split cancun's check_transaction and validate_transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
SamWilsn committed Jan 7, 2025
1 parent 730a064 commit 5c82ed6
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 13 deletions.
22 changes: 9 additions & 13 deletions src/ethereum/cancun/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from dataclasses import dataclass
from typing import List, Optional, Tuple, Union

from ethereum_types.bytes import Bytes, Bytes0, Bytes32
from ethereum_types.bytes import Bytes, Bytes32
from ethereum_types.numeric import U64, U256, Uint

from ethereum.crypto.hash import Hash32, keccak256
Expand Down Expand Up @@ -48,6 +48,7 @@
decode_transaction,
encode_transaction,
recover_sender,
validate_transaction,
)
from .trie import Trie, root, trie_set
from .utils.hexadecimal import hex_to_address
Expand All @@ -59,7 +60,7 @@
calculate_excess_blob_gas,
calculate_total_blob_gas,
)
from .vm.interpreter import MAX_CODE_SIZE, process_message_call
from .vm.interpreter import process_message_call

BASE_FEE_MAX_CHANGE_DENOMINATOR = Uint(8)
ELASTICITY_MULTIPLIER = Uint(2)
Expand Down Expand Up @@ -366,18 +367,10 @@ def check_transaction(
InvalidBlock :
If the transaction is not includable.
"""
if calculate_intrinsic_cost(tx) > tx.gas:
raise InvalidBlock
if tx.nonce >= U256(U64.MAX_VALUE):
raise InvalidBlock
if tx.to == Bytes0(b"") and len(tx.data) > 2 * MAX_CODE_SIZE:
raise InvalidBlock

if tx.gas > gas_available:
raise InvalidBlock

sender = recover_sender(chain_id, tx)
sender_account = get_account(state, sender)
sender_address = recover_sender(chain_id, tx)
sender_account = get_account(state, sender_address)

if isinstance(tx, (FeeMarketTransaction, BlobTransaction)):
if tx.max_fee_per_gas < tx.max_priority_fee_per_gas:
Expand Down Expand Up @@ -423,7 +416,7 @@ def check_transaction(
if sender_account.code != bytearray():
raise InvalidSenderError("not EOA")

return sender, effective_gas_price, blob_versioned_hashes
return sender_address, effective_gas_price, blob_versioned_hashes


def make_receipt(
Expand Down Expand Up @@ -730,6 +723,9 @@ def process_transaction(
logs : `Tuple[ethereum.blocks.Log, ...]`
Logs generated during execution.
"""
if not validate_transaction(tx):
raise InvalidBlock

sender = env.origin
sender_account = get_account(env.state, sender)

Expand Down
37 changes: 37 additions & 0 deletions src/ethereum/cancun/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,43 @@ def decode_transaction(tx: Union[LegacyTransaction, Bytes]) -> Transaction:
return tx


def validate_transaction(tx: Transaction) -> bool:
"""
Verifies a transaction.
The gas in a transaction gets used to pay for the intrinsic cost of
operations, therefore if there is insufficient gas then it would not
be possible to execute a transaction and it will be declared invalid.
Additionally, the nonce of a transaction must not equal or exceed the
limit defined in `EIP-2681 <https://eips.ethereum.org/EIPS/eip-2681>`_.
In practice, defining the limit as ``2**64-1`` has no impact because
sending ``2**64-1`` transactions is improbable. It's not strictly
impossible though, ``2**64-1`` transactions is the entire capacity of the
Ethereum blockchain at 2022 gas limits for a little over 22 years.
Parameters
----------
tx :
Transaction to validate.
Returns
-------
verified : `bool`
True if the transaction can be executed, or False otherwise.
"""
from .vm.interpreter import MAX_CODE_SIZE

if calculate_intrinsic_cost(tx) > tx.gas:
return False
if tx.nonce >= U256(U64.MAX_VALUE):
return False
if tx.to == Bytes0(b"") and len(tx.data) > 2 * MAX_CODE_SIZE:
return False

return True


def calculate_intrinsic_cost(tx: Transaction) -> Uint:
"""
Calculates the gas that is charged before execution is started.
Expand Down

0 comments on commit 5c82ed6

Please sign in to comment.