ethereum.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.

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

Items external to the virtual machine itself, provided by the environment.

@dataclass
class Evm:
68@dataclass
69class Evm:
70    """The internal state of the virtual machine."""
71
72    pc: Uint
73    stack: List[U256]
74    memory: bytearray
75    code: Bytes
76    gas_left: Uint
77    env: Environment
78    valid_jump_destinations: Set[Uint]
79    logs: Tuple[Log, ...]
80    refund_counter: U256
81    running: bool
82    message: Message
83    output: Bytes
84    accounts_to_delete: Set[Address]
85    touched_accounts: Set[Address]
86    error: Optional[Exception]

The internal state of the virtual machine.

@dataclass
class Message:
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    parent_evm: Optional["Evm"]

Items that are used by contract creation or message call.