ethereum.forks.dao_fork.vm.gasethereum.forks.tangerine_whistle.vm.gas
Ethereum Virtual Machine (EVM) Gas.
.. contents:: Table of Contents :backlinks: none :local:
Introduction
EVM gas constants and calculators.
GAS_JUMPDEST¶
| 25 | GAS_JUMPDEST = Uint(1) |
|---|
GAS_BASE¶
| 26 | GAS_BASE = Uint(2) |
|---|
GAS_VERY_LOW¶
| 27 | GAS_VERY_LOW = Uint(3) |
|---|
GAS_SLOAD¶
| 30 | GAS_SLOAD = Uint(50) |
|---|---|
| 28 | GAS_SLOAD = Uint(200) |
GAS_STORAGE_SET¶
| 29 | GAS_STORAGE_SET = Uint(20000) |
|---|
GAS_STORAGE_UPDATE¶
| 30 | GAS_STORAGE_UPDATE = Uint(5000) |
|---|
REFUND_STORAGE_CLEAR¶
| 31 | REFUND_STORAGE_CLEAR = 15000 |
|---|
GAS_LOW¶
| 32 | GAS_LOW = Uint(5) |
|---|
GAS_MID¶
| 33 | GAS_MID = Uint(8) |
|---|
GAS_HIGH¶
| 34 | GAS_HIGH = Uint(10) |
|---|
GAS_EXPONENTIATION¶
| 35 | GAS_EXPONENTIATION = Uint(10) |
|---|
GAS_EXPONENTIATION_PER_BYTE¶
| 36 | GAS_EXPONENTIATION_PER_BYTE = Uint(10) |
|---|
GAS_MEMORY¶
| 37 | GAS_MEMORY = Uint(3) |
|---|
GAS_KECCAK256¶
| 38 | GAS_KECCAK256 = Uint(30) |
|---|
GAS_KECCAK256_PER_WORD¶
| 39 | GAS_KECCAK256_PER_WORD = Uint(6) |
|---|
GAS_COPY¶
| 40 | GAS_COPY = Uint(3) |
|---|
GAS_BLOCK_HASH¶
| 41 | GAS_BLOCK_HASH = Uint(20) |
|---|
GAS_EXTERNAL¶
| 44 | GAS_EXTERNAL = Uint(20) |
|---|---|
| 42 | GAS_EXTERNAL = Uint(700) |
GAS_BALANCE¶
| 45 | GAS_BALANCE = Uint(20) |
|---|---|
| 43 | GAS_BALANCE = Uint(400) |
GAS_LOG¶
| 44 | GAS_LOG = Uint(375) |
|---|
GAS_LOG_DATA_PER_BYTE¶
| 45 | GAS_LOG_DATA_PER_BYTE = Uint(8) |
|---|
GAS_LOG_TOPIC¶
| 46 | GAS_LOG_TOPIC = Uint(375) |
|---|
GAS_CREATE¶
| 47 | GAS_CREATE = Uint(32000) |
|---|
GAS_CODE_DEPOSIT_PER_BYTE¶
| 48 | GAS_CODE_DEPOSIT_PER_BYTE = Uint(200) |
|---|
GAS_ZERO¶
| 49 | GAS_ZERO = Uint(0) |
|---|
GAS_CALL¶
| 52 | GAS_CALL = Uint(40) |
|---|---|
| 50 | GAS_CALL = Uint(700) |
GAS_NEW_ACCOUNT¶
| 51 | GAS_NEW_ACCOUNT = Uint(25000) |
|---|
GAS_CALL_VALUE¶
| 52 | GAS_CALL_VALUE = Uint(9000) |
|---|
GAS_CALL_STIPEND¶
| 53 | GAS_CALL_STIPEND = Uint(2300) |
|---|
GAS_SELF_DESTRUCT¶
| 54 | GAS_SELF_DESTRUCT = Uint(5000) |
|---|
GAS_SELF_DESTRUCT_NEW_ACCOUNT¶
| 55 | GAS_SELF_DESTRUCT_NEW_ACCOUNT = Uint(25000) |
|---|
REFUND_SELF_DESTRUCT¶
| 56 | REFUND_SELF_DESTRUCT = Uint(24000) |
|---|---|
| 56 | REFUND_SELF_DESTRUCT = 24000 |
GAS_ECRECOVER¶
| 57 | GAS_ECRECOVER = Uint(3000) |
|---|
GAS_SHA256¶
| 58 | GAS_SHA256 = Uint(60) |
|---|
GAS_SHA256_WORD¶
| 59 | GAS_SHA256_WORD = Uint(12) |
|---|
GAS_RIPEMD160¶
| 60 | GAS_RIPEMD160 = Uint(600) |
|---|
GAS_RIPEMD160_WORD¶
| 61 | GAS_RIPEMD160_WORD = Uint(120) |
|---|
GAS_IDENTITY¶
| 62 | GAS_IDENTITY = Uint(15) |
|---|
GAS_IDENTITY_WORD¶
| 63 | GAS_IDENTITY_WORD = Uint(3) |
|---|
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
| 66 | @dataclass |
|---|
class ExtendMemory:
cost¶
| 77 | cost: Uint |
|---|
expand_by¶
| 78 | 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.
| 81 | @dataclass |
|---|
class MessageCallGas:
cost¶
| 95 | cost: Uint |
|---|
sub_call¶
| 96 | sub_call: Uint |
|---|
charge_gas ¶
Subtracts amount from evm.gas_left.
Parameters
evm : The current EVM. amount : The amount of gas the current operation requires.
def charge_gas(evm: Evm, amount: Uint) -> None:
| 100 | """ |
|---|---|
| 101 | Subtracts `amount` from `evm.gas_left`. |
| 102 | |
| 103 | Parameters |
| 104 | ---------- |
| 105 | evm : |
| 106 | The current EVM. |
| 107 | amount : |
| 108 | The amount of gas the current operation requires. |
| 109 | |
| 110 | """ |
| 111 | evm_trace(evm, GasAndRefund(int(amount))) |
| 112 | |
| 113 | if evm.gas_left < amount: |
| 114 | raise OutOfGasError |
| 115 | else: |
| 116 | evm.gas_left -= amount |
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:
| 120 | """ |
|---|---|
| 121 | Calculates the gas cost for allocating memory |
| 122 | to the smallest multiple of 32 bytes, |
| 123 | such that the allocated size is at least as big as the given size. |
| 124 | |
| 125 | Parameters |
| 126 | ---------- |
| 127 | size_in_bytes : |
| 128 | The size of the data in bytes. |
| 129 | |
| 130 | Returns |
| 131 | ------- |
| 132 | total_gas_cost : `ethereum.base_types.Uint` |
| 133 | The gas cost for storing data in memory. |
| 134 | |
| 135 | """ |
| 136 | size_in_words = ceil32(size_in_bytes) // Uint(32) |
| 137 | linear_cost = size_in_words * GAS_MEMORY |
| 138 | quadratic_cost = size_in_words ** Uint(2) // Uint(512) |
| 139 | total_gas_cost = linear_cost + quadratic_cost |
| 140 | try: |
| 141 | return total_gas_cost |
| 142 | except ValueError as e: |
| 143 | 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:
| 149 | """ |
|---|---|
| 150 | Calculates the gas amount to extend memory. |
| 151 | |
| 152 | Parameters |
| 153 | ---------- |
| 154 | memory : |
| 155 | Memory contents of the EVM. |
| 156 | extensions: |
| 157 | List of extensions to be made to the memory. |
| 158 | Consists of a tuple of start position and size. |
| 159 | |
| 160 | Returns |
| 161 | ------- |
| 162 | extend_memory: `ExtendMemory` |
| 163 | |
| 164 | """ |
| 165 | size_to_extend = Uint(0) |
| 166 | to_be_paid = Uint(0) |
| 167 | current_size = Uint(len(memory)) |
| 168 | for start_position, size in extensions: |
| 169 | if size == 0: |
| 170 | continue |
| 171 | before_size = ceil32(current_size) |
| 172 | after_size = ceil32(Uint(start_position) + Uint(size)) |
| 173 | if after_size <= before_size: |
| 174 | continue |
| 175 | |
| 176 | size_to_extend += after_size - before_size |
| 177 | already_paid = calculate_memory_gas_cost(before_size) |
| 178 | total_cost = calculate_memory_gas_cost(after_size) |
| 179 | to_be_paid += total_cost - already_paid |
| 180 | |
| 181 | current_size = after_size |
| 182 | |
| 183 | return ExtendMemory(to_be_paid, size_to_extend) |
calculate_message_call_gas ¶
Calculates the gas amount for executing Opcodes Calculates the MessageCallGas (cost and gas made available to the sub-call)
for executing call Opcodes.CALL and CALLCODE.
Parameters
state :value:
The current state.The amount of ETH that needs to be transferred.
gas :
The amount of gas provided to the message-call.
to:gas_left :
The address of the recipient account.The amount of gas left in the current frame.
value:memory_cost :
The amount of 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).ETH that needs to be transferred.
Returns
message_call_gas: MessageCallGas
def calculate_message_call_gas(statevalue: StateU256, gas: Uint, togas_left: AddressUint, valuememory_cost: U256Uint, extra_gas: Uintcall_stipend: Uint) -> MessageCallGas:
| 194 | """ |
|---|---|
| 190 | Calculates the gas amount for executing Opcodes `CALL` and `CALLCODE`. |
| 195 | Calculates the MessageCallGas (cost and gas made available to the sub-call) |
| 196 | for executing call Opcodes. |
| 197 | |
| 198 | Parameters |
| 199 | ---------- |
| 194 | state : |
| 195 | The current state. |
| 200 | value: |
| 201 | The amount of `ETH` that needs to be transferred. |
| 202 | gas : |
| 203 | The amount of gas provided to the message-call. |
| 198 | to: |
| 199 | The address of the recipient account. |
| 200 | value: |
| 201 | The amount of `ETH` that needs to be transferred. |
| 204 | gas_left : |
| 205 | The amount of gas left in the current frame. |
| 206 | memory_cost : |
| 207 | The amount needed to extend the memory in the current frame. |
| 208 | extra_gas : |
| 209 | The amount of gas needed for transferring value + creating a new |
| 210 | account inside a message call. |
| 211 | call_stipend : |
| 212 | The amount of stipend provided to a message call to execute code while |
| 213 | transferring value (ETH). |
| 214 | |
| 215 | Returns |
| 216 | ------- |
| 217 | message_call_gas: `MessageCallGas` |
| 218 | |
| 219 | """ |
| 208 | create_gas_cost = Uint(0) if account_exists(state, to) else GAS_NEW_ACCOUNT |
| 209 | transfer_gas_cost = Uint(0) if value == 0 else GAS_CALL_VALUE |
| 210 | cost = GAS_CALL + gas + create_gas_cost + transfer_gas_cost |
| 211 | stipend = gas if value == 0 else GAS_CALL_STIPEND + gas |
| 212 | return MessageCallGas(cost, stipend) |
| 220 | call_stipend = Uint(0) if value == 0 else call_stipend |
| 221 | if gas_left < extra_gas + memory_cost: |
| 222 | return MessageCallGas(gas + extra_gas, gas + call_stipend) |
| 223 | |
| 224 | gas = min(gas, max_message_call_gas(gas_left - memory_cost - extra_gas)) |
| 225 | |
| 226 | 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:
| 230 | """ |
|---|---|
| 231 | Calculates the maximum gas that is allowed for making a message call. |
| 232 | |
| 233 | Parameters |
| 234 | ---------- |
| 235 | gas : |
| 236 | The amount of gas provided to the message-call. |
| 237 | |
| 238 | Returns |
| 239 | ------- |
| 240 | max_allowed_message_call_gas: `ethereum.base_types.Uint` |
| 241 | The maximum gas allowed for making the message-call. |
| 242 | |
| 243 | """ |
| 244 | return gas - (gas // Uint(64)) |