ethereum.forks.amsterdam.state

State.

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

Introduction

The state contains all information that is preserved between transactions.

It consists of a main account trie and storage tries for each contract.

There is a distinction between an account that does not exist and EMPTY_ACCOUNT.

State

Contains all information that is preserved between transactions.

30
@dataclass
class State:

_main_trie

36
    _main_trie: Trie[Address, Optional[Account]] = field(
37
        default_factory=lambda: Trie(secured=True, default=None)
38
    )

_storage_tries

39
    _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field(
40
        default_factory=dict
41
    )

get_account_optional

Get the account at an address.

Return None if there is no account at the address.

def get_account_optional(self, ​​address: Address) -> Optional[Account]:
44
        """
45
        Get the account at an address.
46
47
        Return ``None`` if there is no account at the address.
48
        """
49
        return trie_get(self._main_trie, address)

get_storage

Get a storage value.

Return U256(0) if the key has not been set.

def get_storage(self, ​​address: Address, ​​key: Bytes32) -> U256:
52
        """
53
        Get a storage value.
54
55
        Return ``U256(0)`` if the key has not been set.
56
        """
57
        trie = self._storage_tries.get(address)
58
        if trie is None:
59
            return U256(0)
60
61
        value = trie_get(trie, key)
62
63
        assert isinstance(value, U256)
64
        return value

account_has_storage

Check whether an account has any storage.

Only needed for EIP-7610.

def account_has_storage(self, ​​address: Address) -> bool:
67
        """
68
        Check whether an account has any storage.
69
70
        Only needed for EIP-7610.
71
        """
72
        return address in self._storage_tries

compute_state_root_and_trie_changes

Compute the state root after applying changes to the pre-state.

Return the new state root together with the internal trie nodes that were created or modified.

def compute_state_root_and_trie_changes(self, ​​account_changes: Dict[Address, Optional[Account]], ​​storage_changes: Dict[Address, Dict[Bytes32, U256]]) -> Tuple[Root, List[InternalNode]]:
79
        """
80
        Compute the state root after applying changes to the pre-state.
81
82
        Return the new state root together with the internal trie nodes
83
        that were created or modified.
84
        """
85
        main_trie = copy_trie(self._main_trie)
86
        storage_tries = {
87
            k: copy_trie(v) for k, v in self._storage_tries.items()
88
        }
89
90
        for address, account in account_changes.items():
91
            trie_set(main_trie, address, account)
92
93
        for address, slots in storage_changes.items():
94
            trie = storage_tries.get(address)
95
            if trie is None:
96
                trie = Trie(secured=True, default=U256(0))
97
                storage_tries[address] = trie
98
            for key, value in slots.items():
99
                trie_set(trie, key, value)
100
            if trie._data == {}:
101
                del storage_tries[address]
102
103
        def get_storage_root(addr: Address) -> Root:
104
            if addr in storage_tries:
105
                return root(storage_tries[addr])
106
            return EMPTY_TRIE_ROOT
107
108
        state_root_value = root(main_trie, get_storage_root=get_storage_root)
109
110
        return state_root_value, []

close_state

Free resources held by the state. Used by optimized implementations to release file descriptors.

def close_state(state: State) -> None:
114
    """
115
    Free resources held by the state. Used by optimized implementations to
116
    release file descriptors.
117
    """
118
    del state._main_trie
119
    del state._storage_tries

apply_changes_to_state

Apply block-level diffs to the State for the next block.

Parameters

state : The state to update. account_changes : Account changes to apply. storage_changes : Storage changes to apply.

def apply_changes_to_state(state: State, ​​account_changes: Dict[Address, Optional[Account]], ​​storage_changes: Dict[Address, Dict[Bytes32, U256]]) -> None:
127
    """
128
    Apply block-level diffs to the ``State`` for the next block.
129
130
    Parameters
131
    ----------
132
    state :
133
        The state to update.
134
    account_changes :
135
        Account changes to apply.
136
    storage_changes :
137
        Storage changes to apply.
138
139
    """
140
    for address, account in account_changes.items():
141
        trie_set(state._main_trie, address, account)
142
143
    for address, slots in storage_changes.items():
144
        trie = state._storage_tries.get(address)
145
        if trie is None:
146
            trie = Trie(secured=True, default=U256(0))
147
            state._storage_tries[address] = trie
148
        for key, value in slots.items():
149
            trie_set(trie, key, value)
150
        if trie._data == {}:
151
            del state._storage_tries[address]

set_account

Set an account in a State.

Setting to None deletes the account.

def set_account(state: State, ​​address: Address, ​​account: Optional[Account]) -> None:
159
    """
160
    Set an account in a ``State``.
161
162
    Setting to ``None`` deletes the account.
163
    """
164
    trie_set(state._main_trie, address, account)

set_storage

Set a storage value in a State.

Setting to U256(0) deletes the key.

def set_storage(state: State, ​​address: Address, ​​key: Bytes32, ​​value: U256) -> None:
173
    """
174
    Set a storage value in a ``State``.
175
176
    Setting to ``U256(0)`` deletes the key.
177
    """
178
    assert trie_get(state._main_trie, address) is not None
179
180
    trie = state._storage_tries.get(address)
181
    if trie is None:
182
        trie = Trie(secured=True, default=U256(0))
183
        state._storage_tries[address] = trie
184
    trie_set(trie, key, value)
185
    if trie._data == {}:
186
        del state._storage_tries[address]

state_root

Compute the state root of the current state.

def state_root(state: State) -> Root:
190
    """
191
    Compute the state root of the current state.
192
    """
193
    root_value, _ = state.compute_state_root_and_trie_changes({}, {})
194
    return root_value