Skip to content

Commit 4a6100a

Browse files
committed
WIP: latest system contract changes
1 parent 2dcc7d0 commit 4a6100a

File tree

3 files changed

+67
-7
lines changed

3 files changed

+67
-7
lines changed

src/ethereum/osaka/block_access_lists/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from .tracker import (
1616
StateChangeTracker,
1717
set_transaction_index,
18+
set_system_transaction_index,
1819
track_address_access,
1920
track_balance_change,
2021
track_code_change,
@@ -40,6 +41,7 @@
4041
"build",
4142
"compute_bal_hash",
4243
"set_transaction_index",
44+
"set_system_transaction_index",
4345
"ssz_encode_block_access_list",
4446
"track_address_access",
4547
"track_balance_change",

src/ethereum/osaka/block_access_lists/tracker.py

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ class StateChangeTracker:
6363
"""
6464
The index of the currently executing transaction within the block.
6565
"""
66+
67+
system_tx_index: Optional[int] = None
68+
"""
69+
Special transaction index for system contract calls.
70+
Set to len(transactions) + 1 to track system contract state changes.
71+
"""
6672

6773

6874
def set_transaction_index(tracker: StateChangeTracker, tx_index: int) -> None:
@@ -80,6 +86,24 @@ def set_transaction_index(tracker: StateChangeTracker, tx_index: int) -> None:
8086
The index of the transaction about to be processed.
8187
"""
8288
tracker.current_tx_index = tx_index
89+
tracker.system_tx_index = None # Reset system tx index
90+
91+
92+
def set_system_transaction_index(tracker: StateChangeTracker, tx_index: int) -> None:
93+
"""
94+
Set the system transaction index for tracking system contract changes.
95+
96+
Used to track state changes from system contracts (pre/post execution)
97+
with a special transaction index of len(transactions) + 1.
98+
99+
Parameters
100+
----------
101+
tracker :
102+
The state change tracker instance.
103+
tx_index :
104+
The system transaction index (typically len(transactions) + 1).
105+
"""
106+
tracker.system_tx_index = tx_index
83107

84108

85109
def capture_pre_state(
@@ -200,12 +224,15 @@ def track_storage_write(
200224

201225
value_bytes = new_value.to_be_bytes32()
202226

227+
# Use system tx index if set, otherwise use current tx index
228+
tx_index = tracker.system_tx_index if tracker.system_tx_index is not None else tracker.current_tx_index
229+
203230
if pre_value != new_value:
204231
add_storage_write(
205232
tracker.block_access_list_builder,
206233
address,
207234
key,
208-
U32(tracker.current_tx_index),
235+
U32(tx_index),
209236
value_bytes
210237
)
211238
else:
@@ -239,11 +266,14 @@ def track_balance_change(
239266
"""
240267
track_address_access(tracker, address)
241268

269+
# Use system tx index if set, otherwise use current tx index
270+
tx_index = tracker.system_tx_index if tracker.system_tx_index is not None else tracker.current_tx_index
271+
242272
balance_bytes = U128(new_balance).to_be_bytes16()
243273
add_balance_change(
244274
tracker.block_access_list_builder,
245275
address,
246-
U32(tracker.current_tx_index),
276+
U32(tx_index),
247277
balance_bytes
248278
)
249279

@@ -276,10 +306,14 @@ def track_nonce_change(
276306
[`CREATE2`]: ref:ethereum.osaka.vm.instructions.system.create2
277307
"""
278308
track_address_access(tracker, address)
309+
310+
# Use system tx index if set, otherwise use current tx index
311+
tx_index = tracker.system_tx_index if tracker.system_tx_index is not None else tracker.current_tx_index
312+
279313
add_nonce_change(
280314
tracker.block_access_list_builder,
281315
address,
282-
U32(tracker.current_tx_index),
316+
U32(tx_index),
283317
U64(new_nonce)
284318
)
285319

@@ -313,10 +347,14 @@ def track_code_change(
313347
[`SETCODE`]: ref:ethereum.osaka.vm.instructions.system.setcode
314348
"""
315349
track_address_access(tracker, address)
350+
351+
# Use system tx index if set, otherwise use current tx index
352+
tx_index = tracker.system_tx_index if tracker.system_tx_index is not None else tracker.current_tx_index
353+
316354
add_code_change(
317355
tracker.block_access_list_builder,
318356
address,
319-
U32(tracker.current_tx_index),
357+
U32(tx_index),
320358
new_code
321359
)
322360

src/ethereum/osaka/fork.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
)
3131

3232
from . import vm
33-
from .block_access_lists import StateChangeTracker, compute_bal_hash, build
33+
from .block_access_lists import StateChangeTracker, compute_bal_hash, build, set_system_transaction_index, track_balance_change
3434
from .blocks import Block, Header, Log, Receipt, Withdrawal, encode_receipt
3535
from .bloom import logs_bloom
3636
from .exceptions import (
@@ -582,6 +582,7 @@ def process_system_transaction(
582582
target_address: Address,
583583
system_contract_code: Bytes,
584584
data: Bytes,
585+
change_tracker: Optional[StateChangeTracker] = None,
585586
) -> MessageCallOutput:
586587
"""
587588
Process a system transaction with the given code.
@@ -639,6 +640,7 @@ def process_system_transaction(
639640
disable_precompiles=False,
640641
warm_code_addresses=set(),
641642
parent_evm=None,
643+
change_tracker=change_tracker,
642644
)
643645

644646
system_tx_output = process_message_call(system_tx_message)
@@ -650,6 +652,7 @@ def process_checked_system_transaction(
650652
block_env: vm.BlockEnvironment,
651653
target_address: Address,
652654
data: Bytes,
655+
change_tracker: Optional[StateChangeTracker] = None,
653656
) -> MessageCallOutput:
654657
"""
655658
Process a system transaction and raise an error if the contract does not
@@ -682,6 +685,7 @@ def process_checked_system_transaction(
682685
target_address,
683686
system_contract_code,
684687
data,
688+
change_tracker,
685689
)
686690

687691
if system_tx_output.error:
@@ -697,6 +701,7 @@ def process_unchecked_system_transaction(
697701
block_env: vm.BlockEnvironment,
698702
target_address: Address,
699703
data: Bytes,
704+
change_tracker: Optional[StateChangeTracker] = None,
700705
) -> MessageCallOutput:
701706
"""
702707
Process a system transaction without checking if the contract contains code
@@ -722,6 +727,7 @@ def process_unchecked_system_transaction(
722727
target_address,
723728
system_contract_code,
724729
data,
730+
change_tracker,
725731
)
726732

727733

@@ -759,16 +765,23 @@ def apply_body(
759765
# Initialize Block Access List state change tracker
760766
change_tracker = StateChangeTracker(block_output.block_access_list_builder)
761767

768+
# Set system transaction index for pre-execution system contracts
769+
# Using len(transactions) + 1 as specified
770+
system_tx_index = len(transactions) + 1
771+
set_system_transaction_index(change_tracker, system_tx_index)
772+
762773
process_unchecked_system_transaction(
763774
block_env=block_env,
764775
target_address=BEACON_ROOTS_ADDRESS,
765776
data=block_env.parent_beacon_block_root,
777+
change_tracker=change_tracker,
766778
)
767779

768780
process_unchecked_system_transaction(
769781
block_env=block_env,
770782
target_address=HISTORY_STORAGE_ADDRESS,
771783
data=block_env.block_hashes[-1], # The parent hash
784+
change_tracker=change_tracker,
772785
)
773786

774787
for i, tx in enumerate(map(decode_transaction, transactions)):
@@ -777,9 +790,13 @@ def apply_body(
777790

778791
process_withdrawals(block_env, block_output, withdrawals, change_tracker)
779792

793+
# Set system transaction index for post-execution system contracts
794+
set_system_transaction_index(change_tracker, system_tx_index)
795+
780796
process_general_purpose_requests(
781797
block_env=block_env,
782798
block_output=block_output,
799+
change_tracker=change_tracker,
783800
)
784801

785802
return block_output
@@ -788,6 +805,7 @@ def apply_body(
788805
def process_general_purpose_requests(
789806
block_env: vm.BlockEnvironment,
790807
block_output: vm.BlockOutput,
808+
change_tracker: StateChangeTracker,
791809
) -> None:
792810
"""
793811
Process all the requests in the block.
@@ -809,6 +827,7 @@ def process_general_purpose_requests(
809827
block_env=block_env,
810828
target_address=WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS,
811829
data=b"",
830+
change_tracker=change_tracker,
812831
)
813832

814833
if len(system_withdrawal_tx_output.return_data) > 0:
@@ -820,6 +839,7 @@ def process_general_purpose_requests(
820839
block_env=block_env,
821840
target_address=CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS,
822841
data=b"",
842+
change_tracker=change_tracker,
823843
)
824844

825845
if len(system_consolidation_tx_output.return_data) > 0:
@@ -1022,9 +1042,9 @@ def increase_recipient_balance(recipient: Account) -> None:
10221042

10231043
modify_state(block_env.state, wd.address, increase_recipient_balance)
10241044

1025-
# Track balance change for BAL
1045+
# Track balance change for BAL (withdrawals are tracked as system contract changes)
10261046
new_balance = get_account(block_env.state, wd.address).balance
1027-
change_tracker.track_balance_change(wd.address, U256(new_balance), block_env.state)
1047+
track_balance_change(change_tracker, wd.address, U256(new_balance), block_env.state)
10281048

10291049
if account_exists_and_is_empty(block_env.state, wd.address):
10301050
destroy_account(block_env.state, wd.address)

0 commit comments

Comments
 (0)