Skip to content
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

Add EIP-7623 #966

Merged
merged 9 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
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
48 changes: 38 additions & 10 deletions src/ethereum/prague/fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@
state_root,
)
from .transactions import (
FLOOR_CALLDATA_COST,
STANDARD_CALLDATA_TOKEN_COST,
TX_ACCESS_LIST_ADDRESS_COST,
TX_ACCESS_LIST_STORAGE_KEY_COST,
TX_BASE_COST,
TX_CREATE_COST,
TX_DATA_COST_PER_NON_ZERO,
TX_DATA_COST_PER_ZERO,
AccessListTransaction,
BlobTransaction,
FeeMarketTransaction,
Expand Down Expand Up @@ -395,7 +395,9 @@ def check_transaction(
InvalidBlock :
If the transaction is not includable.
"""
if calculate_intrinsic_cost(tx) > tx.gas:
intrinsic_gas, tokens_in_calldata = calculate_intrinsic_cost(tx)
floor = Uint(tokens_in_calldata * FLOOR_CALLDATA_COST + TX_BASE_COST)
if max(intrinsic_gas, floor) > tx.gas:
raise InvalidBlock
if tx.nonce >= 2**64 - 1:
raise InvalidBlock
Expand Down Expand Up @@ -921,7 +923,9 @@ def process_transaction(

effective_gas_fee = tx.gas * env.gas_price

gas = tx.gas - calculate_intrinsic_cost(tx)
intrinsic_gas, tokens_in_calldata = calculate_intrinsic_cost(tx)

gas = tx.gas - intrinsic_gas
increment_nonce(env.state, sender)

sender_balance_after_gas_fee = (
Expand Down Expand Up @@ -964,7 +968,19 @@ def process_transaction(

output = process_message_call(message, env)

# For EIP-7623 gas_used includes the intrinsic costs with the floor price
# for calldata.
gas_used = tx.gas - output.gas_left

# EIP-7623 floor price (note: no EVM costs)

# Transactions with less gas used than the floor pay at the floor cost.
floor = Uint(tokens_in_calldata * FLOOR_CALLDATA_COST + TX_BASE_COST)
if gas_used < floor:
petertdavies marked this conversation as resolved.
Show resolved Hide resolved
gas_used = floor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this correction should be applied after the gas refund is applied. Argumentation and spec clarification here: ethereum/EIPs#9227.


output.gas_left = tx.gas - gas_used

gas_refund = min(gas_used // 5, output.refund_counter)
gas_refund_amount = (output.gas_left + gas_refund) * env.gas_price

Expand Down Expand Up @@ -1001,7 +1017,7 @@ def process_transaction(
return total_gas_used, output.logs, output.error


def calculate_intrinsic_cost(tx: Transaction) -> Uint:
def calculate_intrinsic_cost(tx: Transaction) -> Tuple[Uint, Uint]:
"""
Calculates the gas that is charged before execution is started.

Expand All @@ -1023,14 +1039,19 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint:
-------
verified : `ethereum.base_types.Uint`
The intrinsic cost of the transaction.
tokens_in_calldata : `ethereum.base_types.Uint`
The eip-7623 calldata tokens used by the transaction.
"""
data_cost = 0

zero_bytes = 0
for byte in tx.data:
if byte == 0:
data_cost += TX_DATA_COST_PER_ZERO
else:
data_cost += TX_DATA_COST_PER_NON_ZERO
zero_bytes += 1

tokens_in_calldata = zero_bytes + (len(tx.data) - zero_bytes) * 4

data_cost = tokens_in_calldata * STANDARD_CALLDATA_TOKEN_COST

if tx.to == Bytes0(b""):
create_cost = TX_CREATE_COST + int(init_code_cost(Uint(len(tx.data))))
Expand All @@ -1055,8 +1076,15 @@ def calculate_intrinsic_cost(tx: Transaction) -> Uint:
if isinstance(tx, SetCodeTransaction):
auth_cost += PER_EMPTY_ACCOUNT_COST * len(tx.authorizations)

return Uint(
TX_BASE_COST + data_cost + create_cost + access_list_cost + auth_cost
return (
Uint(
TX_BASE_COST
+ data_cost
+ create_cost
+ access_list_cost
+ auth_cost
),
Uint(tokens_in_calldata),
)


Expand Down
4 changes: 2 additions & 2 deletions src/ethereum/prague/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
from .fork_types import Address, Authorization, VersionedHash

TX_BASE_COST = 21000
TX_DATA_COST_PER_NON_ZERO = 16
TX_DATA_COST_PER_ZERO = 4
FLOOR_CALLDATA_COST = 10
STANDARD_CALLDATA_TOKEN_COST = 4
TX_CREATE_COST = 32000
TX_ACCESS_LIST_ADDRESS_COST = 2400
TX_ACCESS_LIST_STORAGE_KEY_COST = 1900
Expand Down
4 changes: 3 additions & 1 deletion whitelist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ Bytes64
Bytes8
Bytes256
Bytes0
calldata
copyreg
copytree
coinbase
coincurve
crypto
E501
EIP
encodings
endian
eth
Expand Down Expand Up @@ -459,4 +461,4 @@ exponentiate
monomial
impl

eoa
eoa
Loading