ethereum.forks.amsterdam.state_tracker

State Tracking for Block Execution.

Track state changes on top of a read-only PreState. At block end, accumulated diffs feed into PreState.compute_state_root_and_trie_changes().

.. contents:: Table of Contents :backlinks: none :local:

Introduction

Replace the mutable State class with lightweight state trackers that record diffs. BlockState accumulates committed transaction changes across a block. TransactionState tracks in-flight changes within a single transaction and supports copy-on-write rollback.

BlockState

Accumulate committed transaction-level changes across a block.

Read chain: block writes -> pre_state.

account_reads and storage_reads accumulate across all transactions for BAL generation.

42
@dataclass
class BlockState:

pre_state

53
    pre_state: PreState

account_reads

54
    account_reads: Set[Address] = field(default_factory=set)

account_writes

55
    account_writes: Dict[Address, Optional[Account]] = field(
56
        default_factory=dict
57
    )

storage_reads

58
    storage_reads: Set[Tuple[Address, Bytes32]] = field(default_factory=set)

storage_writes

59
    storage_writes: Dict[Address, Dict[Bytes32, U256]] = field(
60
        default_factory=dict
61
    )

code_writes

62
    code_writes: Dict[Hash32, Bytes] = field(default_factory=dict)

TransactionState

Track in-flight state changes within a single transaction.

Read chain: tx writes -> block writes -> pre_state.

storage_reads and account_reads are shared references that survive rollback (reads from failed calls still appear in the Block Access List).

65
@dataclass
class TransactionState:

parent

77
    parent: BlockState

account_reads

78
    account_reads: Set[Address] = field(default_factory=set)

account_writes

79
    account_writes: Dict[Address, Optional[Account]] = field(
80
        default_factory=dict
81
    )

storage_reads

82
    storage_reads: Set[Tuple[Address, Bytes32]] = field(default_factory=set)

storage_writes

83
    storage_writes: Dict[Address, Dict[Bytes32, U256]] = field(
84
        default_factory=dict
85
    )

code_writes

86
    code_writes: Dict[Hash32, Bytes] = field(default_factory=dict)

created_accounts

87
    created_accounts: Set[Address] = field(default_factory=set)

transient_storage

88
    transient_storage: Dict[Tuple[Address, Bytes32], U256] = field(
89
        default_factory=dict
90
    )

get_account_optional

Get the Account object at an address. Return None (rather than EMPTY_ACCOUNT) if there is no account at the address.

Parameters

tx_state : The transaction state. address : Address to look up.

Returns

account : Optional[Account] Account at address.

def get_account_optional(tx_state: TransactionState, ​​address: Address) -> Optional[Account]:
96
    """
97
    Get the ``Account`` object at an address. Return ``None`` (rather than
98
    ``EMPTY_ACCOUNT``) if there is no account at the address.
99
100
    Parameters
101
    ----------
102
    tx_state :
103
        The transaction state.
104
    address :
105
        Address to look up.
106
107
    Returns
108
    -------
109
    account : ``Optional[Account]``
110
        Account at address.
111
112
    """
113
    tx_state.account_reads.add(address)
114
    if address in tx_state.account_writes:
115
        return tx_state.account_writes[address]
116
    if address in tx_state.parent.account_writes:
117
        return tx_state.parent.account_writes[address]
118
    return tx_state.parent.pre_state.get_account_optional(address)

get_account

Get the Account object at an address. Return EMPTY_ACCOUNT if there is no account at the address.

Use get_account_optional() if you care about the difference between a non-existent account and EMPTY_ACCOUNT.

Parameters

tx_state : The transaction state. address : Address to look up.

Returns

account : Account Account at address.

def get_account(tx_state: TransactionState, ​​address: Address) -> Account:
122
    """
123
    Get the ``Account`` object at an address. Return ``EMPTY_ACCOUNT``
124
    if there is no account at the address.
125
126
    Use ``get_account_optional()`` if you care about the difference
127
    between a non-existent account and ``EMPTY_ACCOUNT``.
128
129
    Parameters
130
    ----------
131
    tx_state :
132
        The transaction state.
133
    address :
134
        Address to look up.
135
136
    Returns
137
    -------
138
    account : ``Account``
139
        Account at address.
140
141
    """
142
    account = get_account_optional(tx_state, address)
143
    if isinstance(account, Account):
144
        return account
145
    else:
146
        return EMPTY_ACCOUNT

get_code

Get the bytecode for a given code hash.

Read chain: tx code_writes -> block code_writes -> pre_state.

Parameters

tx_state : The transaction state. code_hash : Hash of the code to look up.

Returns

code : Bytes The bytecode.

def get_code(tx_state: TransactionState, ​​code_hash: Hash32) -> Bytes:
150
    """
151
    Get the bytecode for a given code hash.
152
153
    Read chain: tx code_writes -> block code_writes -> pre_state.
154
155
    Parameters
156
    ----------
157
    tx_state :
158
        The transaction state.
159
    code_hash :
160
        Hash of the code to look up.
161
162
    Returns
163
    -------
164
    code : ``Bytes``
165
        The bytecode.
166
167
    """
168
    if code_hash == EMPTY_CODE_HASH:
169
        return b""
170
    if code_hash in tx_state.code_writes:
171
        return tx_state.code_writes[code_hash]
172
    if code_hash in tx_state.parent.code_writes:
173
        return tx_state.parent.code_writes[code_hash]
174
    return tx_state.parent.pre_state.get_code(code_hash)

get_storage

Get a value at a storage key on an account. Return U256(0) if the storage key has not been set previously.

Parameters

tx_state : The transaction state. address : Address of the account. key : Key to look up.

Returns

value : U256 Value at the key.

def get_storage(tx_state: TransactionState, ​​address: Address, ​​key: Bytes32) -> U256:
180
    """
181
    Get a value at a storage key on an account. Return ``U256(0)`` if
182
    the storage key has not been set previously.
183
184
    Parameters
185
    ----------
186
    tx_state :
187
        The transaction state.
188
    address :
189
        Address of the account.
190
    key :
191
        Key to look up.
192
193
    Returns
194
    -------
195
    value : ``U256``
196
        Value at the key.
197
198
    """
199
    tx_state.storage_reads.add((address, key))
200
    if address in tx_state.storage_writes:
201
        if key in tx_state.storage_writes[address]:
202
            return tx_state.storage_writes[address][key]
203
    if address in tx_state.parent.storage_writes:
204
        if key in tx_state.parent.storage_writes[address]:
205
            return tx_state.parent.storage_writes[address][key]
206
    return tx_state.parent.pre_state.get_storage(address, key)

get_storage_original

Get the original value in a storage slot i.e. the value before the current transaction began. Read from block-level writes, then pre_state. Return U256(0) for accounts created in the current transaction.

Parameters

tx_state : The transaction state. address : Address of the account to read the value from. key : Key of the storage slot.

def get_storage_original(tx_state: TransactionState, ​​address: Address, ​​key: Bytes32) -> U256:
212
    """
213
    Get the original value in a storage slot i.e. the value before the
214
    current transaction began. Read from block-level writes, then
215
    pre_state. Return ``U256(0)`` for accounts created in the current
216
    transaction.
217
218
    Parameters
219
    ----------
220
    tx_state :
221
        The transaction state.
222
    address :
223
        Address of the account to read the value from.
224
    key :
225
        Key of the storage slot.
226
227
    """
228
    if address in tx_state.created_accounts:
229
        return U256(0)
230
    if address in tx_state.parent.storage_writes:
231
        if key in tx_state.parent.storage_writes[address]:
232
            return tx_state.parent.storage_writes[address][key]
233
    return tx_state.parent.pre_state.get_storage(address, key)

get_transient_storage

Get a value at a storage key on an account from transient storage. Return U256(0) if the storage key has not been set previously.

Parameters

tx_state : The transaction state. address : Address of the account. key : Key to look up.

Returns

value : U256 Value at the key.

def get_transient_storage(tx_state: TransactionState, ​​address: Address, ​​key: Bytes32) -> U256:
239
    """
240
    Get a value at a storage key on an account from transient storage.
241
    Return ``U256(0)`` if the storage key has not been set previously.
242
243
    Parameters
244
    ----------
245
    tx_state :
246
        The transaction state.
247
    address :
248
        Address of the account.
249
    key :
250
        Key to look up.
251
252
    Returns
253
    -------
254
    value : ``U256``
255
        Value at the key.
256
257
    """
258
    return tx_state.transient_storage.get((address, key), U256(0))

account_exists

Check if an account exists in the state trie.

Parameters

tx_state : The transaction state. address : Address of the account that needs to be checked.

Returns

account_exists : bool True if account exists in the state trie, False otherwise.

def account_exists(tx_state: TransactionState, ​​address: Address) -> bool:
262
    """
263
    Check if an account exists in the state trie.
264
265
    Parameters
266
    ----------
267
    tx_state :
268
        The transaction state.
269
    address :
270
        Address of the account that needs to be checked.
271
272
    Returns
273
    -------
274
    account_exists : ``bool``
275
        True if account exists in the state trie, False otherwise.
276
277
    """
278
    return get_account_optional(tx_state, address) is not None

account_has_code_or_nonce

Check if an account has non-zero nonce or non-empty code.

Parameters

tx_state : The transaction state. address : Address of the account that needs to be checked.

Returns

has_code_or_nonce : bool True if the account has non-zero nonce or non-empty code, False otherwise.

def account_has_code_or_nonce(tx_state: TransactionState, ​​address: Address) -> bool:
284
    """
285
    Check if an account has non-zero nonce or non-empty code.
286
287
    Parameters
288
    ----------
289
    tx_state :
290
        The transaction state.
291
    address :
292
        Address of the account that needs to be checked.
293
294
    Returns
295
    -------
296
    has_code_or_nonce : ``bool``
297
        True if the account has non-zero nonce or non-empty code,
298
        False otherwise.
299
300
    """
301
    account = get_account(tx_state, address)
302
    return account.nonce != Uint(0) or account.code_hash != EMPTY_CODE_HASH

account_has_storage

Check if an account has storage.

Parameters

tx_state : The transaction state. address : Address of the account that needs to be checked.

Returns

has_storage : bool True if the account has storage, False otherwise.

def account_has_storage(tx_state: TransactionState, ​​address: Address) -> bool:
306
    """
307
    Check if an account has storage.
308
309
    Parameters
310
    ----------
311
    tx_state :
312
        The transaction state.
313
    address :
314
        Address of the account that needs to be checked.
315
316
    Returns
317
    -------
318
    has_storage : ``bool``
319
        True if the account has storage, False otherwise.
320
321
    """
322
    if tx_state.storage_writes.get(address):
323
        return True
324
    if tx_state.parent.storage_writes.get(address):
325
        return True
326
    return tx_state.parent.pre_state.account_has_storage(address)

account_exists_and_is_empty

Check if an account exists and has zero nonce, empty code and zero balance.

Parameters

tx_state : The transaction state. address : Address of the account that needs to be checked.

Returns

exists_and_is_empty : bool True if an account exists and has zero nonce, empty code and zero balance, False otherwise.

def account_exists_and_is_empty(tx_state: TransactionState, ​​address: Address) -> bool:
332
    """
333
    Check if an account exists and has zero nonce, empty code and zero
334
    balance.
335
336
    Parameters
337
    ----------
338
    tx_state :
339
        The transaction state.
340
    address :
341
        Address of the account that needs to be checked.
342
343
    Returns
344
    -------
345
    exists_and_is_empty : ``bool``
346
        True if an account exists and has zero nonce, empty code and
347
        zero balance, False otherwise.
348
349
    """
350
    account = get_account_optional(tx_state, address)
351
    return (
352
        account is not None
353
        and account.nonce == Uint(0)
354
        and account.code_hash == EMPTY_CODE_HASH
355
        and account.balance == 0
356
    )

is_account_alive

Check whether an account is both in the state and non-empty.

Parameters

tx_state : The transaction state. address : Address of the account that needs to be checked.

Returns

is_alive : bool True if the account is alive.

def is_account_alive(tx_state: TransactionState, ​​address: Address) -> bool:
360
    """
361
    Check whether an account is both in the state and non-empty.
362
363
    Parameters
364
    ----------
365
    tx_state :
366
        The transaction state.
367
    address :
368
        Address of the account that needs to be checked.
369
370
    Returns
371
    -------
372
    is_alive : ``bool``
373
        True if the account is alive.
374
375
    """
376
    account = get_account_optional(tx_state, address)
377
    return account is not None and account != EMPTY_ACCOUNT

set_account

Set the Account object at an address. Setting to None deletes the account (but not its storage, see destroy_account()).

Parameters

tx_state : The transaction state. address : Address to set. account : Account to set at address.

def set_account(tx_state: TransactionState, ​​address: Address, ​​account: Optional[Account]) -> None:
385
    """
386
    Set the ``Account`` object at an address. Setting to ``None``
387
    deletes the account (but not its storage, see
388
    ``destroy_account()``).
389
390
    Parameters
391
    ----------
392
    tx_state :
393
        The transaction state.
394
    address :
395
        Address to set.
396
    account :
397
        Account to set at address.
398
399
    """
400
    tx_state.account_writes[address] = account

set_storage

Set a value at a storage key on an account.

Parameters

tx_state : The transaction state. address : Address of the account. key : Key to set. value : Value to set at the key.

def set_storage(tx_state: TransactionState, ​​address: Address, ​​key: Bytes32, ​​value: U256) -> None:
409
    """
410
    Set a value at a storage key on an account.
411
412
    Parameters
413
    ----------
414
    tx_state :
415
        The transaction state.
416
    address :
417
        Address of the account.
418
    key :
419
        Key to set.
420
    value :
421
        Value to set at the key.
422
423
    """
424
    assert get_account_optional(tx_state, address) is not None
425
    if address not in tx_state.storage_writes:
426
        tx_state.storage_writes[address] = {}
427
    tx_state.storage_writes[address][key] = value

destroy_account

Completely remove the account at address and all of its storage.

This function is made available exclusively for the SELFDESTRUCT opcode. It is expected that SELFDESTRUCT will be disabled in a future hardfork and this function will be removed. Only supports same transaction destruction.

Parameters

tx_state : The transaction state. address : Address of account to destroy.

def destroy_account(tx_state: TransactionState, ​​address: Address) -> None:
431
    """
432
    Completely remove the account at ``address`` and all of its storage.
433
434
    This function is made available exclusively for the ``SELFDESTRUCT``
435
    opcode. It is expected that ``SELFDESTRUCT`` will be disabled in a
436
    future hardfork and this function will be removed. Only supports same
437
    transaction destruction.
438
439
    Parameters
440
    ----------
441
    tx_state :
442
        The transaction state.
443
    address :
444
        Address of account to destroy.
445
446
    """
447
    destroy_storage(tx_state, address)
448
    set_account(tx_state, address, None)

destroy_storage

Completely remove the storage at address.

Convert storage writes to reads before deleting so that accesses from created-then-destroyed accounts appear in the Block Access List. Only supports same transaction destruction.

Parameters

tx_state : The transaction state. address : Address of account whose storage is to be deleted.

def destroy_storage(tx_state: TransactionState, ​​address: Address) -> None:
452
    """
453
    Completely remove the storage at ``address``.
454
455
    Convert storage writes to reads before deleting so that accesses
456
    from created-then-destroyed accounts appear in the Block Access
457
    List. Only supports same transaction destruction.
458
459
    Parameters
460
    ----------
461
    tx_state :
462
        The transaction state.
463
    address :
464
        Address of account whose storage is to be deleted.
465
466
    """
467
    if address in tx_state.storage_writes:
468
        for key in tx_state.storage_writes[address]:
469
            tx_state.storage_reads.add((address, key))
470
        del tx_state.storage_writes[address]

mark_account_created

Mark an account as having been created in the current transaction. This information is used by get_storage_original() to handle an obscure edgecase, and to respect the constraints added to SELFDESTRUCT by EIP-6780.

The marker is not removed even if the account creation reverts. Since the account cannot have had code prior to its creation and can't call get_storage_original(), this is harmless.

Parameters

tx_state : The transaction state. address : Address of the account that has been created.

def mark_account_created(tx_state: TransactionState, ​​address: Address) -> None:
474
    """
475
    Mark an account as having been created in the current transaction.
476
    This information is used by ``get_storage_original()`` to handle an
477
    obscure edgecase, and to respect the constraints added to
478
    SELFDESTRUCT by EIP-6780.
479
480
    The marker is not removed even if the account creation reverts.
481
    Since the account cannot have had code prior to its creation and
482
    can't call ``get_storage_original()``, this is harmless.
483
484
    Parameters
485
    ----------
486
    tx_state :
487
        The transaction state.
488
    address :
489
        Address of the account that has been created.
490
491
    """
492
    tx_state.created_accounts.add(address)

set_transient_storage

Set a value at a storage key on an account in transient storage.

Parameters

tx_state : The transaction state. address : Address of the account. key : Key to set. value : Value to set at the key.

def set_transient_storage(tx_state: TransactionState, ​​address: Address, ​​key: Bytes32, ​​value: U256) -> None:
501
    """
502
    Set a value at a storage key on an account in transient storage.
503
504
    Parameters
505
    ----------
506
    tx_state :
507
        The transaction state.
508
    address :
509
        Address of the account.
510
    key :
511
        Key to set.
512
    value :
513
        Value to set at the key.
514
515
    """
516
    if value == U256(0):
517
        tx_state.transient_storage.pop((address, key), None)
518
    else:
519
        tx_state.transient_storage[(address, key)] = value

modify_state

Modify an Account in the state. If, after modification, the account exists and has zero nonce, empty code, and zero balance, it is destroyed.

def modify_state(tx_state: TransactionState, ​​address: Address, ​​f: Callable[[Account], None]) -> None:
527
    """
528
    Modify an ``Account`` in the state. If, after modification, the
529
    account exists and has zero nonce, empty code, and zero balance, it
530
    is destroyed.
531
    """
532
    set_account(tx_state, address, modify(get_account(tx_state, address), f))
533
    if account_exists_and_is_empty(tx_state, address):
534
        destroy_account(tx_state, address)

move_ether

Move funds between accounts.

Parameters

tx_state : The transaction state. sender_address : Address of the sender. recipient_address : Address of the recipient. amount : The amount to transfer.

def move_ether(tx_state: TransactionState, ​​sender_address: Address, ​​recipient_address: Address, ​​amount: U256) -> None:
543
    """
544
    Move funds between accounts.
545
546
    Parameters
547
    ----------
548
    tx_state :
549
        The transaction state.
550
    sender_address :
551
        Address of the sender.
552
    recipient_address :
553
        Address of the recipient.
554
    amount :
555
        The amount to transfer.
556
557
    """
558
559
    def reduce_sender_balance(sender: Account) -> None:
560
        if sender.balance < amount:
561
            raise AssertionError
562
        sender.balance -= amount
563
564
    def increase_recipient_balance(recipient: Account) -> None:
565
        recipient.balance += amount
566
567
    modify_state(tx_state, sender_address, reduce_sender_balance)
568
    modify_state(tx_state, recipient_address, increase_recipient_balance)

set_account_balance

Set the balance of an account.

Parameters

tx_state : The transaction state. address : Address of the account whose balance needs to be set. amount : The amount that needs to be set in the balance.

def set_account_balance(tx_state: TransactionState, ​​address: Address, ​​amount: U256) -> None:
574
    """
575
    Set the balance of an account.
576
577
    Parameters
578
    ----------
579
    tx_state :
580
        The transaction state.
581
    address :
582
        Address of the account whose balance needs to be set.
583
    amount :
584
        The amount that needs to be set in the balance.
585
586
    """
587
588
    def set_balance(account: Account) -> None:
589
        account.balance = amount
590
591
    modify_state(tx_state, address, set_balance)

increment_nonce

Increment the nonce of an account.

Parameters

tx_state : The transaction state. address : Address of the account whose nonce needs to be incremented.

def increment_nonce(tx_state: TransactionState, ​​address: Address) -> None:
595
    """
596
    Increment the nonce of an account.
597
598
    Parameters
599
    ----------
600
    tx_state :
601
        The transaction state.
602
    address :
603
        Address of the account whose nonce needs to be incremented.
604
605
    """
606
607
    def increase_nonce(sender: Account) -> None:
608
        sender.nonce += Uint(1)
609
610
    modify_state(tx_state, address, increase_nonce)

set_code

Set Account code.

Parameters

tx_state : The transaction state. address : Address of the account whose code needs to be updated. code : The bytecode that needs to be set.

def set_code(tx_state: TransactionState, ​​address: Address, ​​code: Bytes) -> None:
616
    """
617
    Set Account code.
618
619
    Parameters
620
    ----------
621
    tx_state :
622
        The transaction state.
623
    address :
624
        Address of the account whose code needs to be updated.
625
    code :
626
        The bytecode that needs to be set.
627
628
    """
629
    code_hash = keccak256(code)
630
    if code_hash != EMPTY_CODE_HASH:
631
        tx_state.code_writes[code_hash] = code
632
633
    def write_code_hash(sender: Account) -> None:
634
        sender.code_hash = code_hash
635
636
    modify_state(tx_state, address, write_code_hash)

copy_tx_state

Create a snapshot of the transaction state for rollback.

Deep-copy writes and transient storage. The parent reference, created_accounts, storage_reads, and account_reads are shared (not rolled back).

Parameters

tx_state : The transaction state to snapshot.

Returns

snapshot : TransactionState A copy of the transaction state.

def copy_tx_state(tx_state: TransactionState) -> TransactionState:
643
    """
644
    Create a snapshot of the transaction state for rollback.
645
646
    Deep-copy writes and transient storage.  The parent reference,
647
    ``created_accounts``, ``storage_reads``, and ``account_reads``
648
    are shared (not rolled back).
649
650
    Parameters
651
    ----------
652
    tx_state :
653
        The transaction state to snapshot.
654
655
    Returns
656
    -------
657
    snapshot : ``TransactionState``
658
        A copy of the transaction state.
659
660
    """
661
    return TransactionState(
662
        parent=tx_state.parent,
663
        account_writes=dict(tx_state.account_writes),
664
        storage_writes={
665
            addr: dict(slots)
666
            for addr, slots in tx_state.storage_writes.items()
667
        },
668
        code_writes=dict(tx_state.code_writes),
669
        created_accounts=tx_state.created_accounts,
670
        transient_storage=dict(tx_state.transient_storage),
671
        storage_reads=tx_state.storage_reads,
672
        account_reads=tx_state.account_reads,
673
    )

restore_tx_state

Restore transaction state from a snapshot (rollback on failure).

Parameters

tx_state : The transaction state to restore. snapshot : The snapshot to restore from.

def restore_tx_state(tx_state: TransactionState, ​​snapshot: TransactionState) -> None:
679
    """
680
    Restore transaction state from a snapshot (rollback on failure).
681
682
    Parameters
683
    ----------
684
    tx_state :
685
        The transaction state to restore.
686
    snapshot :
687
        The snapshot to restore from.
688
689
    """
690
    tx_state.account_writes = snapshot.account_writes
691
    tx_state.storage_writes = snapshot.storage_writes
692
    tx_state.code_writes = snapshot.code_writes
693
    tx_state.transient_storage = snapshot.transient_storage

incorporate_tx_into_block

Merge transaction writes into the block state and clear for reuse.

Update the BAL builder incrementally by diffing this transaction's writes against the block's cumulative state. Merge reads and touches into block-level sets.

Parameters

tx_state : The transaction state to commit. builder : The BAL builder for incremental updates.

def incorporate_tx_into_block(tx_state: TransactionState, ​​builder: "BlockAccessListBuilder") -> None:
703
    """
704
    Merge transaction writes into the block state and clear for reuse.
705
706
    Update the BAL builder incrementally by diffing this transaction's
707
    writes against the block's cumulative state.  Merge reads and
708
    touches into block-level sets.
709
710
    Parameters
711
    ----------
712
    tx_state :
713
        The transaction state to commit.
714
    builder :
715
        The BAL builder for incremental updates.
716
717
    """
718
    from .block_access_lists import update_builder_from_tx
719
720
    block = tx_state.parent
721
722
    # Update BAL builder before merging writes into block state
723
    update_builder_from_tx(builder, tx_state)
724
725
    # Merge reads and touches into block-level sets
726
    block.storage_reads.update(tx_state.storage_reads)
727
    block.account_reads.update(tx_state.account_reads)
728
729
    # Merge cumulative writes
730
    for address, account in tx_state.account_writes.items():
731
        block.account_writes[address] = account
732
733
    for address, slots in tx_state.storage_writes.items():
734
        if address not in block.storage_writes:
735
            block.storage_writes[address] = {}
736
        block.storage_writes[address].update(slots)
737
738
    block.code_writes.update(tx_state.code_writes)
739
740
    tx_state.account_writes.clear()
741
    tx_state.storage_writes.clear()
742
    tx_state.code_writes.clear()
743
    tx_state.created_accounts.clear()
744
    tx_state.transient_storage.clear()
745
    tx_state.storage_reads = set()
746
    tx_state.account_reads = set()

extract_block_diff

Extract account, storage, and code diff from the block state.

Parameters

block_state : The block state.

Returns

diff : BlockDiff Account, storage, and code changes accumulated during block execution.

def extract_block_diff(block_state: BlockState) -> BlockDiff:
750
    """
751
    Extract account, storage, and code diff from the block state.
752
753
    Parameters
754
    ----------
755
    block_state :
756
        The block state.
757
758
    Returns
759
    -------
760
    diff : `BlockDiff`
761
        Account, storage, and code changes accumulated during block execution.
762
763
    """
764
    return BlockDiff(
765
        account_changes=block_state.account_writes,
766
        storage_changes=block_state.storage_writes,
767
        code_changes=block_state.code_writes,
768
    )