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.