ethereum.forks.amsterdam.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__

39
__all__ = ("Environment", "Evm")

TRANSFER_TOPIC

40
TRANSFER_TOPIC = keccak256(b"Transfer(address,address,uint256)")

SYSTEM_ADDRESS

41
SYSTEM_ADDRESS = Address(
42
    bytes.fromhex("fffffffffffffffffffffffffffffffffffffffe")
43
)

CALL_SUCCESS

44
CALL_SUCCESS = U256(1)

BlockEnvironment

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

47
@final
48
@dataclass
class BlockEnvironment:

chain_id

54
    chain_id: U64

state

55
    state: BlockState

block_gas_limit

56
    block_gas_limit: Uint

block_hashes

57
    block_hashes: List[Hash32]

coinbase

58
    coinbase: Address

number

59
    number: Uint

base_fee_per_gas

60
    base_fee_per_gas: Uint

time

61
    time: U256

prev_randao

62
    prev_randao: Bytes32

excess_blob_gas

63
    excess_blob_gas: U64

parent_beacon_block_root

64
    parent_beacon_block_root: Hash32

block_access_list_builder

65
    block_access_list_builder: BlockAccessListBuilder

slot_number

66
    slot_number: U64

BlockOutput

Output from applying the block body to the present state.

Contains the following:

block_gas_used : ExecutionGas Execution gas used for executing all transactions. EIP-8037 names this counter block_execution_gas_used. block_state_gas_used : StateGas State gas used for executing all transactions. cumulative_gas_used : ethereum.base_types.Uint Cumulative gas paid by users (post-refund, post-floor). 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 : Keys of all the receipts in the block. block_logs : Bloom Logs bloom of all the logs included in all the transactions of the block. withdrawals_trie : ethereum.fork_types.Root Trie root of all the withdrawals in the block. blob_gas_used : ethereum.base_types.U64 Total blob gas used in the block. requests : Bytes Hash of all the requests in the block. block_access_list: BlockAccessList The block access list for the block.

69
@final
70
@dataclass
class BlockOutput:

block_gas_used

103
    block_gas_used: ExecutionGas = ExecutionGas(Uint(0))

block_state_gas_used

104
    block_state_gas_used: StateGas = StateGas(Uint(0))

cumulative_gas_used

105
    cumulative_gas_used: Uint = Uint(0)

transactions_trie

106
    transactions_trie: Trie[Bytes, Optional[Bytes | LegacyTransaction]] = (
107
        field(default_factory=lambda: Trie(secured=False, default=None))
108
    )

receipts_trie

109
    receipts_trie: Trie[Bytes, Optional[Bytes | Receipt]] = field(
110
        default_factory=lambda: Trie(secured=False, default=None)
111
    )

receipt_keys

112
    receipt_keys: Tuple[Bytes, ...] = field(default_factory=tuple)

block_logs

113
    block_logs: Tuple[Log, ...] = field(default_factory=tuple)

withdrawals_trie

114
    withdrawals_trie: Trie[Bytes, Optional[Bytes | Withdrawal]] = field(
115
        default_factory=lambda: Trie(secured=False, default=None)
116
    )

blob_gas_used

117
    blob_gas_used: U64 = U64(0)

requests

118
    requests: List[Bytes] = field(default_factory=list)

block_access_list

119
    block_access_list: BlockAccessList = field(default_factory=list)

TransactionEnvironment

Items that are used while processing a transaction.

122
@final
123
@dataclass
class TransactionEnvironment:

origin

129
    origin: Address

recipient

131
    recipient: Address

is_create

132
    is_create: bool

data

133
    data: Bytes

value

134
    value: U256

gas_limit

135
    gas_limit: Uint

effective_gas_price

136
    effective_gas_price: Uint

execution_gas_grant

137
    execution_gas_grant: ExecutionGas

state_gas_reservoir

138
    state_gas_reservoir: StateGas

calldata_floor

139
    calldata_floor: Uint

access_list_addresses

140
    access_list_addresses: Set[Address]

access_list_storage_keys

141
    access_list_storage_keys: Set[Tuple[Address, Bytes32]]

accounts_with_paid_writes

142
    accounts_with_paid_writes: Set[Address]

state

143
    state: TransactionState

blob_versioned_hashes

144
    blob_versioned_hashes: Tuple[VersionedHash, ...]

authorizations

145
    authorizations: Tuple[Authorization, ...]

index_in_block

146
    index_in_block: Optional[Uint]

tx_hash

147
    tx_hash: Optional[Hash32]

Evm

A single call frame: its parameters, gas meter, machine state, and accrued effects.

A call spawns a child frame and each top-level call is a frame at depth zero, so one dataclass describes them all.

150
@final
151
@dataclass
class Evm:

pc

161
    pc: Uint

stack

162
    stack: List[U256]

memory

163
    memory: bytearray

code

165
    code: Bytes

gas_meter

166
    gas_meter: GasMeter

valid_jump_destinations

167
    valid_jump_destinations: Set[Uint]

logs

168
    logs: Tuple[Log, ...]

running

169
    running: bool

block_env

172
    block_env: BlockEnvironment

tx_env

173
    tx_env: TransactionEnvironment

caller

174
    caller: Address

current_target

175
    current_target: Address

value

176
    value: U256

call_data

177
    call_data: Bytes

code_address

178
    code_address: Optional[Address]

depth

179
    depth: Uint

should_transfer_value

180
    should_transfer_value: bool

is_static

181
    is_static: bool

disable_precompiles

182
    disable_precompiles: bool

parent_evm

183
    parent_evm: Optional["Evm"]

output

185
    output: Bytes

accounts_to_delete

186
    accounts_to_delete: Set[Address]

return_data

187
    return_data: Bytes

error

188
    error: Optional[EthereumException]

accessed_addresses

189
    accessed_addresses: Set[Address]

accessed_storage_keys

190
    accessed_storage_keys: Set[Tuple[Address, Bytes32]]

incorporate_child

Incorporate the state of a returning child_evm into the parent evm.

Gas flows back to the parent regardless of the child's fate. A failed child settles its own meter before returning -- its state gas rolled back to the baseline, its spill refilled, and its refunds discarded -- so absorbing the meter unconditionally reclaims exactly the gas the child gives back. Everything else the child accumulated -- logs, scheduled self-destructs, refunds, and warmed access sets -- survives only on success, dying with a failed child's reverted state.

Parameters

evm : The parent EVM. child_evm : The child evm to incorporate.

def incorporate_child(evm: Evm, ​​child_evm: Evm) -> None:
194
    <snip>
217
    child_meter = child_evm.gas_meter
218
    # Only the top frame commits state gas; a child never carries any.
219
    assert child_meter.state_gas_committed_spill == Uint(0)
220
221
    if child_evm.error:
222
        # A failed child arrives settled: rolled back to its baseline,
223
        # spill refilled, refunds discarded.
224
        assert child_meter.state_gas_spilled == Uint(0)
225
        assert child_meter.refund_counter == 0
226
        assert child_meter.state_gas_left == child_meter.state_gas_baseline
227
228
    # Gas returns to the parent regardless of the child's fate.
229
    # Note that upon failure, the child already arrives settled.
230
    gas_meter = evm.gas_meter
231
    gas_meter.gas_left += child_meter.gas_left
232
    gas_meter.state_gas_left += child_meter.state_gas_left
233
    gas_meter.state_gas_spilled += child_meter.state_gas_spilled
234
    gas_meter.refund_counter += child_meter.refund_counter
235
236
    # Everything else survives only on success.
237
    if not child_evm.error:
238
        evm.logs += child_evm.logs
239
        evm.accounts_to_delete.update(child_evm.accounts_to_delete)
240
        evm.accessed_addresses.update(child_evm.accessed_addresses)
241
        evm.accessed_storage_keys.update(child_evm.accessed_storage_keys)

emit_transfer_log

Emit a LOG3 for all ETH transfers satisfying EIP-7708.

Parameters

evm : The state of the ethereum virtual machine sender : The account address sending the transfer recipient : The account address receiving the transfer transfer_amount : The amount of ETH transacted

def emit_transfer_log(evm: Evm, ​​sender: Address, ​​recipient: Address, ​​transfer_amount: U256) -> None:
250
    <snip>
265
    if transfer_amount == 0:
266
        return
267
268
    padded_sender = left_pad_zero_bytes(sender, 32)
269
    padded_recipient = left_pad_zero_bytes(recipient, 32)
270
    log_entry = Log(
271
        address=SYSTEM_ADDRESS,
272
        topics=(
273
            TRANSFER_TOPIC,
274
            Hash32(padded_sender),
275
            Hash32(padded_recipient),
276
        ),
277
        data=transfer_amount.to_be_bytes32(),
278
    )
279
280
    evm.logs = evm.logs + (log_entry,)