@@ -113,9 +113,7 @@ class StateChangeTracker:
113113 """
114114
115115
116- def set_block_access_index (
117- tracker : StateChangeTracker , block_access_index : Uint
118- ) -> None :
116+ def set_block_access_index (state : "State" , block_access_index : Uint ) -> None :
119117 """
120118 Set the current block access index for tracking changes.
121119
@@ -129,13 +127,14 @@ def set_block_access_index(
129127
130128 Parameters
131129 ----------
132- tracker :
133- The state change tracker instance .
130+ state :
131+ The current execution state .
134132 block_access_index :
135133 The block access index (0 for pre-execution,
136134 1..n for transactions, n+1 for post-execution).
137135
138136 """
137+ tracker = state .change_tracker
139138 tracker .current_block_access_index = block_access_index
140139 # Clear the pre-storage cache for each new transaction to ensure
141140 # no-op writes are detected relative to the transaction start
@@ -181,9 +180,7 @@ def capture_pre_state(
181180 return tracker .pre_storage_cache [cache_key ]
182181
183182
184- def track_address_access (
185- tracker : StateChangeTracker , address : Address
186- ) -> None :
183+ def track_address_access (state : "State" , address : Address ) -> None :
187184 """
188185 Track that an address was accessed.
189186
@@ -192,18 +189,18 @@ def track_address_access(
192189
193190 Parameters
194191 ----------
195- tracker :
196- The state change tracker instance .
192+ state :
193+ The current execution state .
197194 address :
198195 The account address that was accessed.
199196
200197 """
201- add_touched_account (tracker .block_access_list_builder , address )
198+ add_touched_account (
199+ state .change_tracker .block_access_list_builder , address
200+ )
202201
203202
204- def track_storage_read (
205- tracker : StateChangeTracker , address : Address , key : Bytes32 , state : "State"
206- ) -> None :
203+ def track_storage_read (state : "State" , address : Address , key : Bytes32 ) -> None :
207204 """
208205 Track a storage read operation.
209206
@@ -213,29 +210,28 @@ def track_storage_read(
213210
214211 Parameters
215212 ----------
216- tracker :
217- The state change tracker instance .
213+ state :
214+ The current execution state .
218215 address :
219216 The account address whose storage is being read.
220217 key :
221218 The storage slot being read.
222- state :
223- The current execution state.
224219
225220 """
226- track_address_access (tracker , address )
221+ track_address_access (state , address )
227222
228- capture_pre_state (tracker , address , key , state )
223+ capture_pre_state (state . change_tracker , address , key , state )
229224
230- add_storage_read (tracker .block_access_list_builder , address , key )
225+ add_storage_read (
226+ state .change_tracker .block_access_list_builder , address , key
227+ )
231228
232229
233230def track_storage_write (
234- tracker : StateChangeTracker ,
231+ state : "State" ,
235232 address : Address ,
236233 key : Bytes32 ,
237234 new_value : U256 ,
238- state : "State" ,
239235) -> None :
240236 """
241237 Track a storage write operation.
@@ -246,22 +242,21 @@ def track_storage_write(
246242
247243 Parameters
248244 ----------
249- tracker :
250- The state change tracker instance .
245+ state :
246+ The current execution state .
251247 address :
252248 The account address whose storage is being modified.
253249 key :
254250 The storage slot being written to.
255251 new_value :
256252 The new value to write.
257- state :
258- The current execution state.
259253
260254 [EIP-7928]: https://eips.ethereum.org/EIPS/eip-7928
261255
262256 """
263- track_address_access (tracker , address )
257+ track_address_access (state , address )
264258
259+ tracker = state .change_tracker
265260 pre_value = capture_pre_state (tracker , address , key , state )
266261
267262 value_bytes = new_value .to_be_bytes32 ()
@@ -322,8 +317,33 @@ def capture_pre_balance(
322317 return tracker .pre_balance_cache [address ]
323318
324319
320+ def prepare_balance_tracking (state : "State" , address : Address ) -> None :
321+ """
322+ Prepare for tracking balance changes by caching the pre-transaction
323+ balance.
324+
325+ This should be called before any balance modifications when you need to
326+ ensure the pre-balance is captured for later normalization. This is
327+ particularly important for operations like withdrawals where the balance
328+ might not actually change.
329+
330+ Parameters
331+ ----------
332+ state :
333+ The current execution state.
334+ address :
335+ The account address whose balance will be tracked.
336+
337+ """
338+ # Ensure the address is tracked
339+ track_address_access (state , address )
340+
341+ # Cache the pre-balance for later normalization
342+ capture_pre_balance (state .change_tracker , address , state )
343+
344+
325345def track_balance_change (
326- tracker : StateChangeTracker ,
346+ state : "State" ,
327347 address : Address ,
328348 new_balance : U256 ,
329349) -> None :
@@ -335,16 +355,17 @@ def track_balance_change(
335355
336356 Parameters
337357 ----------
338- tracker :
339- The state change tracker instance .
358+ state :
359+ The current execution state .
340360 address :
341361 The account address whose balance changed.
342362 new_balance :
343363 The new balance value.
344364
345365 """
346- track_address_access (tracker , address )
366+ track_address_access (state , address )
347367
368+ tracker = state .change_tracker
348369 block_access_index = BlockAccessIndex (tracker .current_block_access_index )
349370 add_balance_change (
350371 tracker .block_access_list_builder ,
@@ -362,7 +383,7 @@ def track_balance_change(
362383
363384
364385def track_nonce_change (
365- tracker : StateChangeTracker , address : Address , new_nonce : Uint
386+ state : "State" , address : Address , new_nonce : Uint
366387) -> None :
367388 """
368389 Track a nonce change for an account.
@@ -373,20 +394,19 @@ def track_nonce_change(
373394
374395 Parameters
375396 ----------
376- tracker :
377- The state change tracker instance .
397+ state :
398+ The current execution state .
378399 address :
379400 The account address whose nonce changed.
380401 new_nonce :
381402 The new nonce value.
382- state :
383- The current execution state.
384403
385404 [`CREATE`]: ref:ethereum.forks.amsterdam.vm.instructions.system.create
386405 [`CREATE2`]: ref:ethereum.forks.amsterdam.vm.instructions.system.create2
387406
388407 """
389- track_address_access (tracker , address )
408+ track_address_access (state , address )
409+ tracker = state .change_tracker
390410 block_access_index = BlockAccessIndex (tracker .current_block_access_index )
391411 nonce_u64 = U64 (new_nonce )
392412 add_nonce_change (
@@ -403,7 +423,7 @@ def track_nonce_change(
403423
404424
405425def track_code_change (
406- tracker : StateChangeTracker , address : Address , new_code : Bytes
426+ state : "State" , address : Address , new_code : Bytes
407427) -> None :
408428 """
409429 Track a code change for contract deployment.
@@ -414,8 +434,8 @@ def track_code_change(
414434
415435 Parameters
416436 ----------
417- tracker :
418- The state change tracker instance .
437+ state :
438+ The current execution state .
419439 address :
420440 The address receiving the contract code.
421441 new_code :
@@ -425,7 +445,8 @@ def track_code_change(
425445 [`CREATE2`]: ref:ethereum.forks.amsterdam.vm.instructions.system.create2
426446
427447 """
428- track_address_access (tracker , address )
448+ track_address_access (state , address )
449+ tracker = state .change_tracker
429450 block_access_index = BlockAccessIndex (tracker .current_block_access_index )
430451 add_code_change (
431452 tracker .block_access_list_builder ,
@@ -441,7 +462,7 @@ def track_code_change(
441462
442463
443464def handle_in_transaction_selfdestruct (
444- tracker : StateChangeTracker , address : Address
465+ state : "State" , address : Address
445466) -> None :
446467 """
447468 Handle an account that self-destructed in the same transaction it was
@@ -456,12 +477,13 @@ def handle_in_transaction_selfdestruct(
456477
457478 Parameters
458479 ----------
459- tracker :
460- The state change tracker instance .
480+ state :
481+ The current execution state .
461482 address :
462483 The address that self-destructed.
463484
464485 """
486+ tracker = state .change_tracker
465487 builder = tracker .block_access_list_builder
466488 if address not in builder .accounts :
467489 return
@@ -493,9 +515,7 @@ def handle_in_transaction_selfdestruct(
493515 ]
494516
495517
496- def normalize_balance_changes (
497- tracker : StateChangeTracker , state : "State"
498- ) -> None :
518+ def normalize_balance_changes (state : "State" ) -> None :
499519 """
500520 Normalize balance changes for the current block access index.
501521
@@ -515,15 +535,14 @@ def normalize_balance_changes(
515535
516536 Parameters
517537 ----------
518- tracker :
519- The state change tracker instance.
520538 state :
521539 The current execution state.
522540
523541 """
524542 # Import locally to avoid circular import
525543 from ..state import get_account
526544
545+ tracker = state .change_tracker
527546 builder = tracker .block_access_list_builder
528547 current_index = tracker .current_block_access_index
529548
@@ -548,7 +567,7 @@ def normalize_balance_changes(
548567 ]
549568
550569
551- def begin_call_frame (tracker : StateChangeTracker ) -> None :
570+ def begin_call_frame (state : "State" ) -> None :
552571 """
553572 Begin a new call frame for tracking reverts.
554573
@@ -557,14 +576,14 @@ def begin_call_frame(tracker: StateChangeTracker) -> None:
557576
558577 Parameters
559578 ----------
560- tracker :
561- The state change tracker instance .
579+ state :
580+ The current execution state .
562581
563582 """
564- tracker .call_frame_snapshots .append (CallFrameSnapshot ())
583+ state . change_tracker .call_frame_snapshots .append (CallFrameSnapshot ())
565584
566585
567- def rollback_call_frame (tracker : StateChangeTracker ) -> None :
586+ def rollback_call_frame (state : "State" ) -> None :
568587 """
569588 Rollback changes from the current call frame.
570589
@@ -578,10 +597,11 @@ def rollback_call_frame(tracker: StateChangeTracker) -> None:
578597
579598 Parameters
580599 ----------
581- tracker :
582- The state change tracker instance .
600+ state :
601+ The current execution state .
583602
584603 """
604+ tracker = state .change_tracker
585605 if not tracker .call_frame_snapshots :
586606 return
587607
@@ -651,7 +671,7 @@ def rollback_call_frame(tracker: StateChangeTracker) -> None:
651671 # All touched addresses remain in the access list (already tracked)
652672
653673
654- def commit_call_frame (tracker : StateChangeTracker ) -> None :
674+ def commit_call_frame (state : "State" ) -> None :
655675 """
656676 Commit changes from the current call frame.
657677
@@ -660,9 +680,9 @@ def commit_call_frame(tracker: StateChangeTracker) -> None:
660680
661681 Parameters
662682 ----------
663- tracker :
664- The state change tracker instance .
683+ state :
684+ The current execution state .
665685
666686 """
667- if tracker .call_frame_snapshots :
668- tracker .call_frame_snapshots .pop ()
687+ if state . change_tracker .call_frame_snapshots :
688+ state . change_tracker .call_frame_snapshots .pop ()
0 commit comments