ethereum.forks.london.vmethereum.forks.arrow_glacier.vm
            
            
            Ethereum Virtual Machine (EVM).
.. contents:: Table of Contents :backlinks: none :local:
Introduction
The abstract computer which runs the code stored in an
.fork_types.Account.
__all__
| 31 | __all__ = ("Environment", "Evm", "Message") | 
|---|
BlockEnvironment
Items external to the virtual machine itself, provided by the environment.
| 34 | @dataclass | 
|---|
class BlockEnvironment:
chain_id
| 40 |     chain_id: U64 | 
|---|
state
| 41 |     state: State | 
|---|
block_gas_limit
| 42 |     block_gas_limit: Uint | 
|---|
block_hashes
| 43 |     block_hashes: List[Hash32] | 
|---|
coinbase
| 44 |     coinbase: Address | 
|---|
number
| 45 |     number: Uint | 
|---|
base_fee_per_gas
| 46 |     base_fee_per_gas: Uint | 
|---|
time
| 47 |     time: U256 | 
|---|
difficulty
| 48 |     difficulty: Uint | 
|---|
BlockOutput
Output from applying the block body to the present state.
Contains the following:
block_gas_used : ethereum.base_types.Uint
Gas used for executing all transactions.
transactions_trie : ethereum.fork_types.Root
Trie of all the transactions in the block.
receipts_trie : ethereum.fork_types.Root
Trie root of all the receipts in the block.
receipt_keys :
Key of all the receipts in the block.
block_logs : Bloom
Logs bloom of all the logs included in all the transactions of the
block.
| 51 | @dataclass | 
|---|
class BlockOutput:
block_gas_used
| 71 |     block_gas_used: Uint = Uint(0) | 
|---|
transactions_trie
| 72 |     transactions_trie: Trie[Bytes, Optional[Bytes | LegacyTransaction]] = ( | 
|---|---|
| 73 |         field(default_factory=lambda: Trie(secured=False, default=None)) | 
| 74 |     ) | 
receipts_trie
| 75 |     receipts_trie: Trie[Bytes, Optional[Bytes | Receipt]] = field( | 
|---|---|
| 76 |         default_factory=lambda: Trie(secured=False, default=None) | 
| 77 |     ) | 
receipt_keys
| 78 |     receipt_keys: Tuple[Bytes, ...] = field(default_factory=tuple) | 
|---|
block_logs
| 79 |     block_logs: Tuple[Log, ...] = field(default_factory=tuple) | 
|---|
TransactionEnvironment
Items that are used by contract creation or message call.
| 82 | @dataclass | 
|---|
class TransactionEnvironment:
origin
| 88 |     origin: Address | 
|---|
gas_price
| 89 |     gas_price: Uint | 
|---|
gas
| 90 |     gas: Uint | 
|---|
access_list_addresses
| 91 |     access_list_addresses: Set[Address] | 
|---|
access_list_storage_keys
| 92 |     access_list_storage_keys: Set[Tuple[Address, Bytes32]] | 
|---|
index_in_block
| 93 |     index_in_block: Optional[Uint] | 
|---|
tx_hash
| 94 |     tx_hash: Optional[Hash32] | 
|---|
Message
Items that are used by contract creation or message call.
| 97 | @dataclass | 
|---|
class Message:
block_env
| 103 |     block_env: BlockEnvironment | 
|---|
tx_env
| 104 |     tx_env: TransactionEnvironment | 
|---|
caller
| 105 |     caller: Address | 
|---|
target
| 106 |     target: Bytes0 | Address | 
|---|
current_target
| 107 |     current_target: Address | 
|---|
gas
| 108 |     gas: Uint | 
|---|
value
| 109 |     value: U256 | 
|---|
data
| 110 |     data: Bytes | 
|---|
code_address
| 111 |     code_address: Optional[Address] | 
|---|
code
| 112 |     code: Bytes | 
|---|
depth
| 113 |     depth: Uint | 
|---|
should_transfer_value
| 114 |     should_transfer_value: bool | 
|---|
is_static
| 115 |     is_static: bool | 
|---|
accessed_addresses
| 116 |     accessed_addresses: Set[Address] | 
|---|
accessed_storage_keys
| 117 |     accessed_storage_keys: Set[Tuple[Address, Bytes32]] | 
|---|
parent_evm
| 118 |     parent_evm: Optional["Evm"] | 
|---|
Evm
The internal state of the virtual machine.
| 121 | @dataclass | 
|---|
class Evm:
pc
| 125 |     pc: Uint | 
|---|
stack
| 126 |     stack: List[U256] | 
|---|
memory
| 127 |     memory: bytearray | 
|---|
code
| 128 |     code: Bytes | 
|---|
gas_left
| 129 |     gas_left: Uint | 
|---|
valid_jump_destinations
| 130 |     valid_jump_destinations: Set[Uint] | 
|---|
logs
| 131 |     logs: Tuple[Log, ...] | 
|---|
refund_counter
| 132 |     refund_counter: int | 
|---|
running
| 133 |     running: bool | 
|---|
message
| 134 |     message: Message | 
|---|
output
| 135 |     output: Bytes | 
|---|
accounts_to_delete
| 136 |     accounts_to_delete: Set[Address] | 
|---|
touched_accounts
| 137 |     touched_accounts: Set[Address] | 
|---|
return_data
| 138 |     return_data: Bytes | 
|---|
error
| 139 |     error: Optional[EthereumException] | 
|---|
accessed_addresses
| 140 |     accessed_addresses: Set[Address] | 
|---|
accessed_storage_keys
| 141 |     accessed_storage_keys: Set[Tuple[Address, Bytes32]] | 
|---|
incorporate_child_on_success
Incorporate the state of a successful child_evm into the parent evm.
Parameters
evm :
The parent EVM.
child_evm :
The child evm to incorporate.
                def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None:
            
| 145 |     """ | 
|---|---|
| 146 |     Incorporate the state of a successful `child_evm` into the parent `evm`. | 
| 147 |  | 
| 148 |     Parameters | 
| 149 |     ---------- | 
| 150 |     evm : | 
| 151 |         The parent `EVM`. | 
| 152 |     child_evm : | 
| 153 |         The child evm to incorporate. | 
| 154 |  | 
| 155 |     """ | 
| 156 |     evm.gas_left += child_evm.gas_left | 
| 157 |     evm.logs += child_evm.logs | 
| 158 |     evm.refund_counter += child_evm.refund_counter | 
| 159 |     evm.accounts_to_delete.update(child_evm.accounts_to_delete) | 
| 160 |     evm.touched_accounts.update(child_evm.touched_accounts) | 
| 161 |     if account_exists_and_is_empty( | 
| 162 |         evm.message.block_env.state, child_evm.message.current_target | 
| 163 |     ): | 
| 164 |         evm.touched_accounts.add(child_evm.message.current_target) | 
| 165 |     evm.accessed_addresses.update(child_evm.accessed_addresses) | 
| 166 |     evm.accessed_storage_keys.update(child_evm.accessed_storage_keys) | 
incorporate_child_on_error
Incorporate the state of an unsuccessful child_evm into the parent evm.
Parameters
evm :
The parent EVM.
child_evm :
The child evm to incorporate.
                def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None:
            
| 170 |     """ | 
|---|---|
| 171 |     Incorporate the state of an unsuccessful `child_evm` into the parent `evm`. | 
| 172 |  | 
| 173 |     Parameters | 
| 174 |     ---------- | 
| 175 |     evm : | 
| 176 |         The parent `EVM`. | 
| 177 |     child_evm : | 
| 178 |         The child evm to incorporate. | 
| 179 |  | 
| 180 |     """ | 
| 181 |     # In block 2675119, the empty account at 0x3 (the RIPEMD160 precompile) was | 
| 182 |     # cleared despite running out of gas. This is an obscure edge case that can | 
| 183 |     # only happen to a precompile. | 
| 184 |     # According to the general rules governing clearing of empty accounts, the | 
| 185 |     # touch should have been reverted. Due to client bugs, this event went | 
| 186 |     # unnoticed and 0x3 has been exempted from the rule that touches are | 
| 187 |     # reverted in order to preserve this historical behaviour. | 
| 188 |     if RIPEMD160_ADDRESS in child_evm.touched_accounts: | 
| 189 |         evm.touched_accounts.add(RIPEMD160_ADDRESS) | 
| 190 |     if child_evm.message.current_target == RIPEMD160_ADDRESS: | 
| 191 |         if account_exists_and_is_empty( | 
| 192 |             evm.message.block_env.state, child_evm.message.current_target | 
| 193 |         ): | 
| 194 |             evm.touched_accounts.add(RIPEMD160_ADDRESS) | 
| 195 |     evm.gas_left += child_evm.gas_left |