ethereum.berlin.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
.
1""" 2Ethereum Virtual Machine (EVM) 3^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 5.. contents:: Table of Contents 6 :backlinks: none 7 :local: 8 9Introduction 10------------ 11 12The abstract computer which runs the code stored in an 13`.fork_types.Account`. 14""" 15 16from dataclasses import dataclass 17from typing import List, Optional, Set, Tuple, Union 18 19from ethereum.base_types import U64, U256, Bytes, Bytes0, Bytes32, Uint 20from ethereum.crypto.hash import Hash32 21 22from ..fork_types import Address, Log 23from ..state import State, account_exists_and_is_empty 24from .precompiled_contracts import RIPEMD160_ADDRESS 25 26__all__ = ("Environment", "Evm", "Message") 27 28 29@dataclass 30class Environment: 31 """ 32 Items external to the virtual machine itself, provided by the environment. 33 """ 34 35 caller: Address 36 block_hashes: List[Hash32] 37 origin: Address 38 coinbase: Address 39 number: Uint 40 gas_limit: Uint 41 gas_price: Uint 42 time: U256 43 difficulty: Uint 44 state: State 45 chain_id: U64 46 traces: List[dict] 47 48 49@dataclass 50class Message: 51 """ 52 Items that are used by contract creation or message call. 53 """ 54 55 caller: Address 56 target: Union[Bytes0, Address] 57 current_target: Address 58 gas: Uint 59 value: U256 60 data: Bytes 61 code_address: Optional[Address] 62 code: Bytes 63 depth: Uint 64 should_transfer_value: bool 65 is_static: bool 66 accessed_addresses: Set[Address] 67 accessed_storage_keys: Set[Tuple[Address, Bytes32]] 68 parent_evm: Optional["Evm"] 69 70 71@dataclass 72class Evm: 73 """The internal state of the virtual machine.""" 74 75 pc: Uint 76 stack: List[U256] 77 memory: bytearray 78 code: Bytes 79 gas_left: Uint 80 env: Environment 81 valid_jump_destinations: Set[Uint] 82 logs: Tuple[Log, ...] 83 refund_counter: int 84 running: bool 85 message: Message 86 output: Bytes 87 accounts_to_delete: Set[Address] 88 touched_accounts: Set[Address] 89 return_data: Bytes 90 error: Optional[Exception] 91 accessed_addresses: Set[Address] 92 accessed_storage_keys: Set[Tuple[Address, Bytes32]] 93 94 95def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None: 96 """ 97 Incorporate the state of a successful `child_evm` into the parent `evm`. 98 99 Parameters 100 ---------- 101 evm : 102 The parent `EVM`. 103 child_evm : 104 The child evm to incorporate. 105 """ 106 evm.gas_left += child_evm.gas_left 107 evm.logs += child_evm.logs 108 evm.refund_counter += child_evm.refund_counter 109 evm.accounts_to_delete.update(child_evm.accounts_to_delete) 110 evm.touched_accounts.update(child_evm.touched_accounts) 111 if account_exists_and_is_empty( 112 evm.env.state, child_evm.message.current_target 113 ): 114 evm.touched_accounts.add(child_evm.message.current_target) 115 evm.accessed_addresses.update(child_evm.accessed_addresses) 116 evm.accessed_storage_keys.update(child_evm.accessed_storage_keys) 117 118 119def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None: 120 """ 121 Incorporate the state of an unsuccessful `child_evm` into the parent `evm`. 122 123 Parameters 124 ---------- 125 evm : 126 The parent `EVM`. 127 child_evm : 128 The child evm to incorporate. 129 """ 130 # In block 2675119, the empty account at 0x3 (the RIPEMD160 precompile) was 131 # cleared despite running out of gas. This is an obscure edge case that can 132 # only happen to a precompile. 133 # According to the general rules governing clearing of empty accounts, the 134 # touch should have been reverted. Due to client bugs, this event went 135 # unnoticed and 0x3 has been exempted from the rule that touches are 136 # reverted in order to preserve this historical behaviour. 137 if RIPEMD160_ADDRESS in child_evm.touched_accounts: 138 evm.touched_accounts.add(RIPEMD160_ADDRESS) 139 if child_evm.message.current_target == RIPEMD160_ADDRESS: 140 if account_exists_and_is_empty( 141 evm.env.state, child_evm.message.current_target 142 ): 143 evm.touched_accounts.add(RIPEMD160_ADDRESS) 144 evm.gas_left += child_evm.gas_left
@dataclass
class
Environment:
30@dataclass 31class Environment: 32 """ 33 Items external to the virtual machine itself, provided by the environment. 34 """ 35 36 caller: Address 37 block_hashes: List[Hash32] 38 origin: Address 39 coinbase: Address 40 number: Uint 41 gas_limit: Uint 42 gas_price: Uint 43 time: U256 44 difficulty: Uint 45 state: State 46 chain_id: U64 47 traces: List[dict]
Items external to the virtual machine itself, provided by the environment.
@dataclass
class
Evm:
72@dataclass 73class Evm: 74 """The internal state of the virtual machine.""" 75 76 pc: Uint 77 stack: List[U256] 78 memory: bytearray 79 code: Bytes 80 gas_left: Uint 81 env: Environment 82 valid_jump_destinations: Set[Uint] 83 logs: Tuple[Log, ...] 84 refund_counter: int 85 running: bool 86 message: Message 87 output: Bytes 88 accounts_to_delete: Set[Address] 89 touched_accounts: Set[Address] 90 return_data: Bytes 91 error: Optional[Exception] 92 accessed_addresses: Set[Address] 93 accessed_storage_keys: Set[Tuple[Address, Bytes32]]
The internal state of the virtual machine.
@dataclass
class
Message:
50@dataclass 51class Message: 52 """ 53 Items that are used by contract creation or message call. 54 """ 55 56 caller: Address 57 target: Union[Bytes0, Address] 58 current_target: Address 59 gas: Uint 60 value: U256 61 data: Bytes 62 code_address: Optional[Address] 63 code: Bytes 64 depth: Uint 65 should_transfer_value: bool 66 is_static: bool 67 accessed_addresses: Set[Address] 68 accessed_storage_keys: Set[Tuple[Address, Bytes32]] 69 parent_evm: Optional["Evm"]
Items that are used by contract creation or message call.