ethereum.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
.
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 base_fee_per_gas: 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] 48 49 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"] 70 71 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]] 94 95 96def incorporate_child_on_success(evm: Evm, child_evm: Evm) -> None: 97 """ 98 Incorporate the state of a successful `child_evm` into the parent `evm`. 99 100 Parameters 101 ---------- 102 evm : 103 The parent `EVM`. 104 child_evm : 105 The child evm to incorporate. 106 """ 107 evm.gas_left += child_evm.gas_left 108 evm.logs += child_evm.logs 109 evm.refund_counter += child_evm.refund_counter 110 evm.accounts_to_delete.update(child_evm.accounts_to_delete) 111 evm.touched_accounts.update(child_evm.touched_accounts) 112 if account_exists_and_is_empty( 113 evm.env.state, child_evm.message.current_target 114 ): 115 evm.touched_accounts.add(child_evm.message.current_target) 116 evm.accessed_addresses.update(child_evm.accessed_addresses) 117 evm.accessed_storage_keys.update(child_evm.accessed_storage_keys) 118 119 120def incorporate_child_on_error(evm: Evm, child_evm: Evm) -> None: 121 """ 122 Incorporate the state of an unsuccessful `child_evm` into the parent `evm`. 123 124 Parameters 125 ---------- 126 evm : 127 The parent `EVM`. 128 child_evm : 129 The child evm to incorporate. 130 """ 131 # In block 2675119, the empty account at 0x3 (the RIPEMD160 precompile) was 132 # cleared despite running out of gas. This is an obscure edge case that can 133 # only happen to a precompile. 134 # According to the general rules governing clearing of empty accounts, the 135 # touch should have been reverted. Due to client bugs, this event went 136 # unnoticed and 0x3 has been exempted from the rule that touches are 137 # reverted in order to preserve this historical behaviour. 138 if RIPEMD160_ADDRESS in child_evm.touched_accounts: 139 evm.touched_accounts.add(RIPEMD160_ADDRESS) 140 if child_evm.message.current_target == RIPEMD160_ADDRESS: 141 if account_exists_and_is_empty( 142 evm.env.state, child_evm.message.current_target 143 ): 144 evm.touched_accounts.add(RIPEMD160_ADDRESS) 145 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 base_fee_per_gas: Uint 42 gas_limit: Uint 43 gas_price: Uint 44 time: U256 45 difficulty: Uint 46 state: State 47 chain_id: U64 48 traces: List[dict]
Items external to the virtual machine itself, provided by the environment.
@dataclass
class
Evm:
73@dataclass 74class Evm: 75 """The internal state of the virtual machine.""" 76 77 pc: Uint 78 stack: List[U256] 79 memory: bytearray 80 code: Bytes 81 gas_left: Uint 82 env: Environment 83 valid_jump_destinations: Set[Uint] 84 logs: Tuple[Log, ...] 85 refund_counter: int 86 running: bool 87 message: Message 88 output: Bytes 89 accounts_to_delete: Set[Address] 90 touched_accounts: Set[Address] 91 return_data: Bytes 92 error: Optional[Exception] 93 accessed_addresses: Set[Address] 94 accessed_storage_keys: Set[Tuple[Address, Bytes32]]
The internal state of the virtual machine.
@dataclass
class
Message:
51@dataclass 52class Message: 53 """ 54 Items that are used by contract creation or message call. 55 """ 56 57 caller: Address 58 target: Union[Bytes0, Address] 59 current_target: Address 60 gas: Uint 61 value: U256 62 data: Bytes 63 code_address: Optional[Address] 64 code: Bytes 65 depth: Uint 66 should_transfer_value: bool 67 is_static: bool 68 accessed_addresses: Set[Address] 69 accessed_storage_keys: Set[Tuple[Address, Bytes32]] 70 parent_evm: Optional["Evm"]
Items that are used by contract creation or message call.