Skip to content

Commit a9e6a18

Browse files
committed
Add EIP-7623
1 parent 46f41bb commit a9e6a18

File tree

2 files changed

+31
-14
lines changed

2 files changed

+31
-14
lines changed

src/ethereum/prague/fork.py

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@
5252
TX_ACCESS_LIST_STORAGE_KEY_COST,
5353
TX_BASE_COST,
5454
TX_CREATE_COST,
55-
TX_DATA_COST_PER_NON_ZERO,
56-
TX_DATA_COST_PER_ZERO,
55+
LEGACY_CALLDATA_TOKEN_COST,
56+
COST_FLOOR_PER_CALLDATA_TOKEN,
5757
AccessListTransaction,
5858
BlobTransaction,
5959
FeeMarketTransaction,
@@ -369,7 +369,7 @@ def check_transaction(
369369
InvalidBlock :
370370
If the transaction is not includable.
371371
"""
372-
if calculate_intrinsic_cost(tx) > tx.gas:
372+
if calculate_intrinsic_cost(tx)[0] > tx.gas:
373373
raise InvalidBlock
374374
if tx.nonce >= 2**64 - 1:
375375
raise InvalidBlock
@@ -754,7 +754,8 @@ def process_transaction(
754754

755755
effective_gas_fee = tx.gas * env.gas_price
756756

757-
gas = tx.gas - calculate_intrinsic_cost(tx)
757+
intrinsic_gas, tokens_in_calldata = calculate_intrinsic_cost(tx)
758+
gas = tx.gas - intrinsic_gas
758759
increment_nonce(env.state, sender)
759760

760761
sender_balance_after_gas_fee = (
@@ -785,8 +786,17 @@ def process_transaction(
785786
)
786787

787788
output = process_message_call(message, env)
788-
789-
gas_used = tx.gas - output.gas_left
789+
790+
floor = Uint(tokens_in_calldata * COST_FLOOR_PER_CALLDATA_TOKEN + TX_BASE_COST)
791+
792+
legacy_cost = Uint(gas_used + tokens_in_calldata * LEGACY_TOKEN_COST)
793+
794+
if legacy_cost < floor:
795+
output.gas_left -= floor - gas_used
796+
gas_used = floor
797+
else:
798+
gas_used = tx.gas - output.gas_left
799+
790800
gas_refund = min(gas_used // 5, output.refund_counter)
791801
gas_refund_amount = (output.gas_left + gas_refund) * env.gas_price
792802

@@ -823,7 +833,7 @@ def process_transaction(
823833
return total_gas_used, output.logs, output.error
824834

825835

826-
def calculate_intrinsic_cost(tx: Transaction) -> Uint:
836+
def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]:
827837
"""
828838
Calculates the gas that is charged before execution is started.
829839
@@ -845,14 +855,19 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint:
845855
-------
846856
verified : `ethereum.base_types.Uint`
847857
The intrinsic cost of the transaction.
858+
verified : `ethereum.base_types.Uint`
859+
The eip-7623 calldata tokens used by the transaction.
848860
"""
849861
data_cost = 0
850-
862+
863+
zerobytes = 0
851864
for byte in tx.data:
852865
if byte == 0:
853-
data_cost += TX_DATA_COST_PER_ZERO
854-
else:
855-
data_cost += TX_DATA_COST_PER_NON_ZERO
866+
zerobytes += 1
867+
868+
tokens_in_calldata = zerobytes + (len(tx.data) - zerobytes) * 4
869+
870+
data_cost = tokens_in_calldata * COST_FLOOR_PER_CALLDATA_TOKEN
856871

857872
if tx.to == Bytes0(b""):
858873
create_cost = TX_CREATE_COST + int(init_code_cost(Uint(len(tx.data))))
@@ -867,7 +882,9 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint:
867882
access_list_cost += TX_ACCESS_LIST_ADDRESS_COST
868883
access_list_cost += len(keys) * TX_ACCESS_LIST_STORAGE_KEY_COST
869884

870-
return Uint(TX_BASE_COST + data_cost + create_cost + access_list_cost)
885+
return Uint(TX_BASE_COST +
886+
data_cost +
887+
create_cost + access_list_cost), tokens_in_calldata
871888

872889

873890
def recover_sender(chain_id: U64, tx: Transaction) -> Address:

src/ethereum/prague/transactions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
from .fork_types import Address, VersionedHash
2121

2222
TX_BASE_COST = 21000
23-
TX_DATA_COST_PER_NON_ZERO = 16
24-
TX_DATA_COST_PER_ZERO = 4
23+
COST_FLOOR_PER_CALLDATA_TOKEN = 10
24+
LEGACY_CALLDATA_TOKEN_COST = 4
2525
TX_CREATE_COST = 32000
2626
TX_ACCESS_LIST_ADDRESS_COST = 2400
2727
TX_ACCESS_LIST_STORAGE_KEY_COST = 1900

0 commit comments

Comments
 (0)