ethereum.forks.amsterdam.vm.gas

Ethereum Virtual Machine (EVM) Gas.

.. contents:: Table of Contents :backlinks: none :local:

Introduction

EVM gas constants and calculators.

StateGasCosts

EIP-8037 state-gas constants.

Kept separate from GasCosts because these carry a different unit: state-byte counts that convert into gas via COST_PER_STATE_BYTE.

class StateGasCosts:

COST_PER_STATE_BYTE

47
    COST_PER_STATE_BYTE: Final[StateGasPerByte] = StateGasPerByte(Uint(1530))

STATE_BYTES_PER_NEW_ACCOUNT

48
    STATE_BYTES_PER_NEW_ACCOUNT: Final[Uint] = Uint(120)

STATE_BYTES_PER_STORAGE_SET

49
    STATE_BYTES_PER_STORAGE_SET: Final[Uint] = Uint(64)

STATE_BYTES_PER_AUTH_BASE

50
    STATE_BYTES_PER_AUTH_BASE: Final[Uint] = Uint(23)

STORAGE_SET

51
    STORAGE_SET: Final[StateGas] = (
52
        STATE_BYTES_PER_STORAGE_SET * COST_PER_STATE_BYTE
53
    )

NEW_ACCOUNT

54
    NEW_ACCOUNT: Final[StateGas] = (
55
        STATE_BYTES_PER_NEW_ACCOUNT * COST_PER_STATE_BYTE
56
    )

AUTH_BASE

57
    AUTH_BASE: Final[StateGas] = (
58
        STATE_BYTES_PER_AUTH_BASE * COST_PER_STATE_BYTE
59
    )

GasCosts

Constant gas values for the EVM.

class GasCosts:

BASE

69
    BASE: Final[Uint] = Uint(2)

VERY_LOW

70
    VERY_LOW: Final[Uint] = Uint(3)

LOW

71
    LOW: Final[Uint] = Uint(5)

MID

72
    MID: Final[Uint] = Uint(8)

HIGH

73
    HIGH: Final[Uint] = Uint(10)

WARM_ACCESS

76
    WARM_ACCESS: Final[Uint] = Uint(100)

COLD_ACCOUNT_ACCESS

77
    COLD_ACCOUNT_ACCESS: Final[Uint] = Uint(3000)

COLD_STORAGE_ACCESS

78
    COLD_STORAGE_ACCESS: Final[Uint] = Uint(3000)

STORAGE_WRITE

81
    STORAGE_WRITE: Final[Uint] = Uint(10000)

CALL_VALUE

84
    CALL_VALUE: Final[Uint] = Uint(10300)

CALL_STIPEND

85
    CALL_STIPEND: Final[Uint] = Uint(2300)

ACCOUNT_WRITE

86
    ACCOUNT_WRITE: Final[Uint] = Uint(8000)

CODE_DEPOSIT_PER_BYTE

89
    CODE_DEPOSIT_PER_BYTE: Final[Uint] = Uint(200)

CODE_INIT_PER_WORD

90
    CODE_INIT_PER_WORD: Final[Uint] = Uint(2)

CREATE_ACCESS

91
    CREATE_ACCESS: Final[Uint] = ACCOUNT_WRITE + COLD_STORAGE_ACCESS

ZERO

94
    ZERO: Final[Uint] = Uint(0)

MEMORY_PER_WORD

95
    MEMORY_PER_WORD: Final[Uint] = Uint(3)

FAST_STEP

96
    FAST_STEP: Final[Uint] = Uint(5)

REFUND_STORAGE_CLEAR

99
    REFUND_STORAGE_CLEAR: Final[int] = int(
100
        (STORAGE_WRITE + COLD_STORAGE_ACCESS) * Uint(4800) // Uint(5000)
101
    )

PRECOMPILE_ECRECOVER

104
    PRECOMPILE_ECRECOVER: Final[Uint] = Uint(3000)

PRECOMPILE_P256VERIFY

105
    PRECOMPILE_P256VERIFY: Final[Uint] = Uint(6900)

PRECOMPILE_SHA256_BASE

106
    PRECOMPILE_SHA256_BASE: Final[Uint] = Uint(60)

PRECOMPILE_SHA256_PER_WORD

107
    PRECOMPILE_SHA256_PER_WORD: Final[Uint] = Uint(12)

PRECOMPILE_RIPEMD160_BASE

108
    PRECOMPILE_RIPEMD160_BASE: Final[Uint] = Uint(600)

PRECOMPILE_RIPEMD160_PER_WORD

109
    PRECOMPILE_RIPEMD160_PER_WORD: Final[Uint] = Uint(120)

PRECOMPILE_IDENTITY_BASE

110
    PRECOMPILE_IDENTITY_BASE: Final[Uint] = Uint(15)

PRECOMPILE_IDENTITY_PER_WORD

111
    PRECOMPILE_IDENTITY_PER_WORD: Final[Uint] = Uint(3)

PRECOMPILE_BLAKE2F_PER_ROUND

112
    PRECOMPILE_BLAKE2F_PER_ROUND: Final[Uint] = Uint(1)

PRECOMPILE_POINT_EVALUATION

113
    PRECOMPILE_POINT_EVALUATION: Final[Uint] = Uint(50000)

PRECOMPILE_BLS_G1ADD

114
    PRECOMPILE_BLS_G1ADD: Final[Uint] = Uint(375)

PRECOMPILE_BLS_G1MUL

115
    PRECOMPILE_BLS_G1MUL: Final[Uint] = Uint(12000)

PRECOMPILE_BLS_G1MAP

116
    PRECOMPILE_BLS_G1MAP: Final[Uint] = Uint(5500)

PRECOMPILE_BLS_G2ADD

117
    PRECOMPILE_BLS_G2ADD: Final[Uint] = Uint(600)

PRECOMPILE_BLS_G2MUL

118
    PRECOMPILE_BLS_G2MUL: Final[Uint] = Uint(22500)

PRECOMPILE_BLS_G2MAP

119
    PRECOMPILE_BLS_G2MAP: Final[Uint] = Uint(23800)

PRECOMPILE_ECADD

120
    PRECOMPILE_ECADD: Final[Uint] = Uint(150)

PRECOMPILE_ECMUL

121
    PRECOMPILE_ECMUL: Final[Uint] = Uint(6000)

PRECOMPILE_ECPAIRING_BASE

122
    PRECOMPILE_ECPAIRING_BASE: Final[Uint] = Uint(45000)

PRECOMPILE_ECPAIRING_PER_POINT

123
    PRECOMPILE_ECPAIRING_PER_POINT: Final[Uint] = Uint(34000)

PER_BLOB

126
    PER_BLOB: Final[U64] = U64(2**17)

BLOB_SCHEDULE_TARGET

127
    BLOB_SCHEDULE_TARGET: Final[U64] = U64(14)

BLOB_TARGET_GAS_PER_BLOCK

128
    BLOB_TARGET_GAS_PER_BLOCK: Final[U64] = PER_BLOB * BLOB_SCHEDULE_TARGET

BLOB_BASE_COST

129
    BLOB_BASE_COST: Final[Uint] = Uint(2**13)

BLOB_SCHEDULE_MAX

130
    BLOB_SCHEDULE_MAX: Final[U64] = U64(21)

BLOB_MIN_GASPRICE

131
    BLOB_MIN_GASPRICE: Final[Uint] = Uint(1)

BLOB_BASE_FEE_UPDATE_FRACTION

132
    BLOB_BASE_FEE_UPDATE_FRACTION: Final[Uint] = Uint(11684671)

BLOCK_ACCESS_LIST_ITEM

135
    BLOCK_ACCESS_LIST_ITEM: Final[Uint] = Uint(2000)

TX_BASE

138
    TX_BASE: Final[Uint] = Uint(12000)

TX_CREATE

139
    TX_CREATE: Final[Uint] = Uint(32000)

TX_VALUE_COST

140
    TX_VALUE_COST: Final[Uint] = Uint(4244)

TRANSFER_LOG_COST

141
    TRANSFER_LOG_COST: Final[Uint] = Uint(1756)

TX_DATA_TOKEN_STANDARD

142
    TX_DATA_TOKEN_STANDARD: Final[Uint] = Uint(4)

TX_DATA_TOKEN_FLOOR

143
    TX_DATA_TOKEN_FLOOR: Final[Uint] = Uint(16)

TX_ACCESS_LIST_ADDRESS

144
    TX_ACCESS_LIST_ADDRESS: Final[Uint] = COLD_ACCOUNT_ACCESS

TX_ACCESS_LIST_STORAGE_KEY

145
    TX_ACCESS_LIST_STORAGE_KEY: Final[Uint] = COLD_STORAGE_ACCESS

AUTH_TUPLE_BYTES

148
    AUTH_TUPLE_BYTES: Final[Uint] = Uint(101)

REGULAR_PER_AUTH_BASE_COST

149
    REGULAR_PER_AUTH_BASE_COST: Final[Uint] = (
150
        AUTH_TUPLE_BYTES * TX_DATA_TOKEN_FLOOR
151
        + PRECOMPILE_ECRECOVER
152
        + COLD_ACCOUNT_ACCESS
153
        + Uint(2) * WARM_ACCESS
154
    )

LIMIT_ADJUSTMENT_FACTOR

157
    LIMIT_ADJUSTMENT_FACTOR: Final[Uint] = Uint(1024)

LIMIT_MINIMUM

158
    LIMIT_MINIMUM: Final[Uint] = Uint(5000)

OPCODE_ADD

161
    OPCODE_ADD: Final[Uint] = VERY_LOW

OPCODE_SUB

162
    OPCODE_SUB: Final[Uint] = VERY_LOW

OPCODE_MUL

163
    OPCODE_MUL: Final[Uint] = LOW

OPCODE_DIV

164
    OPCODE_DIV: Final[Uint] = LOW

OPCODE_SDIV

165
    OPCODE_SDIV: Final[Uint] = LOW

OPCODE_MOD

166
    OPCODE_MOD: Final[Uint] = LOW

OPCODE_SMOD

167
    OPCODE_SMOD: Final[Uint] = LOW

OPCODE_ADDMOD

168
    OPCODE_ADDMOD: Final[Uint] = MID

OPCODE_MULMOD

169
    OPCODE_MULMOD: Final[Uint] = MID

OPCODE_SIGNEXTEND

170
    OPCODE_SIGNEXTEND: Final[Uint] = LOW

OPCODE_LT

171
    OPCODE_LT: Final[Uint] = VERY_LOW

OPCODE_GT

172
    OPCODE_GT: Final[Uint] = VERY_LOW

OPCODE_SLT

173
    OPCODE_SLT: Final[Uint] = VERY_LOW

OPCODE_SGT

174
    OPCODE_SGT: Final[Uint] = VERY_LOW

OPCODE_EQ

175
    OPCODE_EQ: Final[Uint] = VERY_LOW

OPCODE_ISZERO

176
    OPCODE_ISZERO: Final[Uint] = VERY_LOW

OPCODE_AND

177
    OPCODE_AND: Final[Uint] = VERY_LOW

OPCODE_OR

178
    OPCODE_OR: Final[Uint] = VERY_LOW

OPCODE_XOR

179
    OPCODE_XOR: Final[Uint] = VERY_LOW

OPCODE_NOT

180
    OPCODE_NOT: Final[Uint] = VERY_LOW

OPCODE_BYTE

181
    OPCODE_BYTE: Final[Uint] = VERY_LOW

OPCODE_SHL

182
    OPCODE_SHL: Final[Uint] = VERY_LOW

OPCODE_SHR

183
    OPCODE_SHR: Final[Uint] = VERY_LOW

OPCODE_SAR

184
    OPCODE_SAR: Final[Uint] = VERY_LOW

OPCODE_CLZ

185
    OPCODE_CLZ: Final[Uint] = LOW

OPCODE_JUMP

186
    OPCODE_JUMP: Final[Uint] = MID

OPCODE_JUMPI

187
    OPCODE_JUMPI: Final[Uint] = HIGH

OPCODE_JUMPDEST

188
    OPCODE_JUMPDEST: Final[Uint] = Uint(1)

OPCODE_CALLDATALOAD

189
    OPCODE_CALLDATALOAD: Final[Uint] = VERY_LOW

OPCODE_BLOCKHASH

190
    OPCODE_BLOCKHASH: Final[Uint] = Uint(20)

OPCODE_COINBASE

191
    OPCODE_COINBASE: Final[Uint] = BASE

OPCODE_POP

192
    OPCODE_POP: Final[Uint] = BASE

OPCODE_MSIZE

193
    OPCODE_MSIZE: Final[Uint] = BASE

OPCODE_PC

194
    OPCODE_PC: Final[Uint] = BASE

OPCODE_GAS

195
    OPCODE_GAS: Final[Uint] = BASE

OPCODE_ADDRESS

196
    OPCODE_ADDRESS: Final[Uint] = BASE

OPCODE_ORIGIN

197
    OPCODE_ORIGIN: Final[Uint] = BASE

OPCODE_CALLER

198
    OPCODE_CALLER: Final[Uint] = BASE

OPCODE_CALLVALUE

199
    OPCODE_CALLVALUE: Final[Uint] = BASE

OPCODE_CALLDATASIZE

200
    OPCODE_CALLDATASIZE: Final[Uint] = BASE

OPCODE_CODESIZE

201
    OPCODE_CODESIZE: Final[Uint] = BASE

OPCODE_GASPRICE

202
    OPCODE_GASPRICE: Final[Uint] = BASE

OPCODE_TIMESTAMP

203
    OPCODE_TIMESTAMP: Final[Uint] = BASE

OPCODE_NUMBER

204
    OPCODE_NUMBER: Final[Uint] = BASE

OPCODE_GASLIMIT

205
    OPCODE_GASLIMIT: Final[Uint] = BASE

OPCODE_PREVRANDAO

206
    OPCODE_PREVRANDAO: Final[Uint] = BASE

OPCODE_RETURNDATASIZE

207
    OPCODE_RETURNDATASIZE: Final[Uint] = BASE

OPCODE_CHAINID

208
    OPCODE_CHAINID: Final[Uint] = BASE

OPCODE_BASEFEE

209
    OPCODE_BASEFEE: Final[Uint] = BASE

OPCODE_BLOBBASEFEE

210
    OPCODE_BLOBBASEFEE: Final[Uint] = BASE

OPCODE_SLOTNUM

211
    OPCODE_SLOTNUM: Final[Uint] = BASE

OPCODE_BLOBHASH

212
    OPCODE_BLOBHASH: Final[Uint] = Uint(3)

OPCODE_PUSH

213
    OPCODE_PUSH: Final[Uint] = VERY_LOW

OPCODE_PUSH0

214
    OPCODE_PUSH0: Final[Uint] = BASE

OPCODE_DUP

215
    OPCODE_DUP: Final[Uint] = VERY_LOW

OPCODE_SWAP

216
    OPCODE_SWAP: Final[Uint] = VERY_LOW

OPCODE_DUPN

217
    OPCODE_DUPN: Final[Uint] = VERY_LOW

OPCODE_SWAPN

218
    OPCODE_SWAPN: Final[Uint] = VERY_LOW

OPCODE_EXCHANGE

219
    OPCODE_EXCHANGE: Final[Uint] = VERY_LOW

OPCODE_TLOAD

220
    OPCODE_TLOAD: Final[Uint] = Uint(100)

OPCODE_TSTORE

221
    OPCODE_TSTORE: Final[Uint] = Uint(100)

OPCODE_RETURNDATACOPY_BASE

224
    OPCODE_RETURNDATACOPY_BASE: Final[Uint] = VERY_LOW

OPCODE_RETURNDATACOPY_PER_WORD

225
    OPCODE_RETURNDATACOPY_PER_WORD: Final[Uint] = Uint(3)

OPCODE_CALLDATACOPY_BASE

226
    OPCODE_CALLDATACOPY_BASE: Final[Uint] = VERY_LOW

OPCODE_CODECOPY_BASE

227
    OPCODE_CODECOPY_BASE: Final[Uint] = VERY_LOW

OPCODE_MCOPY_BASE

228
    OPCODE_MCOPY_BASE: Final[Uint] = VERY_LOW

OPCODE_MLOAD_BASE

229
    OPCODE_MLOAD_BASE: Final[Uint] = VERY_LOW

OPCODE_MSTORE_BASE

230
    OPCODE_MSTORE_BASE: Final[Uint] = VERY_LOW

OPCODE_MSTORE8_BASE

231
    OPCODE_MSTORE8_BASE: Final[Uint] = VERY_LOW

OPCODE_COPY_PER_WORD

232
    OPCODE_COPY_PER_WORD: Final[Uint] = Uint(3)

OPCODE_EXP_BASE

233
    OPCODE_EXP_BASE: Final[Uint] = Uint(10)

OPCODE_EXP_PER_BYTE

234
    OPCODE_EXP_PER_BYTE: Final[Uint] = Uint(50)

OPCODE_KECCAK256_BASE

235
    OPCODE_KECCAK256_BASE: Final[Uint] = Uint(30)

OPCODE_KECCAK256_PER_WORD

236
    OPCODE_KECCAK256_PER_WORD: Final[Uint] = Uint(6)

OPCODE_LOG_BASE

237
    OPCODE_LOG_BASE: Final[Uint] = Uint(375)

OPCODE_LOG_DATA_PER_BYTE

238
    OPCODE_LOG_DATA_PER_BYTE: Final[Uint] = Uint(8)

OPCODE_LOG_TOPIC

239
    OPCODE_LOG_TOPIC: Final[Uint] = Uint(375)

OPCODE_SELFDESTRUCT_BASE

240
    OPCODE_SELFDESTRUCT_BASE: Final[Uint] = Uint(5000)

GasMeter

Track a frame's gas consumption across both gas dimensions.

Bundle every mutable gas quantity a frame maintains, so the frame and its settlement work against one object instead of a scatter of fields on the Evm.

243
@final
244
@dataclass
class GasMeter:

gas_left

Gas still available from the frame's regular grant. Pays regular charges, and state charges as spill once the reservoir empties.

256
    gas_left: Uint

state_gas_left

State gas still available in the frame's reservoir. Charges draw from here first and spill into gas_left once it is empty.

264
    state_gas_left: Uint

state_gas_baseline

Reservoir level a rollback refills to: the frame's grant at entry, moved down by commit_state_gas when charges become non-refillable.

270
    state_gas_baseline: Uint

refund_counter

Gas eligible for refund at the end of the transaction.

279
    refund_counter: int = 0

state_gas_spilled

Regular gas spent covering state charges after the reservoir emptied. Credited back to gas_left first, in LIFO order, on a refund or failure. EIP-8037 names this quantity state_gas_from_gas_left.

282
    state_gas_spilled: Uint = Uint(0)

state_gas_committed_spill

Spill that commit_state_gas marked non-refillable. It outlives the rollbacks restore_state_gas performs; only restore_state_gas_to_entry credits it back to gas_left. Committed reservoir draw needs no counter of its own: each commit lowers the baseline, so it is the frame's grant minus state_gas_baseline.

292
    state_gas_committed_spill: Uint = Uint(0)

ExtendMemory

Define the parameters for memory extension in opcodes.

cost: ethereum.base_types.Uint The gas required to perform the extension expand_by: ethereum.base_types.Uint The size by which the memory will be extended

308
@final
309
@dataclass
class ExtendMemory:

cost

320
    cost: Uint

expand_by

321
    expand_by: Uint

MessageCallGas

Define the gas cost and gas given to the sub-call for executing the call opcodes.

cost: ethereum.base_types.Uint The gas required to execute the call opcode, excludes memory expansion costs. sub_call: ethereum.base_types.Uint The portion of gas available to sub-calls that is refundable if not consumed.

324
@final
325
@dataclass
class MessageCallGas:

cost

339
    cost: Uint

sub_call

340
    sub_call: Uint

check_gas

Checks if amount gas is available without charging it. Raises OutOfGasError if insufficient gas.

Parameters

evm : The current EVM. amount : The amount of gas to check.

def check_gas(evm: "Evm", ​​amount: Uint) -> None:
344
    <snip>
356
    if evm.gas_meter.gas_left < amount:
357
        raise OutOfGasError

charge_gas

Subtracts amount from gas_left (regular gas).

Parameters

evm : The current EVM. amount : The amount of regular gas the current operation requires.

def charge_gas(evm: "Evm", ​​amount: Uint) -> None:
361
    <snip>
372
    evm_trace(evm, GasAndRefund(int(amount)))
373
374
    gas_meter = evm.gas_meter
375
    if gas_meter.gas_left < amount:
376
        raise OutOfGasError
377
    gas_meter.gas_left -= amount

charge_state_gas

Subtracts amount from the state gas reservoir, then from gas_left when the reservoir is empty, tracking any spill.

Parameters

evm : The current EVM. amount : The amount of state gas the current operation requires.

def charge_state_gas(evm: "Evm", ​​amount: StateGas) -> None:
381
    <snip>
395
    evm_trace(evm, StateGasAndRefund(int(amount)))
396
397
    gas_meter = evm.gas_meter
398
    if gas_meter.state_gas_left >= amount:
399
        gas_meter.state_gas_left -= amount
400
    elif gas_meter.state_gas_left + gas_meter.gas_left >= amount:
401
        remainder = amount - gas_meter.state_gas_left
402
        gas_meter.state_gas_left = Uint(0)
403
        gas_meter.gas_left -= remainder
404
        gas_meter.state_gas_spilled += remainder
405
    else:
406
        raise OutOfGasError

commit_state_gas

Mark the state gas spent so far as non-refillable.

A later rollback via restore_state_gas leaves the state bought so far in place, so it must not credit this gas back. In the top frame that protects the delegations applied by set_delegation, which survive a failure of the dispatched code. A failure that reverts the committed state as well -- one raised before dispatch -- must instead undo the commit with restore_state_gas_to_entry.

Move the baseline down to the current reservoir level and fold the spill into state_gas_committed_spill, so later refunds route to the reservoir instead of back into gas_left.

Parameters

gas_meter : The frame's gas meter.

def commit_state_gas(gas_meter: GasMeter) -> None:
410
    <snip>
435
    # Only charges precede a commit, so no refund has pushed the
436
    # reservoir above the baseline: a commit only ever lowers it.
437
    assert gas_meter.state_gas_left <= gas_meter.state_gas_baseline
438
    gas_meter.state_gas_committed_spill += gas_meter.state_gas_spilled
439
    gas_meter.state_gas_baseline = gas_meter.state_gas_left
440
    gas_meter.state_gas_spilled = Uint(0)

restore_state_gas

Roll the frame's state gas back to the baseline on revert or halt.

The frame's state changes are undone, so the state gas consumed since the baseline is credited back in LIFO order: the spill returns to gas_left first, then the reservoir resets to the baseline. The refunds accrued on the undone changes are discarded with them. State gas committed as non-refillable stays charged.

Parameters

gas_meter : The frame's gas meter.

def restore_state_gas(gas_meter: GasMeter) -> None:
444
    <snip>  # noqa: E501
462
    gas_meter.gas_left += gas_meter.state_gas_spilled
463
    gas_meter.state_gas_spilled = Uint(0)
464
    gas_meter.state_gas_left = gas_meter.state_gas_baseline
465
    gas_meter.refund_counter = 0

restore_state_gas_to_entry

Roll the frame's state gas back to frame entry, undoing any commit.

Used when the transaction-state rollback also reverts the applied delegations a commit_state_gas protected: every state charge refills -- all spill, committed or not, returns to gas_left -- and the baseline resets to the frame's grant.

Parameters

gas_meter : The frame's gas meter. state_gas_reservoir : The frame's immutable state gas grant.

def restore_state_gas_to_entry(gas_meter: GasMeter, ​​state_gas_reservoir: Uint) -> None:
471
    <snip>
490
    # The baseline starts at the grant and only ever moves down.
491
    assert gas_meter.state_gas_baseline <= state_gas_reservoir
492
    # Only pre-dispatch failures roll back to entry, and no refund
493
    # accrues before dispatch.
494
    assert gas_meter.refund_counter == 0
495
    gas_meter.gas_left += (
496
        gas_meter.state_gas_spilled + gas_meter.state_gas_committed_spill
497
    )
498
    gas_meter.state_gas_spilled = Uint(0)
499
    gas_meter.state_gas_committed_spill = Uint(0)
500
    gas_meter.state_gas_left = state_gas_reservoir
501
    gas_meter.state_gas_baseline = state_gas_reservoir

tx_state_gas_used

Return the net state gas a transaction's execution consumed.

Measured off the top frame's finished gas meter: the reservoir drawn down since the transaction's grant plus the spill, outstanding or committed. May be negative when refunds exceed charges.

Parameters

gas_meter : The top frame's finished gas meter. state_gas_reservoir : The transaction's immutable state gas grant.

Returns

state_gas_used : int The net state gas consumed.

def tx_state_gas_used(gas_meter: GasMeter, ​​state_gas_reservoir: Uint) -> int:
505
    <snip>
528
    # The baseline starts at the grant and only ever moves down.
529
    assert gas_meter.state_gas_baseline <= state_gas_reservoir
530
    return (
531
        int(state_gas_reservoir)
532
        - int(gas_meter.state_gas_left)
533
        + int(gas_meter.state_gas_spilled)
534
        + int(gas_meter.state_gas_committed_spill)
535
    )

credit_state_gas_refund

Credit a state gas refund to the local frame, in LIFO order.

State-gas charges draw from the reservoir first and from gas_left last, so refunds credit the pool charged last first: gas_left up to the spill, then the reservoir. This restores the exact pools the charge drew from, so the two never drift.

Parameters

gas_meter : The gas meter crediting the refund. amount : The refund amount to credit.

def credit_state_gas_refund(gas_meter: GasMeter, ​​amount: StateGas) -> None:
539
    <snip>
557
    from_gas_left = min(amount, gas_meter.state_gas_spilled)
558
    gas_meter.gas_left += from_gas_left
559
    gas_meter.state_gas_spilled -= from_gas_left
560
    gas_meter.state_gas_left += amount - from_gas_left

forfeit_remaining_gas

Consume all remaining regular gas on an exceptional halt.

Parameters

gas_meter : The halted frame's gas meter.

def forfeit_remaining_gas(gas_meter: GasMeter) -> None:
564
    <snip>
573
    # A rollback owes any outstanding spill back to `gas_left`; it
574
    # must be restored before the remainder burns.
575
    assert gas_meter.state_gas_spilled == Uint(0)
576
    gas_meter.gas_left = Uint(0)

withhold_create_gas

Withhold and return the gas made available to a CREATE* child.

Deduct the all-but-one-64th share from the frame's gas_left and return it as the child frame's regular gas grant.

Parameters

gas_meter : The creating frame's gas meter.

Returns

child_gas : ethereum.base_types.Uint The regular gas granted to the child frame.

def withhold_create_gas(gas_meter: GasMeter) -> Uint:
580
    <snip>
597
    child_gas = max_message_call_gas(gas_meter.gas_left)
598
    gas_meter.gas_left -= child_gas
599
    return child_gas

drain_state_gas_reservoir

Empty the frame's state gas reservoir for a child frame.

A child frame receives the parent's entire reservoir; there is no all-but-one-64th rule for state gas. The parent's reservoir is restored when the child returns.

Parameters

gas_meter : The parent frame's gas meter.

Returns

reservoir : ethereum.base_types.Uint The state gas granted to the child frame.

def drain_state_gas_reservoir(gas_meter: GasMeter) -> Uint:
603
    <snip>
621
    reservoir = gas_meter.state_gas_left
622
    gas_meter.state_gas_left = Uint(0)
623
    return reservoir

restore_child_gas

Return a child frame's unused gas grant to the parent.

Used when the child frame is never entered (for example, a stack depth or balance check fails): the withheld regular gas and drained reservoir are returned untouched.

Parameters

gas_meter : The parent frame's gas meter. gas : The regular gas grant to return. state_gas_reservoir : The state gas reservoir to return.

def restore_child_gas(gas_meter: GasMeter, ​​gas: Uint, ​​state_gas_reservoir: Uint) -> None:
629
    <snip>
646
    gas_meter.gas_left += gas
647
    gas_meter.state_gas_left += state_gas_reservoir

calculate_memory_gas_cost

Calculates the gas cost for allocating memory to the smallest multiple of 32 bytes, such that the allocated size is at least as big as the given size.

Parameters

size_in_bytes : The size of the data in bytes.

Returns

total_gas_cost : ethereum.base_types.Uint The gas cost for storing data in memory.

def calculate_memory_gas_cost(size_in_bytes: Uint) -> Uint:
651
    <snip>
667
    size_in_words = ceil32(size_in_bytes) // Uint(32)
668
    linear_cost = size_in_words * GasCosts.MEMORY_PER_WORD
669
    quadratic_cost = size_in_words ** Uint(2) // Uint(512)
670
    total_gas_cost = linear_cost + quadratic_cost
671
    try:
672
        return total_gas_cost
673
    except ValueError as e:
674
        raise OutOfGasError from e

calculate_gas_extend_memory

Calculates the gas amount to extend memory.

Parameters

memory : Memory contents of the EVM. extensions: List of extensions to be made to the memory. Consists of a tuple of start position and size.

Returns

extend_memory: ExtendMemory

def calculate_gas_extend_memory(memory: bytearray, ​​extensions: List[Tuple[U256, U256]]) -> ExtendMemory:
680
    <snip>
696
    size_to_extend = Uint(0)
697
    to_be_paid = Uint(0)
698
    current_size = ulen(memory)
699
    for start_position, size in extensions:
700
        if size == 0:
701
            continue
702
        before_size = ceil32(current_size)
703
        after_size = ceil32(Uint(start_position) + Uint(size))
704
        if after_size <= before_size:
705
            continue
706
707
        size_to_extend += after_size - before_size
708
        already_paid = calculate_memory_gas_cost(before_size)
709
        total_cost = calculate_memory_gas_cost(after_size)
710
        to_be_paid += total_cost - already_paid
711
712
        current_size = after_size
713
714
    return ExtendMemory(to_be_paid, size_to_extend)

calculate_message_call_gas

Calculates the MessageCallGas (cost and gas made available to the sub-call) for executing call Opcodes.

Parameters

value: The amount of ETH that needs to be transferred. gas : The amount of gas provided to the message-call. gas_left : The amount of gas left in the current frame. memory_cost : The amount needed to extend the memory in the current frame. extra_gas : The amount of gas needed for transferring value + creating a new account inside a message call. call_stipend : The amount of stipend provided to a message call to execute code while transferring value (ETH).

Returns

message_call_gas: MessageCallGas

def calculate_message_call_gas(value: U256, ​​gas: Uint, ​​gas_left: Uint, ​​memory_cost: Uint, ​​extra_gas: Uint, ​​call_stipend: Uint) -> MessageCallGas:
725
    <snip>
751
    call_stipend = Uint(0) if value == 0 else call_stipend
752
    if gas_left < extra_gas + memory_cost:
753
        return MessageCallGas(gas + extra_gas, gas + call_stipend)
754
755
    gas = min(gas, max_message_call_gas(gas_left - memory_cost - extra_gas))
756
757
    return MessageCallGas(gas + extra_gas, gas + call_stipend)

max_message_call_gas

Calculates the maximum gas that is allowed for making a message call.

Parameters

gas : The amount of gas provided to the message-call.

Returns

max_allowed_message_call_gas: ethereum.base_types.Uint The maximum gas allowed for making the message-call.

def max_message_call_gas(gas: Uint) -> Uint:
761
    <snip>
775
    return gas - (gas // Uint(64))

init_code_cost

Calculates the gas to be charged for the init code in CREATE* opcodes as well as create transactions.

Parameters

init_code_length : The length of the init code provided to the opcode or a create transaction

Returns

init_code_gas: ethereum.base_types.Uint The gas to be charged for the init code.

def init_code_cost(init_code_length: Uint) -> Uint:
779
    <snip>
795
    return GasCosts.CODE_INIT_PER_WORD * ceil32(init_code_length) // Uint(32)

calculate_excess_blob_gas

Calculates the excess blob gas for the current block based on the gas used in the parent block.

Parameters

parent_header : The parent block of the current block.

Returns

excess_blob_gas: ethereum.base_types.U64 The excess blob gas for the current block.

def calculate_excess_blob_gas(parent_header: Header | PreviousHeader) -> U64:
801
    <snip>
816
    # At the fork block, these are defined as zero.
817
    excess_blob_gas = U64(0)
818
    blob_gas_used = U64(0)
819
    base_fee_per_gas = Uint(0)
820
821
    if isinstance(parent_header, Header):
822
        # After the fork block, read them from the parent header.
823
        excess_blob_gas = parent_header.excess_blob_gas
824
        blob_gas_used = parent_header.blob_gas_used
825
        base_fee_per_gas = parent_header.base_fee_per_gas
826
827
    parent_blob_gas = excess_blob_gas + blob_gas_used
828
    if parent_blob_gas < GasCosts.BLOB_TARGET_GAS_PER_BLOCK:
829
        return U64(0)
830
831
    target_blob_gas_price = Uint(GasCosts.PER_BLOB)
832
    target_blob_gas_price *= calculate_blob_gas_price(excess_blob_gas)
833
834
    base_blob_tx_price = GasCosts.BLOB_BASE_COST * base_fee_per_gas
835
    if base_blob_tx_price > target_blob_gas_price:
836
        blob_schedule_delta = (
837
            GasCosts.BLOB_SCHEDULE_MAX - GasCosts.BLOB_SCHEDULE_TARGET
838
        )
839
        return (
840
            excess_blob_gas
841
            + blob_gas_used * blob_schedule_delta // GasCosts.BLOB_SCHEDULE_MAX
842
        )
843
844
    return parent_blob_gas - GasCosts.BLOB_TARGET_GAS_PER_BLOCK

calculate_total_blob_gas

Calculate the total blob gas for a transaction.

Parameters

tx : The transaction for which the blob gas is to be calculated.

Returns

total_blob_gas: ethereum.base_types.Uint The total blob gas for the transaction.

def calculate_total_blob_gas(tx: Transaction) -> U64:
848
    <snip>
862
    if isinstance(tx, BlobTransaction):
863
        return GasCosts.PER_BLOB * U64(len(tx.blob_versioned_hashes))
864
    else:
865
        return U64(0)

calculate_blob_gas_price

Calculate the blob gasprice for a block.

Parameters

excess_blob_gas : The excess blob gas for the block.

Returns

blob_gasprice: Uint The blob gasprice.

def calculate_blob_gas_price(excess_blob_gas: U64) -> Uint:
869
    <snip>
883
    return taylor_exponential(
884
        GasCosts.BLOB_MIN_GASPRICE,
885
        Uint(excess_blob_gas),
886
        GasCosts.BLOB_BASE_FEE_UPDATE_FRACTION,
887
    )

calculate_data_fee

Calculate the blob data fee for a transaction.

Parameters

excess_blob_gas : The excess_blob_gas for the execution. tx : The transaction for which the blob data fee is to be calculated.

Returns

data_fee: Uint The blob data fee.

def calculate_data_fee(excess_blob_gas: U64, ​​tx: Transaction) -> Uint:
891
    <snip>
907
    return Uint(calculate_total_blob_gas(tx)) * calculate_blob_gas_price(
908
        excess_blob_gas
909
    )

ExecutionGasAllocation

Split of a transaction's execution gas across the two dimensions.

912
@final
913
@dataclass
class ExecutionGasAllocation:

regular_gas

Regular gas granted to the top frame, capped by the budget.

919
    regular_gas: Uint

state_gas_reservoir

State gas set aside for the top frame's reservoir.

922
    state_gas_reservoir: Uint

allocate_execution_gas

Split execution gas into a regular grant and a state reservoir.

After the intrinsic cost is removed, the remaining execution gas is divided into regular gas -- capped by the regular-gas budget that remains below TX_MAX_GAS_LIMIT -- and a state gas reservoir that holds whatever exceeds that cap.

Only valid once validate_transaction has confirmed the transaction can afford its intrinsic cost, which guarantees the subtractions below do not underflow.

Parameters

tx_gas : The transaction's gas limit. intrinsic : The transaction's intrinsic gas cost.

Returns

allocation : ExecutionGasAllocation The regular gas grant and state gas reservoir.

def allocate_execution_gas(tx_gas: Uint, ​​intrinsic: IntrinsicGasCost) -> ExecutionGasAllocation:
929
    <snip>
954
    execution_gas = tx_gas - Uint(intrinsic.regular)
955
    regular_gas_budget = TX_MAX_GAS_LIMIT - intrinsic.regular
956
    regular_gas = min(regular_gas_budget, execution_gas)
957
    state_gas_reservoir = Uint(execution_gas - regular_gas)
958
    return ExecutionGasAllocation(regular_gas, state_gas_reservoir)

TransactionGasSettlement

Settled gas amounts for a finished transaction.

Hold only gas figures; the caller turns them into fee payments and block-accounting updates.

961
@final
962
@dataclass
class TransactionGasSettlement:

gas_used

Total gas charged to the sender, after refund and floor.

971
    gas_used: Uint

gas_left

Gas returned to the sender, priced at the effective gas price.

974
    gas_left: Uint

regular_gas_used

Regular gas the transaction contributes to the block total.

977
    regular_gas_used: Uint

state_gas_used

State gas the transaction contributes to the block total.

980
    state_gas_used: Uint

settle_transaction_gas

Settle a transaction's gas after execution.

Compute, in order:

  • the gas used before refunds, from the gas limit less the regular gas and reservoir the top frame returned;

  • the refund, capped at one fifth of that pre-refund usage;

  • the gas used, taken as the larger of the post-refund usage and the calldata floor, so a transaction never pays below the floor; and

  • the per-dimension block amounts: the state gas used (clamped to zero, since refunds can drive it negative) and the regular gas used, which carries the floor because the floor binds the regular dimension. Unlike the sender-facing gas_used, it ignores refunds: block accounting counts pre-refund gas (EIP-7778).

Parameters

tx_gas : The transaction's gas limit. intrinsic : The transaction's intrinsic gas cost. gas_left : Regular gas the top frame returned. state_gas_left : State gas reservoir the top frame returned. refund_counter : The refund the top frame accrued. state_gas_used : Net state gas the top frame consumed, possibly negative.

Returns

settlement : TransactionGasSettlement The settled gas amounts.

def settle_transaction_gas(tx_gas: Uint, ​​intrinsic: IntrinsicGasCost, ​​gas_left: Uint, ​​state_gas_left: Uint, ​​refund_counter: U256, ​​state_gas_used: int) -> TransactionGasSettlement:
992
    <snip>
1031
    gas_used_before_refund = tx_gas - gas_left - state_gas_left
1032
    gas_refund = min(gas_used_before_refund // Uint(5), Uint(refund_counter))
1033
    gas_used_after_refund = gas_used_before_refund - gas_refund
1034
    gas_used = max(gas_used_after_refund, intrinsic.calldata_floor)
1035
1036
    settled_state_gas_used = Uint(max(0, state_gas_used))
1037
    regular_gas_used = max(
1038
        gas_used_before_refund - settled_state_gas_used,
1039
        intrinsic.calldata_floor,
1040
    )
1041
    return TransactionGasSettlement(
1042
        gas_used=gas_used,
1043
        gas_left=tx_gas - gas_used,
1044
        regular_gas_used=regular_gas_used,
1045
        state_gas_used=settled_state_gas_used,
1046
    )