ethereum.forks.spurious_dragon.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 | 
|---|
time
| 46 |     time: U256 | 
|---|
difficulty
| 47 |     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.
| 50 | @dataclass | 
|---|
class BlockOutput:
block_gas_used
| 70 |     block_gas_used: Uint = Uint(0) | 
|---|
transactions_trie
| 71 |     transactions_trie: Trie[Bytes, Optional[Transaction]] = field( | 
|---|---|
| 72 |         default_factory=lambda: Trie(secured=False, default=None) | 
| 73 |     ) | 
receipts_trie
| 74 |     receipts_trie: Trie[Bytes, Optional[Receipt]] = field( | 
|---|---|
| 75 |         default_factory=lambda: Trie(secured=False, default=None) | 
| 76 |     ) | 
receipt_keys
| 77 |     receipt_keys: Tuple[Bytes, ...] = field(default_factory=tuple) | 
|---|
block_logs
| 78 |     block_logs: Tuple[Log, ...] = field(default_factory=tuple) | 
|---|
TransactionEnvironment
Items that are used by contract creation or message call.
| 81 | @dataclass | 
|---|
class TransactionEnvironment:
origin
| 87 |     origin: Address | 
|---|
gas_price
| 88 |     gas_price: Uint | 
|---|
gas
| 89 |     gas: Uint | 
|---|
index_in_block
| 90 |     index_in_block: Uint | 
|---|
tx_hash
| 91 |     tx_hash: Optional[Hash32] | 
|---|
Message
Items that are used by contract creation or message call.
| 94 | @dataclass | 
|---|
class Message:
block_env
| 100 |     block_env: BlockEnvironment | 
|---|
tx_env
| 101 |     tx_env: TransactionEnvironment | 
|---|
caller
| 102 |     caller: Address | 
|---|
target
| 103 |     target: Bytes0 | Address | 
|---|
current_target
| 104 |     current_target: Address | 
|---|
gas
| 105 |     gas: Uint | 
|---|
value
| 106 |     value: U256 | 
|---|
data
| 107 |     data: Bytes | 
|---|
code_address
| 108 |     code_address: Optional[Address] | 
|---|
code
| 109 |     code: Bytes | 
|---|
depth
| 110 |     depth: Uint | 
|---|
should_transfer_value
| 111 |     should_transfer_value: bool | 
|---|
parent_evm
| 112 |     parent_evm: Optional["Evm"] | 
|---|
Evm
The internal state of the virtual machine.
| 115 | @dataclass | 
|---|
class Evm:
pc
| 119 |     pc: Uint | 
|---|
stack
| 120 |     stack: List[U256] | 
|---|
memory
| 121 |     memory: bytearray | 
|---|
code
| 122 |     code: Bytes | 
|---|
gas_left
| 123 |     gas_left: Uint | 
|---|
valid_jump_destinations
| 124 |     valid_jump_destinations: Set[Uint] | 
|---|
logs
| 125 |     logs: Tuple[Log, ...] | 
|---|
refund_counter
| 126 |     refund_counter: int | 
|---|
running
| 127 |     running: bool | 
|---|
message
| 128 |     message: Message | 
|---|
output
| 129 |     output: Bytes | 
|---|
accounts_to_delete
| 130 |     accounts_to_delete: Set[Address] | 
|---|
touched_accounts
| 131 |     touched_accounts: Set[Address] | 
|---|
error
| 132 |     error: Optional[EthereumException] | 
|---|
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:
            
| 136 |     """ | 
|---|---|
| 137 |     Incorporate the state of a successful `child_evm` into the parent `evm`. | 
| 138 |  | 
| 139 |     Parameters | 
| 140 |     ---------- | 
| 141 |     evm : | 
| 142 |         The parent `EVM`. | 
| 143 |     child_evm : | 
| 144 |         The child evm to incorporate. | 
| 145 |  | 
| 146 |     """ | 
| 147 |     evm.gas_left += child_evm.gas_left | 
| 148 |     evm.logs += child_evm.logs | 
| 149 |     evm.refund_counter += child_evm.refund_counter | 
| 150 |     evm.accounts_to_delete.update(child_evm.accounts_to_delete) | 
| 151 |     evm.touched_accounts.update(child_evm.touched_accounts) | 
| 152 |     if account_exists_and_is_empty( | 
| 153 |         evm.message.block_env.state, child_evm.message.current_target | 
| 154 |     ): | 
| 155 |         evm.touched_accounts.add(child_evm.message.current_target) | 
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:
            
| 159 |     """ | 
|---|---|
| 160 |     Incorporate the state of an unsuccessful `child_evm` into the parent `evm`. | 
| 161 |  | 
| 162 |     Parameters | 
| 163 |     ---------- | 
| 164 |     evm : | 
| 165 |         The parent `EVM`. | 
| 166 |     child_evm : | 
| 167 |         The child evm to incorporate. | 
| 168 |  | 
| 169 |     """ | 
| 170 |     # In block 2675119, the empty account at 0x3 (the RIPEMD160 precompile) was | 
| 171 |     # cleared despite running out of gas. This is an obscure edge case that can | 
| 172 |     # only happen to a precompile. | 
| 173 |     # According to the general rules governing clearing of empty accounts, the | 
| 174 |     # touch should have been reverted. Due to client bugs, this event went | 
| 175 |     # unnoticed and 0x3 has been exempted from the rule that touches are | 
| 176 |     # reverted in order to preserve this historical behaviour. | 
| 177 |     if RIPEMD160_ADDRESS in child_evm.touched_accounts: | 
| 178 |         evm.touched_accounts.add(RIPEMD160_ADDRESS) | 
| 179 |     if child_evm.message.current_target == RIPEMD160_ADDRESS: | 
| 180 |         if account_exists_and_is_empty( | 
| 181 |             evm.message.block_env.state, child_evm.message.current_target | 
| 182 |         ): | 
| 183 |             evm.touched_accounts.add(RIPEMD160_ADDRESS) | 
| 184 |     evm.gas_left += child_evm.gas_left |