diff --git a/src/ethereum/prague/transactions.py b/src/ethereum/prague/transactions.py index 4ffa10b6d7..8516234fe5 100644 --- a/src/ethereum/prague/transactions.py +++ b/src/ethereum/prague/transactions.py @@ -17,13 +17,12 @@ from .exceptions import TransactionTypeError from .fork_types import Address, Authorization, VersionedHash +from .vm.gas import calculate_total_access_list_gas TX_BASE_COST = Uint(21000) FLOOR_CALLDATA_COST = Uint(10) STANDARD_CALLDATA_TOKEN_COST = Uint(4) TX_CREATE_COST = Uint(32000) -TX_ACCESS_LIST_ADDRESS_COST = Uint(2400) -TX_ACCESS_LIST_STORAGE_KEY_COST = Uint(1900) @slotted_freezable @@ -241,9 +240,11 @@ def calculate_inclusion_gas_cost(tx: Transaction) -> Tuple[Uint, Uint]: data_cost = tokens_in_calldata * STANDARD_CALLDATA_TOKEN_COST + access_list_cost = calculate_total_access_list_gas(tx) + return ( - Uint(TX_BASE_COST + data_cost), - Uint(TX_BASE_COST + calldata_floor_gas_cost), + Uint(TX_BASE_COST + data_cost + access_list_cost), + Uint(TX_BASE_COST + calldata_floor_gas_cost + access_list_cost), ) def calculate_intrinsic_gas_cost(tx: Transaction) -> Tuple[Uint, Uint]: @@ -282,20 +283,6 @@ def calculate_intrinsic_gas_cost(tx: Transaction) -> Tuple[Uint, Uint]: else: create_cost = Uint(0) - access_list_cost = Uint(0) - if isinstance( - tx, - ( - AccessListTransaction, - FeeMarketTransaction, - BlobTransaction, - SetCodeTransaction, - ), - ): - for _address, keys in tx.access_list: - access_list_cost += TX_ACCESS_LIST_ADDRESS_COST - access_list_cost += ulen(keys) * TX_ACCESS_LIST_STORAGE_KEY_COST - auth_cost = Uint(0) if isinstance(tx, SetCodeTransaction): auth_cost += Uint(PER_EMPTY_ACCOUNT_COST * len(tx.authorizations)) @@ -304,7 +291,6 @@ def calculate_intrinsic_gas_cost(tx: Transaction) -> Tuple[Uint, Uint]: Uint( inclusion_gas + create_cost - + access_list_cost + auth_cost ), inclusion_gas_floor, diff --git a/src/ethereum/prague/vm/gas.py b/src/ethereum/prague/vm/gas.py index f01e35b3a5..d76b60e201 100644 --- a/src/ethereum/prague/vm/gas.py +++ b/src/ethereum/prague/vm/gas.py @@ -20,7 +20,7 @@ from ethereum.utils.numeric import ceil32, taylor_exponential from ..blocks import Header -from ..transactions import BlobTransaction, Transaction +from ..transactions import BlobTransaction, Transaction, AccessListTransaction, FeeMarketTransaction, SetCodeTransaction from . import Evm from .exceptions import OutOfGasError @@ -73,6 +73,9 @@ MIN_BLOB_GASPRICE = Uint(1) BLOB_GASPRICE_UPDATE_FRACTION = Uint(5007716) +TX_ACCESS_LIST_ADDRESS_COST = Uint(2400) +TX_ACCESS_LIST_STORAGE_KEY_COST = Uint(1900) + GAS_BLS_G1_ADD = Uint(375) GAS_BLS_G1_MUL = Uint(12000) GAS_BLS_G1_MAP = Uint(5500) @@ -327,6 +330,37 @@ def calculate_total_blob_gas(tx: Transaction) -> Uint: return Uint(0) +def calculate_total_access_list_gas(tx: Transaction) -> Uint: + """ + Calculate the total gas cost for an access list in a transaction. + + Parameters + ---------- + tx : + The transaction for which the access list gas is to be calculated. + + Returns + ------- + access_list_gas: `ethereum.base_types.Uint` + The total gas cost for the access list. + """ + access_list_gas = Uint(0) + if isinstance( + tx, + ( + AccessListTransaction, + FeeMarketTransaction, + BlobTransaction, + SetCodeTransaction, + ), + ): + for _address, keys in tx.access_list: + access_list_gas += TX_ACCESS_LIST_ADDRESS_COST + access_list_gas += Uint(len(keys)) * TX_ACCESS_LIST_STORAGE_KEY_COST + + return access_list_gas + + def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint: """ Calculate the blob gasprice for a block.