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.

38
@dataclass
class State:

_main_trie

44
    _main_trie: Trie[Address, Optional[Account]] = field(
45
        default_factory=lambda: Trie(secured=True, default=None)
46
    )

_storage_tries

47
    _storage_tries: Dict[Address, Trie[Bytes32, U256]] = field(
48
        default_factory=dict
49
    )

_code_store

50
    _code_store: Dict[Hash32, Bytes] = field(
51
        default_factory=dict, compare=False
52
    )

get_code

Get the bytecode for a given code hash.

Return b"" for EMPTY_CODE_HASH.

def get_code(self, ​​code_hash: Hash32) -> Bytes:
55
        """
56
        Get the bytecode for a given code hash.
57
58
        Return ``b""`` for ``EMPTY_CODE_HASH``.
59
        """
60
        if code_hash == EMPTY_CODE_HASH:
61
            return b""
62
        return self._code_store[code_hash]

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]:
65
        """
66
        Get the account at an address.
67
68
        Return ``None`` if there is no account at the address.
69
        """
70
        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:
73
        """
74
        Get a storage value.
75
76
        Return ``U256(0)`` if the key has not been set.
77
        """
78
        trie = self._storage_tries.get(address)
79
        if trie is None:
80
            return U256(0)
81
82
        value = trie_get(trie, key)
83
84
        assert isinstance(value, U256)
85
        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:
88
        """
89
        Check whether an account has any storage.
90
91
        Only needed for EIP-7610.
92
        """
93
        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]]:
100
        """
101
        Compute the state root after applying changes to the pre-state.
102
103
        Return the new state root together with the internal trie nodes
104
        that were created or modified.
105
        """
106
        main_trie = copy_trie(self._main_trie)
107
        storage_tries = {
108
            k: copy_trie(v) for k, v in self._storage_tries.items()
109
        }
110
111
        for address, account in account_changes.items():
112
            trie_set(main_trie, address, account)
113
114
        for address, slots in storage_changes.items():
115
            trie = storage_tries.get(address)
116
            if trie is None:
117
                trie = Trie(secured=True, default=U256(0))
118
                storage_tries[address] = trie
119
            for key, value in slots.items():
120
                trie_set(trie, key, value)
121
            if trie._data == {}:
122
                del storage_tries[address]
123
124
        def get_storage_root(addr: Address) -> Root:
125
            if addr in storage_tries:
126
                return root(storage_tries[addr])
127
            return EMPTY_TRIE_ROOT
128
129
        state_root_value = root(main_trie, get_storage_root=get_storage_root)
130
131
        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:
135
    """
136
    Free resources held by the state. Used by optimized implementations to
137
    release file descriptors.
138
    """
139
    del state._main_trie
140
    del state._storage_tries
141
    del state._code_store

apply_changes_to_state

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

Parameters

state : The state to update. diff : Account, storage, and code changes to apply.

def apply_changes_to_state(state: State, ​​diff: BlockDiff) -> None:
145
    """
146
    Apply block-level diff to the ``State`` for the next block.
147
148
    Parameters
149
    ----------
150
    state :
151
        The state to update.
152
    diff :
153
        Account, storage, and code changes to apply.
154
155
    """
156
    for address, account in diff.account_changes.items():
157
        trie_set(state._main_trie, address, account)
158
159
    for address, slots in diff.storage_changes.items():
160
        trie = state._storage_tries.get(address)
161
        if trie is None:
162
            trie = Trie(secured=True, default=U256(0))
163
            state._storage_tries[address] = trie
164
        for key, value in slots.items():
165
            trie_set(trie, key, value)
166
        if trie._data == {}:
167
            del state._storage_tries[address]
168
169
    state._code_store.update(diff.code_changes)

store_code

Store bytecode in State.

def store_code(state: State, ​​code: Bytes) -> Hash32:
173
    """
174
    Store bytecode in ``State``.
175
    """
176
    code_hash = keccak256(code)
177
    if code_hash != EMPTY_CODE_HASH:
178
        state._code_store[code_hash] = code
179
    return code_hash

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:
187
    """
188
    Set an account in a ``State``.
189
190
    Setting to ``None`` deletes the account.
191
    """
192
    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:
201
    """
202
    Set a storage value in a ``State``.
203
204
    Setting to ``U256(0)`` deletes the key.
205
    """
206
    assert trie_get(state._main_trie, address) is not None
207
208
    trie = state._storage_tries.get(address)
209
    if trie is None:
210
        trie = Trie(secured=True, default=U256(0))
211
        state._storage_tries[address] = trie
212
    trie_set(trie, key, value)
213
    if trie._data == {}:
214
        del state._storage_tries[address]

state_root

Compute the state root of the current state.

def state_root(state: State) -> Root:
218
    """
219
    Compute the state root of the current state.
220
    """
221
    root_value, _ = state.compute_state_root_and_trie_changes({}, {})
222
    return root_value