Skip to content

Commit 78d2b8d

Browse files
committed
refactor(spec-specs): Refactor state changes and their frames
1 parent 4a3a7e0 commit 78d2b8d

File tree

9 files changed

+453
-432
lines changed

9 files changed

+453
-432
lines changed

src/ethereum/forks/amsterdam/fork.py

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,13 @@
6969
commit_transaction_frame,
7070
create_child_frame,
7171
get_block_access_index,
72-
handle_in_transaction_selfdestruct,
7372
increment_block_access_index,
7473
merge_on_success,
7574
normalize_balance_changes_for_transaction,
7675
track_address,
7776
track_balance_change,
77+
track_nonce_change,
78+
track_selfdestruct,
7879
)
7980
from .transactions import (
8081
AccessListTransaction,
@@ -647,8 +648,12 @@ def process_system_transaction(
647648
authorizations=(),
648649
index_in_block=None,
649650
tx_hash=None,
651+
state_changes=system_tx_state_changes,
650652
)
651653

654+
# Create call frame as child of tx frame
655+
call_frame = create_child_frame(tx_env.state_changes)
656+
652657
system_tx_message = Message(
653658
block_env=block_env,
654659
tx_env=tx_env,
@@ -667,14 +672,14 @@ def process_system_transaction(
667672
accessed_storage_keys=set(),
668673
disable_precompiles=False,
669674
parent_evm=None,
670-
transaction_state_changes=system_tx_state_changes,
675+
state_changes=call_frame,
671676
)
672677

673678
system_tx_output = process_message_call(system_tx_message)
674679

675680
# Merge system transaction changes back to block frame
676681
# System transactions always succeed (or block is invalid)
677-
merge_on_success(system_tx_state_changes)
682+
merge_on_success(tx_env.state_changes)
678683

679684
return system_tx_output
680685

@@ -909,7 +914,9 @@ def process_transaction(
909914
# The frame will read the current block_access_index from the block frame
910915
increment_block_access_index(block_env.block_state_changes)
911916
tx_state_changes = create_child_frame(block_env.block_state_changes)
917+
block_access_index = get_block_access_index(block_env.block_state_changes)
912918

919+
# Capture coinbase pre-balance for net-zero filtering
913920
coinbase_pre_balance = get_account(
914921
block_env.state, block_env.coinbase
915922
).balance
@@ -947,16 +954,30 @@ def process_transaction(
947954
effective_gas_fee = tx.gas * effective_gas_price
948955

949956
gas = tx.gas - intrinsic_gas
950-
increment_nonce(block_env.state, sender, tx_state_changes)
957+
958+
# Track sender nonce increment
959+
increment_nonce(block_env.state, sender)
960+
sender_nonce_after = get_account(block_env.state, sender).nonce
961+
track_nonce_change(
962+
tx_state_changes, sender, U64(sender_nonce_after), block_access_index
963+
)
964+
965+
# Track sender balance deduction for gas fee
966+
sender_balance_before = get_account(block_env.state, sender).balance
967+
track_address(tx_state_changes, sender)
968+
capture_pre_balance(tx_state_changes, sender, sender_balance_before)
951969

952970
sender_balance_after_gas_fee = (
953971
Uint(sender_account.balance) - effective_gas_fee - blob_gas_fee
954972
)
955973
set_account_balance(
956-
block_env.state,
974+
block_env.state, sender, U256(sender_balance_after_gas_fee)
975+
)
976+
track_balance_change(
977+
tx_state_changes,
957978
sender,
958979
U256(sender_balance_after_gas_fee),
959-
tx_state_changes,
980+
block_access_index,
960981
)
961982

962983
access_list_addresses = set()
@@ -991,13 +1012,13 @@ def process_transaction(
9911012
authorizations=authorizations,
9921013
index_in_block=index,
9931014
tx_hash=get_transaction_hash(encode_transaction(tx)),
1015+
state_changes=tx_state_changes,
9941016
)
9951017

9961018
message = prepare_message(
9971019
block_env,
9981020
tx_env,
9991021
tx,
1000-
tx_state_changes,
10011022
)
10021023

10031024
tx_output = process_message_call(message)
@@ -1027,22 +1048,26 @@ def process_transaction(
10271048
sender_balance_after_refund = get_account(
10281049
block_env.state, sender
10291050
).balance + U256(gas_refund_amount)
1030-
set_account_balance(
1031-
block_env.state,
1051+
set_account_balance(block_env.state, sender, sender_balance_after_refund)
1052+
track_balance_change(
1053+
tx_env.state_changes,
10321054
sender,
10331055
sender_balance_after_refund,
1034-
tx_state_changes,
1056+
block_access_index,
10351057
)
10361058

10371059
coinbase_balance_after_mining_fee = get_account(
10381060
block_env.state, block_env.coinbase
10391061
).balance + U256(transaction_fee)
10401062

10411063
set_account_balance(
1042-
block_env.state,
1064+
block_env.state, block_env.coinbase, coinbase_balance_after_mining_fee
1065+
)
1066+
track_balance_change(
1067+
tx_env.state_changes,
10431068
block_env.coinbase,
10441069
coinbase_balance_after_mining_fee,
1045-
tx_state_changes,
1070+
block_access_index,
10461071
)
10471072

10481073
if coinbase_balance_after_mining_fee == 0 and account_exists_and_is_empty(
@@ -1078,19 +1103,17 @@ def process_transaction(
10781103
# into block frame. Must happen AFTER destroy_account so net-zero filtering
10791104
# sees the correct post-transaction balance (0 for destroyed accounts).
10801105
normalize_balance_changes_for_transaction(
1081-
tx_state_changes,
1082-
BlockAccessIndex(
1083-
get_block_access_index(block_env.block_state_changes)
1084-
),
1106+
tx_env.state_changes,
1107+
block_access_index,
10851108
block_env.state,
10861109
)
10871110

1088-
commit_transaction_frame(tx_state_changes)
1111+
commit_transaction_frame(tx_env.state_changes)
10891112

1090-
# EIP-7928: Handle in-transaction self-destruct normalization AFTER merge
1113+
# EIP-7928: Track in-transaction self-destruct normalization AFTER merge
10911114
# Convert storage writes to reads and remove nonce/code changes
10921115
for address in tx_output.accounts_to_delete:
1093-
handle_in_transaction_selfdestruct(
1116+
track_selfdestruct(
10941117
block_env.block_state_changes,
10951118
address,
10961119
BlockAccessIndex(
@@ -1107,6 +1130,10 @@ def process_withdrawals(
11071130
"""
11081131
Increase the balance of the withdrawing account.
11091132
"""
1133+
# Get block access index for withdrawals (post-exec phase)
1134+
block_access_index = get_block_access_index(block_env.block_state_changes)
1135+
1136+
# Capture pre-state for withdrawal balance filtering
11101137
withdrawal_addresses = {wd.address for wd in withdrawals}
11111138
for address in withdrawal_addresses:
11121139
pre_balance = get_account(block_env.state, address).balance
@@ -1129,20 +1156,20 @@ def increase_recipient_balance(recipient: Account) -> None:
11291156

11301157
new_balance = get_account(block_env.state, wd.address).balance
11311158
track_balance_change(
1132-
block_env.block_state_changes, wd.address, new_balance
1159+
block_env.block_state_changes,
1160+
wd.address,
1161+
new_balance,
1162+
block_access_index,
11331163
)
11341164

11351165
if account_exists_and_is_empty(block_env.state, wd.address):
11361166
destroy_account(block_env.state, wd.address)
11371167

11381168
# EIP-7928: Normalize balance changes after all withdrawals
11391169
# Filters out net-zero changes
1140-
11411170
normalize_balance_changes_for_transaction(
11421171
block_env.block_state_changes,
1143-
BlockAccessIndex(
1144-
get_block_access_index(block_env.block_state_changes)
1145-
),
1172+
block_access_index,
11461173
block_env.state,
11471174
)
11481175

0 commit comments

Comments
 (0)