diff --git a/packages/testing/src/execution_testing/forks/forks/forks.py b/packages/testing/src/execution_testing/forks/forks/forks.py index d7525f437cb..b504aaba038 100644 --- a/packages/testing/src/execution_testing/forks/forks/forks.py +++ b/packages/testing/src/execution_testing/forks/forks/forks.py @@ -46,7 +46,13 @@ TransactionDataFloorCostCalculator, TransactionIntrinsicCostCalculator, ) -from ..gas_costs import GasCosts +from ..gas_costs import ( + GAS_HIGH, + GAS_LOW, + GAS_MID, + GAS_VERY_LOW, + GasCosts, +) from .helpers import ceiling_division, fake_exponential CURRENT_FILE = Path(realpath(__file__)) @@ -201,6 +207,39 @@ def gas_costs( GAS_PRECOMPILE_BLS_PAIRING_PER_PAIR=0, GAS_PRECOMPILE_P256VERIFY=0, GAS_BLOCK_ACCESS_LIST_ITEM=0, + # Opcode specific gas constants for repricing + GAS_OPCODE_ADD=GAS_VERY_LOW, + GAS_OPCODE_SUB=GAS_VERY_LOW, + GAS_OPCODE_MUL=GAS_LOW, + GAS_OPCODE_DIV=GAS_LOW, + GAS_OPCODE_SDIV=GAS_LOW, + GAS_OPCODE_MOD=GAS_LOW, + GAS_OPCODE_SMOD=GAS_LOW, + GAS_OPCODE_ADDMOD=GAS_MID, + GAS_OPCODE_MULMOD=GAS_MID, + GAS_OPCODE_SIGNEXTEND=GAS_LOW, + GAS_OPCODE_LT=GAS_VERY_LOW, + GAS_OPCODE_GT=GAS_VERY_LOW, + GAS_OPCODE_SLT=GAS_VERY_LOW, + GAS_OPCODE_SGT=GAS_VERY_LOW, + GAS_OPCODE_EQ=GAS_VERY_LOW, + GAS_OPCODE_ISZERO=GAS_VERY_LOW, + GAS_OPCODE_AND=GAS_VERY_LOW, + GAS_OPCODE_OR=GAS_VERY_LOW, + GAS_OPCODE_XOR=GAS_VERY_LOW, + GAS_OPCODE_NOT=GAS_VERY_LOW, + GAS_OPCODE_BYTE=GAS_VERY_LOW, + GAS_OPCODE_JUMP=GAS_MID, + GAS_OPCODE_JUMPI=GAS_HIGH, + GAS_OPCODE_CALLDATALOAD=GAS_VERY_LOW, + GAS_OPCODE_CALLDATACOPY=GAS_VERY_LOW, + GAS_OPCODE_CODECOPY=GAS_VERY_LOW, + GAS_OPCODE_MLOAD=GAS_VERY_LOW, + GAS_OPCODE_MSTORE=GAS_VERY_LOW, + GAS_OPCODE_MSTORE8=GAS_VERY_LOW, + GAS_OPCODE_PUSH_N=GAS_VERY_LOW, + GAS_OPCODE_DUP_N=GAS_VERY_LOW, + GAS_OPCODE_SWAP_N=GAS_VERY_LOW, ) @classmethod @@ -338,33 +377,33 @@ def opcode_gas_map( return { # Stop and arithmetic operations Opcodes.STOP: 0, - Opcodes.ADD: gas_costs.GAS_VERY_LOW, - Opcodes.MUL: gas_costs.GAS_LOW, - Opcodes.SUB: gas_costs.GAS_VERY_LOW, - Opcodes.DIV: gas_costs.GAS_LOW, - Opcodes.SDIV: gas_costs.GAS_LOW, - Opcodes.MOD: gas_costs.GAS_LOW, - Opcodes.SMOD: gas_costs.GAS_LOW, - Opcodes.ADDMOD: gas_costs.GAS_MID, - Opcodes.MULMOD: gas_costs.GAS_MID, + Opcodes.ADD: gas_costs.GAS_OPCODE_ADD, + Opcodes.MUL: gas_costs.GAS_OPCODE_MUL, + Opcodes.SUB: gas_costs.GAS_OPCODE_SUB, + Opcodes.DIV: gas_costs.GAS_OPCODE_DIV, + Opcodes.SDIV: gas_costs.GAS_OPCODE_SDIV, + Opcodes.MOD: gas_costs.GAS_OPCODE_MOD, + Opcodes.SMOD: gas_costs.GAS_OPCODE_SMOD, + Opcodes.ADDMOD: gas_costs.GAS_OPCODE_ADDMOD, + Opcodes.MULMOD: gas_costs.GAS_OPCODE_MULMOD, Opcodes.EXP: lambda op: ( gas_costs.GAS_EXPONENTIATION + gas_costs.GAS_EXPONENTIATION_PER_BYTE * ((op.metadata["exponent"].bit_length() + 7) // 8) ), - Opcodes.SIGNEXTEND: gas_costs.GAS_LOW, + Opcodes.SIGNEXTEND: gas_costs.GAS_OPCODE_SIGNEXTEND, # Comparison & bitwise logic operations - Opcodes.LT: gas_costs.GAS_VERY_LOW, - Opcodes.GT: gas_costs.GAS_VERY_LOW, - Opcodes.SLT: gas_costs.GAS_VERY_LOW, - Opcodes.SGT: gas_costs.GAS_VERY_LOW, - Opcodes.EQ: gas_costs.GAS_VERY_LOW, - Opcodes.ISZERO: gas_costs.GAS_VERY_LOW, - Opcodes.AND: gas_costs.GAS_VERY_LOW, - Opcodes.OR: gas_costs.GAS_VERY_LOW, - Opcodes.XOR: gas_costs.GAS_VERY_LOW, - Opcodes.NOT: gas_costs.GAS_VERY_LOW, - Opcodes.BYTE: gas_costs.GAS_VERY_LOW, + Opcodes.LT: gas_costs.GAS_OPCODE_LT, + Opcodes.GT: gas_costs.GAS_OPCODE_GT, + Opcodes.SLT: gas_costs.GAS_OPCODE_SLT, + Opcodes.SGT: gas_costs.GAS_OPCODE_SGT, + Opcodes.EQ: gas_costs.GAS_OPCODE_EQ, + Opcodes.ISZERO: gas_costs.GAS_OPCODE_ISZERO, + Opcodes.AND: gas_costs.GAS_OPCODE_AND, + Opcodes.OR: gas_costs.GAS_OPCODE_OR, + Opcodes.XOR: gas_costs.GAS_OPCODE_XOR, + Opcodes.NOT: gas_costs.GAS_OPCODE_NOT, + Opcodes.BYTE: gas_costs.GAS_OPCODE_BYTE, # SHA3 Opcodes.SHA3: cls._with_memory_expansion( lambda op: ( @@ -380,15 +419,17 @@ def opcode_gas_map( Opcodes.ORIGIN: gas_costs.GAS_BASE, Opcodes.CALLER: gas_costs.GAS_BASE, Opcodes.CALLVALUE: gas_costs.GAS_BASE, - Opcodes.CALLDATALOAD: gas_costs.GAS_VERY_LOW, + Opcodes.CALLDATALOAD: gas_costs.GAS_OPCODE_CALLDATALOAD, Opcodes.CALLDATASIZE: gas_costs.GAS_BASE, Opcodes.CALLDATACOPY: cls._with_memory_expansion( - cls._with_data_copy(gas_costs.GAS_VERY_LOW, gas_costs), + cls._with_data_copy( + gas_costs.GAS_OPCODE_CALLDATACOPY, gas_costs + ), memory_expansion_calculator, ), Opcodes.CODESIZE: gas_costs.GAS_BASE, Opcodes.CODECOPY: cls._with_memory_expansion( - cls._with_data_copy(gas_costs.GAS_VERY_LOW, gas_costs), + cls._with_data_copy(gas_costs.GAS_OPCODE_CODECOPY, gas_costs), memory_expansion_calculator, ), Opcodes.GASPRICE: gas_costs.GAS_BASE, @@ -410,13 +451,16 @@ def opcode_gas_map( # Stack, memory, storage and flow operations Opcodes.POP: gas_costs.GAS_BASE, Opcodes.MLOAD: cls._with_memory_expansion( - gas_costs.GAS_VERY_LOW, memory_expansion_calculator + gas_costs.GAS_OPCODE_MLOAD, + memory_expansion_calculator, ), Opcodes.MSTORE: cls._with_memory_expansion( - gas_costs.GAS_VERY_LOW, memory_expansion_calculator + gas_costs.GAS_OPCODE_MSTORE, + memory_expansion_calculator, ), Opcodes.MSTORE8: cls._with_memory_expansion( - gas_costs.GAS_VERY_LOW, memory_expansion_calculator + gas_costs.GAS_OPCODE_MSTORE8, + memory_expansion_calculator, ), Opcodes.SLOAD: lambda op: ( gas_costs.GAS_WARM_SLOAD @@ -426,25 +470,25 @@ def opcode_gas_map( Opcodes.SSTORE: lambda op: cls._calculate_sstore_gas( op, gas_costs ), - Opcodes.JUMP: gas_costs.GAS_MID, - Opcodes.JUMPI: gas_costs.GAS_HIGH, + Opcodes.JUMP: gas_costs.GAS_OPCODE_JUMP, + Opcodes.JUMPI: gas_costs.GAS_OPCODE_JUMPI, Opcodes.PC: gas_costs.GAS_BASE, Opcodes.MSIZE: gas_costs.GAS_BASE, Opcodes.GAS: gas_costs.GAS_BASE, Opcodes.JUMPDEST: gas_costs.GAS_JUMPDEST, # Push operations (PUSH1 through PUSH32) **{ - getattr(Opcodes, f"PUSH{i}"): gas_costs.GAS_VERY_LOW + getattr(Opcodes, f"PUSH{i}"): gas_costs.GAS_OPCODE_PUSH_N for i in range(1, 33) }, # Dup operations (DUP1 through DUP16) **{ - getattr(Opcodes, f"DUP{i}"): gas_costs.GAS_VERY_LOW + getattr(Opcodes, f"DUP{i}"): gas_costs.GAS_OPCODE_DUP_N for i in range(1, 17) }, # Swap operations (SWAP1 through SWAP16) **{ - getattr(Opcodes, f"SWAP{i}"): gas_costs.GAS_VERY_LOW + getattr(Opcodes, f"SWAP{i}"): gas_costs.GAS_OPCODE_SWAP_N for i in range(1, 17) }, # Logging operations @@ -1690,7 +1734,10 @@ def opcode_gas_map( **base_map, Opcodes.RETURNDATASIZE: gas_costs.GAS_BASE, Opcodes.RETURNDATACOPY: cls._with_memory_expansion( - cls._with_data_copy(gas_costs.GAS_VERY_LOW, gas_costs), + cls._with_data_copy( + gas_costs.GAS_OPCODE_RETURNDATACOPY, + gas_costs, + ), memory_expansion_calculator, ), Opcodes.STATICCALL: cls._with_memory_expansion( @@ -1730,6 +1777,7 @@ def gas_costs( GAS_PRECOMPILE_ECMUL=40_000, GAS_PRECOMPILE_ECPAIRING_BASE=100_000, GAS_PRECOMPILE_ECPAIRING_PER_POINT=80_000, + GAS_OPCODE_RETURNDATACOPY=GAS_VERY_LOW, ) @@ -1768,6 +1816,20 @@ def create_opcodes( block_number=block_number, timestamp=timestamp ) + @classmethod + def gas_costs( + cls, *, block_number: int = 0, timestamp: int = 0 + ) -> GasCosts: + """At Constantinople, shift opcodes are introduced.""" + return replace( + super(Constantinople, cls).gas_costs( + block_number=block_number, timestamp=timestamp + ), + GAS_OPCODE_SHL=GAS_VERY_LOW, + GAS_OPCODE_SHR=GAS_VERY_LOW, + GAS_OPCODE_SAR=GAS_VERY_LOW, + ) + @classmethod def opcode_gas_map( cls, *, block_number: int = 0, timestamp: int = 0 @@ -1784,9 +1846,9 @@ def opcode_gas_map( ) return { **base_map, - Opcodes.SHL: gas_costs.GAS_VERY_LOW, - Opcodes.SHR: gas_costs.GAS_VERY_LOW, - Opcodes.SAR: gas_costs.GAS_VERY_LOW, + Opcodes.SHL: gas_costs.GAS_OPCODE_SHL, + Opcodes.SHR: gas_costs.GAS_OPCODE_SHR, + Opcodes.SAR: gas_costs.GAS_OPCODE_SAR, Opcodes.EXTCODEHASH: cls._with_account_access(0, gas_costs), Opcodes.CREATE2: cls._with_memory_expansion( lambda op: cls._calculate_create2_gas(op, gas_costs), @@ -2652,6 +2714,8 @@ def gas_costs( block_number=block_number, timestamp=timestamp ), GAS_PRECOMPILE_POINT_EVALUATION=50_000, + GAS_OPCODE_BLOBHASH=GAS_VERY_LOW, + GAS_OPCODE_MCOPY=GAS_VERY_LOW, ) @classmethod @@ -2680,7 +2744,7 @@ def opcode_gas_map( return { **base_map, # EIP-4844: Shard Blob Transactions - Opcodes.BLOBHASH: gas_costs.GAS_VERY_LOW, + Opcodes.BLOBHASH: gas_costs.GAS_OPCODE_BLOBHASH, # EIP-7516: BLOBBASEFEE opcode Opcodes.BLOBBASEFEE: gas_costs.GAS_BASE, # EIP-1153: Transient storage opcodes @@ -2688,7 +2752,7 @@ def opcode_gas_map( Opcodes.TSTORE: gas_costs.GAS_WARM_SLOAD, # EIP-5656: MCOPY - Memory copying instruction Opcodes.MCOPY: cls._with_memory_expansion( - cls._with_data_copy(gas_costs.GAS_VERY_LOW, gas_costs), + cls._with_data_copy(gas_costs.GAS_OPCODE_MCOPY, gas_costs), memory_expansion_calculator, ), } @@ -2781,6 +2845,7 @@ def gas_costs( GAS_PRECOMPILE_BLS_G2MAP=23_800, GAS_PRECOMPILE_BLS_PAIRING_BASE=37_700, GAS_PRECOMPILE_BLS_PAIRING_PER_PAIR=32_600, + GAS_OPCODE_CLZ=GAS_LOW, ) @classmethod @@ -3150,7 +3215,7 @@ def opcode_gas_map( ) return { **base_map, - Opcodes.CLZ: gas_costs.GAS_LOW, + Opcodes.CLZ: gas_costs.GAS_OPCODE_CLZ, } @classmethod diff --git a/packages/testing/src/execution_testing/forks/gas_costs.py b/packages/testing/src/execution_testing/forks/gas_costs.py index eb632dd0888..5ef97ce3e99 100644 --- a/packages/testing/src/execution_testing/forks/gas_costs.py +++ b/packages/testing/src/execution_testing/forks/gas_costs.py @@ -2,6 +2,12 @@ from dataclasses import dataclass +# Common Gas Cost Tiers +GAS_VERY_LOW = 3 +GAS_LOW = 5 +GAS_MID = 8 +GAS_HIGH = 10 + @dataclass(kw_only=True, frozen=True) class GasCosts: @@ -91,3 +97,46 @@ class GasCosts: REFUND_AUTH_PER_EXISTING_ACCOUNT: int GAS_BLOCK_ACCESS_LIST_ITEM: int + + # Opcode specific gas constants for repricing + GAS_OPCODE_ADD: int + GAS_OPCODE_SUB: int + GAS_OPCODE_MUL: int + GAS_OPCODE_DIV: int + GAS_OPCODE_SDIV: int + GAS_OPCODE_MOD: int + GAS_OPCODE_SMOD: int + GAS_OPCODE_ADDMOD: int + GAS_OPCODE_MULMOD: int + GAS_OPCODE_SIGNEXTEND: int + GAS_OPCODE_LT: int + GAS_OPCODE_GT: int + GAS_OPCODE_SLT: int + GAS_OPCODE_SGT: int + GAS_OPCODE_EQ: int + GAS_OPCODE_ISZERO: int + GAS_OPCODE_AND: int + GAS_OPCODE_OR: int + GAS_OPCODE_XOR: int + GAS_OPCODE_NOT: int + GAS_OPCODE_BYTE: int + GAS_OPCODE_JUMP: int + GAS_OPCODE_JUMPI: int + GAS_OPCODE_CALLDATALOAD: int + GAS_OPCODE_CALLDATACOPY: int + GAS_OPCODE_CODECOPY: int + GAS_OPCODE_MLOAD: int + GAS_OPCODE_MSTORE: int + GAS_OPCODE_MSTORE8: int + GAS_OPCODE_PUSH_N: int + GAS_OPCODE_DUP_N: int + GAS_OPCODE_SWAP_N: int + + # Defined post-Frontier + GAS_OPCODE_SHL: int = 0 + GAS_OPCODE_SHR: int = 0 + GAS_OPCODE_SAR: int = 0 + GAS_OPCODE_RETURNDATACOPY: int = 0 + GAS_OPCODE_BLOBHASH: int = 0 + GAS_OPCODE_MCOPY: int = 0 + GAS_OPCODE_CLZ: int = 0 diff --git a/src/ethereum/forks/amsterdam/vm/gas.py b/src/ethereum/forks/amsterdam/vm/gas.py index d3917935e27..ea87d412529 100644 --- a/src/ethereum/forks/amsterdam/vm/gas.py +++ b/src/ethereum/forks/amsterdam/vm/gas.py @@ -67,7 +67,7 @@ GAS_COLD_ACCOUNT_ACCESS = Uint(2600) GAS_WARM_ACCESS = Uint(100) GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) +GAS_BLOBHASH = Uint(3) GAS_POINT_EVALUATION = Uint(50000) GAS_PER_BLOB = U64(2**17) @@ -87,6 +87,46 @@ GAS_BLOCK_ACCESS_LIST_ITEM = Uint(2000) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_CLZ = GAS_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_MCOPY = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + @dataclass class ExtendMemory: diff --git a/src/ethereum/forks/amsterdam/vm/instructions/arithmetic.py b/src/ethereum/forks/amsterdam/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/amsterdam/vm/instructions/bitwise.py b/src/ethereum/forks/amsterdam/vm/instructions/bitwise.py index cc6fa2fbb23..3cb188b8579 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/bitwise.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +264,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/amsterdam/vm/instructions/block.py b/src/ethereum/forks/amsterdam/vm/instructions/block.py index e563a2e96e8..1ded7a0d9fa 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/block.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/amsterdam/vm/instructions/comparison.py b/src/ethereum/forks/amsterdam/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/comparison.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/amsterdam/vm/instructions/control_flow.py b/src/ethereum/forks/amsterdam/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/control_flow.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/amsterdam/vm/instructions/environment.py b/src/ethereum/forks/amsterdam/vm/instructions/environment.py index f5f89bdfa59..3e2a9e053c8 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/environment.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/environment.py @@ -20,16 +20,15 @@ from ...state_tracker import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, - GAS_BLOBHASH_OPCODE, + GAS_BLOBHASH, GAS_COLD_ACCOUNT_ACCESS, GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_blob_gas_price, calculate_gas_extend_memory, @@ -178,7 +177,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -236,7 +235,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -294,7 +296,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -454,7 +459,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -571,7 +579,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GAS_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): diff --git a/src/ethereum/forks/amsterdam/vm/instructions/keccak.py b/src/ethereum/forks/amsterdam/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/keccak.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/amsterdam/vm/instructions/log.py b/src/ethereum/forks/amsterdam/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/log.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/amsterdam/vm/instructions/memory.py b/src/ethereum/forks/amsterdam/vm/instructions/memory.py index 6e111051ee3..bccc5fd6f01 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/memory.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/memory.py @@ -16,11 +16,10 @@ from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, GAS_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +48,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +79,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +107,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -166,7 +165,10 @@ def mcopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_MCOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/amsterdam/vm/instructions/stack.py b/src/ethereum/forks/amsterdam/vm/instructions/stack.py index 0007a28acd4..3aaadbf69ab 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/stack.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -65,7 +68,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: if num_bytes == 0: charge_gas(evm, GAS_BASE) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/amsterdam/vm/instructions/storage.py b/src/ethereum/forks/amsterdam/vm/instructions/storage.py index 60056cf5750..ec7365c4c2f 100644 --- a/src/ethereum/forks/amsterdam/vm/instructions/storage.py +++ b/src/ethereum/forks/amsterdam/vm/instructions/storage.py @@ -20,18 +20,9 @@ set_storage, set_transient_storage, ) -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, - check_gas, -) +from ..gas import charge_gas, check_gas from ..stack import pop, push @@ -51,10 +42,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION tx_state = evm.message.tx_env.state @@ -84,7 +75,7 @@ def sstore(evm: Evm) -> None: new_value = pop(evm.stack) # check we have at least the stipend gas - check_gas(evm, GAS_CALL_STIPEND + Uint(1)) + check_gas(evm, gas.GAS_CALL_STIPEND + Uint(1)) tx_state = evm.message.tx_env.state original_value = get_storage_original( @@ -96,35 +87,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -149,7 +144,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -179,7 +174,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) set_transient_storage( evm.message.tx_env.state, evm.message.current_target, diff --git a/src/ethereum/forks/arrow_glacier/vm/gas.py b/src/ethereum/forks/arrow_glacier/vm/gas.py index 1929dd5ca3b..c38b90d50d6 100644 --- a/src/ethereum/forks/arrow_glacier/vm/gas.py +++ b/src/ethereum/forks/arrow_glacier/vm/gas.py @@ -64,6 +64,45 @@ GAS_WARM_ACCESS = Uint(100) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/arithmetic.py b/src/ethereum/forks/arrow_glacier/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/bitwise.py b/src/ethereum/forks/arrow_glacier/vm/instructions/bitwise.py index 41dabe8185b..4e0a487a749 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/bitwise.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/block.py b/src/ethereum/forks/arrow_glacier/vm/instructions/block.py index bbf01739ff2..24c154271d7 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/block.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -203,7 +203,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/comparison.py b/src/ethereum/forks/arrow_glacier/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/comparison.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/control_flow.py b/src/ethereum/forks/arrow_glacier/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/control_flow.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/environment.py b/src/ethereum/forks/arrow_glacier/vm/instructions/environment.py index fe1b70c1269..31b236e66ca 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/environment.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/environment.py @@ -19,7 +19,7 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, @@ -27,7 +27,6 @@ GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_gas_extend_memory, charge_gas, @@ -173,7 +172,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -231,7 +230,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -289,7 +291,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -443,7 +448,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/keccak.py b/src/ethereum/forks/arrow_glacier/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/keccak.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/log.py b/src/ethereum/forks/arrow_glacier/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/log.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/memory.py b/src/ethereum/forks/arrow_glacier/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/memory.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/stack.py b/src/ethereum/forks/arrow_glacier/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/stack.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/arrow_glacier/vm/instructions/storage.py b/src/ethereum/forks/arrow_glacier/vm/instructions/storage.py index 6129ed5322c..93134c1b42b 100644 --- a/src/ethereum/forks/arrow_glacier/vm/instructions/storage.py +++ b/src/ethereum/forks/arrow_glacier/vm/instructions/storage.py @@ -14,17 +14,9 @@ from ethereum_types.numeric import Uint from ...state import get_storage, get_storage_original, set_storage -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -44,10 +36,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -73,7 +65,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -86,35 +78,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/berlin/vm/gas.py b/src/ethereum/forks/berlin/vm/gas.py index 477037c3298..fea396e188f 100644 --- a/src/ethereum/forks/berlin/vm/gas.py +++ b/src/ethereum/forks/berlin/vm/gas.py @@ -65,6 +65,45 @@ GAS_WARM_ACCESS = Uint(100) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/berlin/vm/instructions/arithmetic.py b/src/ethereum/forks/berlin/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/berlin/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/berlin/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/berlin/vm/instructions/bitwise.py b/src/ethereum/forks/berlin/vm/instructions/bitwise.py index 41dabe8185b..4e0a487a749 100644 --- a/src/ethereum/forks/berlin/vm/instructions/bitwise.py +++ b/src/ethereum/forks/berlin/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/berlin/vm/instructions/block.py b/src/ethereum/forks/berlin/vm/instructions/block.py index bbf01739ff2..24c154271d7 100644 --- a/src/ethereum/forks/berlin/vm/instructions/block.py +++ b/src/ethereum/forks/berlin/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -203,7 +203,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/berlin/vm/instructions/comparison.py b/src/ethereum/forks/berlin/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/berlin/vm/instructions/comparison.py +++ b/src/ethereum/forks/berlin/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/berlin/vm/instructions/control_flow.py b/src/ethereum/forks/berlin/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/berlin/vm/instructions/control_flow.py +++ b/src/ethereum/forks/berlin/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/berlin/vm/instructions/environment.py b/src/ethereum/forks/berlin/vm/instructions/environment.py index 63733aca3d5..c2770cd8fa4 100644 --- a/src/ethereum/forks/berlin/vm/instructions/environment.py +++ b/src/ethereum/forks/berlin/vm/instructions/environment.py @@ -19,7 +19,7 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, @@ -27,7 +27,6 @@ GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_gas_extend_memory, charge_gas, @@ -173,7 +172,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -231,7 +230,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -289,7 +291,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -443,7 +448,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead diff --git a/src/ethereum/forks/berlin/vm/instructions/keccak.py b/src/ethereum/forks/berlin/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/berlin/vm/instructions/keccak.py +++ b/src/ethereum/forks/berlin/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/berlin/vm/instructions/log.py b/src/ethereum/forks/berlin/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/berlin/vm/instructions/log.py +++ b/src/ethereum/forks/berlin/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/berlin/vm/instructions/memory.py b/src/ethereum/forks/berlin/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/berlin/vm/instructions/memory.py +++ b/src/ethereum/forks/berlin/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/berlin/vm/instructions/stack.py b/src/ethereum/forks/berlin/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/berlin/vm/instructions/stack.py +++ b/src/ethereum/forks/berlin/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/berlin/vm/instructions/storage.py b/src/ethereum/forks/berlin/vm/instructions/storage.py index 6129ed5322c..93134c1b42b 100644 --- a/src/ethereum/forks/berlin/vm/instructions/storage.py +++ b/src/ethereum/forks/berlin/vm/instructions/storage.py @@ -14,17 +14,9 @@ from ethereum_types.numeric import Uint from ...state import get_storage, get_storage_original, set_storage -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -44,10 +36,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -73,7 +65,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -86,35 +78,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/bpo1/vm/gas.py b/src/ethereum/forks/bpo1/vm/gas.py index 8b2e13fa8b5..bc6d512698a 100644 --- a/src/ethereum/forks/bpo1/vm/gas.py +++ b/src/ethereum/forks/bpo1/vm/gas.py @@ -66,7 +66,7 @@ GAS_COLD_ACCOUNT_ACCESS = Uint(2600) GAS_WARM_ACCESS = Uint(100) GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) +GAS_BLOBHASH = Uint(3) GAS_POINT_EVALUATION = Uint(50000) GAS_PER_BLOB = U64(2**17) @@ -84,6 +84,46 @@ GAS_BLS_G2_MUL = Uint(22500) GAS_BLS_G2_MAP = Uint(23800) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_CLZ = GAS_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_MCOPY = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + @dataclass class ExtendMemory: diff --git a/src/ethereum/forks/bpo1/vm/instructions/arithmetic.py b/src/ethereum/forks/bpo1/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/bpo1/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/bpo1/vm/instructions/bitwise.py b/src/ethereum/forks/bpo1/vm/instructions/bitwise.py index cc6fa2fbb23..3cb188b8579 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/bitwise.py +++ b/src/ethereum/forks/bpo1/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +264,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/bpo1/vm/instructions/block.py b/src/ethereum/forks/bpo1/vm/instructions/block.py index 75810aacd39..8e181fae616 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/block.py +++ b/src/ethereum/forks/bpo1/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/bpo1/vm/instructions/comparison.py b/src/ethereum/forks/bpo1/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/comparison.py +++ b/src/ethereum/forks/bpo1/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/bpo1/vm/instructions/control_flow.py b/src/ethereum/forks/bpo1/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/control_flow.py +++ b/src/ethereum/forks/bpo1/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/bpo1/vm/instructions/environment.py b/src/ethereum/forks/bpo1/vm/instructions/environment.py index 5848530a960..936297a73a6 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo1/vm/instructions/environment.py @@ -20,16 +20,15 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, - GAS_BLOBHASH_OPCODE, + GAS_BLOBHASH, GAS_COLD_ACCOUNT_ACCESS, GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_blob_gas_price, calculate_gas_extend_memory, @@ -176,7 +175,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -234,7 +233,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -292,7 +294,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -446,7 +451,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -561,7 +569,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GAS_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): diff --git a/src/ethereum/forks/bpo1/vm/instructions/keccak.py b/src/ethereum/forks/bpo1/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/keccak.py +++ b/src/ethereum/forks/bpo1/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo1/vm/instructions/log.py b/src/ethereum/forks/bpo1/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/log.py +++ b/src/ethereum/forks/bpo1/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/bpo1/vm/instructions/memory.py b/src/ethereum/forks/bpo1/vm/instructions/memory.py index 6e111051ee3..bccc5fd6f01 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/memory.py +++ b/src/ethereum/forks/bpo1/vm/instructions/memory.py @@ -16,11 +16,10 @@ from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, GAS_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +48,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +79,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +107,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -166,7 +165,10 @@ def mcopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_MCOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo1/vm/instructions/stack.py b/src/ethereum/forks/bpo1/vm/instructions/stack.py index 0007a28acd4..3aaadbf69ab 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo1/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -65,7 +68,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: if num_bytes == 0: charge_gas(evm, GAS_BASE) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/bpo1/vm/instructions/storage.py b/src/ethereum/forks/bpo1/vm/instructions/storage.py index 084d58cc46c..8ad14c9dedd 100644 --- a/src/ethereum/forks/bpo1/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo1/vm/instructions/storage.py @@ -20,17 +20,9 @@ set_storage, set_transient_storage, ) -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -50,10 +42,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -79,7 +71,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,35 +84,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -147,7 +143,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -174,7 +170,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/bpo2/vm/gas.py b/src/ethereum/forks/bpo2/vm/gas.py index a2e5d1ab39a..9d87d29f244 100644 --- a/src/ethereum/forks/bpo2/vm/gas.py +++ b/src/ethereum/forks/bpo2/vm/gas.py @@ -66,7 +66,7 @@ GAS_COLD_ACCOUNT_ACCESS = Uint(2600) GAS_WARM_ACCESS = Uint(100) GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) +GAS_BLOBHASH = Uint(3) GAS_POINT_EVALUATION = Uint(50000) GAS_PER_BLOB = U64(2**17) @@ -84,6 +84,46 @@ GAS_BLS_G2_MUL = Uint(22500) GAS_BLS_G2_MAP = Uint(23800) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_CLZ = GAS_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_MCOPY = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + @dataclass class ExtendMemory: diff --git a/src/ethereum/forks/bpo2/vm/instructions/arithmetic.py b/src/ethereum/forks/bpo2/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/bpo2/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/bpo2/vm/instructions/bitwise.py b/src/ethereum/forks/bpo2/vm/instructions/bitwise.py index cc6fa2fbb23..3cb188b8579 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/bitwise.py +++ b/src/ethereum/forks/bpo2/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +264,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/bpo2/vm/instructions/block.py b/src/ethereum/forks/bpo2/vm/instructions/block.py index 9923433c7b6..5b43e36a6c4 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/block.py +++ b/src/ethereum/forks/bpo2/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/bpo2/vm/instructions/comparison.py b/src/ethereum/forks/bpo2/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/comparison.py +++ b/src/ethereum/forks/bpo2/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/bpo2/vm/instructions/control_flow.py b/src/ethereum/forks/bpo2/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/control_flow.py +++ b/src/ethereum/forks/bpo2/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/bpo2/vm/instructions/environment.py b/src/ethereum/forks/bpo2/vm/instructions/environment.py index 5848530a960..936297a73a6 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo2/vm/instructions/environment.py @@ -20,16 +20,15 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, - GAS_BLOBHASH_OPCODE, + GAS_BLOBHASH, GAS_COLD_ACCOUNT_ACCESS, GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_blob_gas_price, calculate_gas_extend_memory, @@ -176,7 +175,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -234,7 +233,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -292,7 +294,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -446,7 +451,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -561,7 +569,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GAS_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): diff --git a/src/ethereum/forks/bpo2/vm/instructions/keccak.py b/src/ethereum/forks/bpo2/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/keccak.py +++ b/src/ethereum/forks/bpo2/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo2/vm/instructions/log.py b/src/ethereum/forks/bpo2/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/log.py +++ b/src/ethereum/forks/bpo2/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/bpo2/vm/instructions/memory.py b/src/ethereum/forks/bpo2/vm/instructions/memory.py index 6e111051ee3..bccc5fd6f01 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/memory.py +++ b/src/ethereum/forks/bpo2/vm/instructions/memory.py @@ -16,11 +16,10 @@ from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, GAS_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +48,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +79,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +107,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -166,7 +165,10 @@ def mcopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_MCOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo2/vm/instructions/stack.py b/src/ethereum/forks/bpo2/vm/instructions/stack.py index 0007a28acd4..3aaadbf69ab 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo2/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -65,7 +68,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: if num_bytes == 0: charge_gas(evm, GAS_BASE) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/bpo2/vm/instructions/storage.py b/src/ethereum/forks/bpo2/vm/instructions/storage.py index 084d58cc46c..8ad14c9dedd 100644 --- a/src/ethereum/forks/bpo2/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo2/vm/instructions/storage.py @@ -20,17 +20,9 @@ set_storage, set_transient_storage, ) -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -50,10 +42,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -79,7 +71,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,35 +84,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -147,7 +143,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -174,7 +170,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/bpo3/vm/gas.py b/src/ethereum/forks/bpo3/vm/gas.py index a2e5d1ab39a..9d87d29f244 100644 --- a/src/ethereum/forks/bpo3/vm/gas.py +++ b/src/ethereum/forks/bpo3/vm/gas.py @@ -66,7 +66,7 @@ GAS_COLD_ACCOUNT_ACCESS = Uint(2600) GAS_WARM_ACCESS = Uint(100) GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) +GAS_BLOBHASH = Uint(3) GAS_POINT_EVALUATION = Uint(50000) GAS_PER_BLOB = U64(2**17) @@ -84,6 +84,46 @@ GAS_BLS_G2_MUL = Uint(22500) GAS_BLS_G2_MAP = Uint(23800) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_CLZ = GAS_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_MCOPY = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + @dataclass class ExtendMemory: diff --git a/src/ethereum/forks/bpo3/vm/instructions/arithmetic.py b/src/ethereum/forks/bpo3/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/bpo3/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/bpo3/vm/instructions/bitwise.py b/src/ethereum/forks/bpo3/vm/instructions/bitwise.py index cc6fa2fbb23..3cb188b8579 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/bitwise.py +++ b/src/ethereum/forks/bpo3/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +264,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/bpo3/vm/instructions/block.py b/src/ethereum/forks/bpo3/vm/instructions/block.py index 10fcbdbdb57..726c50501b8 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/block.py +++ b/src/ethereum/forks/bpo3/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/bpo3/vm/instructions/comparison.py b/src/ethereum/forks/bpo3/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/comparison.py +++ b/src/ethereum/forks/bpo3/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/bpo3/vm/instructions/control_flow.py b/src/ethereum/forks/bpo3/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/control_flow.py +++ b/src/ethereum/forks/bpo3/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/bpo3/vm/instructions/environment.py b/src/ethereum/forks/bpo3/vm/instructions/environment.py index 5848530a960..936297a73a6 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo3/vm/instructions/environment.py @@ -20,16 +20,15 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, - GAS_BLOBHASH_OPCODE, + GAS_BLOBHASH, GAS_COLD_ACCOUNT_ACCESS, GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_blob_gas_price, calculate_gas_extend_memory, @@ -176,7 +175,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -234,7 +233,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -292,7 +294,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -446,7 +451,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -561,7 +569,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GAS_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): diff --git a/src/ethereum/forks/bpo3/vm/instructions/keccak.py b/src/ethereum/forks/bpo3/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/keccak.py +++ b/src/ethereum/forks/bpo3/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo3/vm/instructions/log.py b/src/ethereum/forks/bpo3/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/log.py +++ b/src/ethereum/forks/bpo3/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/bpo3/vm/instructions/memory.py b/src/ethereum/forks/bpo3/vm/instructions/memory.py index 6e111051ee3..bccc5fd6f01 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/memory.py +++ b/src/ethereum/forks/bpo3/vm/instructions/memory.py @@ -16,11 +16,10 @@ from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, GAS_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +48,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +79,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +107,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -166,7 +165,10 @@ def mcopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_MCOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo3/vm/instructions/stack.py b/src/ethereum/forks/bpo3/vm/instructions/stack.py index 0007a28acd4..3aaadbf69ab 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo3/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -65,7 +68,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: if num_bytes == 0: charge_gas(evm, GAS_BASE) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/bpo3/vm/instructions/storage.py b/src/ethereum/forks/bpo3/vm/instructions/storage.py index 084d58cc46c..8ad14c9dedd 100644 --- a/src/ethereum/forks/bpo3/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo3/vm/instructions/storage.py @@ -20,17 +20,9 @@ set_storage, set_transient_storage, ) -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -50,10 +42,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -79,7 +71,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,35 +84,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -147,7 +143,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -174,7 +170,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/bpo4/vm/gas.py b/src/ethereum/forks/bpo4/vm/gas.py index a2e5d1ab39a..9d87d29f244 100644 --- a/src/ethereum/forks/bpo4/vm/gas.py +++ b/src/ethereum/forks/bpo4/vm/gas.py @@ -66,7 +66,7 @@ GAS_COLD_ACCOUNT_ACCESS = Uint(2600) GAS_WARM_ACCESS = Uint(100) GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) +GAS_BLOBHASH = Uint(3) GAS_POINT_EVALUATION = Uint(50000) GAS_PER_BLOB = U64(2**17) @@ -84,6 +84,46 @@ GAS_BLS_G2_MUL = Uint(22500) GAS_BLS_G2_MAP = Uint(23800) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_CLZ = GAS_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_MCOPY = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + @dataclass class ExtendMemory: diff --git a/src/ethereum/forks/bpo4/vm/instructions/arithmetic.py b/src/ethereum/forks/bpo4/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/bpo4/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/bpo4/vm/instructions/bitwise.py b/src/ethereum/forks/bpo4/vm/instructions/bitwise.py index cc6fa2fbb23..3cb188b8579 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/bitwise.py +++ b/src/ethereum/forks/bpo4/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +264,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/bpo4/vm/instructions/block.py b/src/ethereum/forks/bpo4/vm/instructions/block.py index 52145aa9f82..d577c28dbbf 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/block.py +++ b/src/ethereum/forks/bpo4/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/bpo4/vm/instructions/comparison.py b/src/ethereum/forks/bpo4/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/comparison.py +++ b/src/ethereum/forks/bpo4/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/bpo4/vm/instructions/control_flow.py b/src/ethereum/forks/bpo4/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/control_flow.py +++ b/src/ethereum/forks/bpo4/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/bpo4/vm/instructions/environment.py b/src/ethereum/forks/bpo4/vm/instructions/environment.py index 5848530a960..936297a73a6 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo4/vm/instructions/environment.py @@ -20,16 +20,15 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, - GAS_BLOBHASH_OPCODE, + GAS_BLOBHASH, GAS_COLD_ACCOUNT_ACCESS, GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_blob_gas_price, calculate_gas_extend_memory, @@ -176,7 +175,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -234,7 +233,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -292,7 +294,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -446,7 +451,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -561,7 +569,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GAS_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): diff --git a/src/ethereum/forks/bpo4/vm/instructions/keccak.py b/src/ethereum/forks/bpo4/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/keccak.py +++ b/src/ethereum/forks/bpo4/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo4/vm/instructions/log.py b/src/ethereum/forks/bpo4/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/log.py +++ b/src/ethereum/forks/bpo4/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/bpo4/vm/instructions/memory.py b/src/ethereum/forks/bpo4/vm/instructions/memory.py index 6e111051ee3..bccc5fd6f01 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/memory.py +++ b/src/ethereum/forks/bpo4/vm/instructions/memory.py @@ -16,11 +16,10 @@ from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, GAS_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +48,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +79,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +107,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -166,7 +165,10 @@ def mcopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_MCOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo4/vm/instructions/stack.py b/src/ethereum/forks/bpo4/vm/instructions/stack.py index 0007a28acd4..3aaadbf69ab 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo4/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -65,7 +68,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: if num_bytes == 0: charge_gas(evm, GAS_BASE) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/bpo4/vm/instructions/storage.py b/src/ethereum/forks/bpo4/vm/instructions/storage.py index 084d58cc46c..8ad14c9dedd 100644 --- a/src/ethereum/forks/bpo4/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo4/vm/instructions/storage.py @@ -20,17 +20,9 @@ set_storage, set_transient_storage, ) -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -50,10 +42,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -79,7 +71,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,35 +84,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -147,7 +143,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -174,7 +170,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/bpo5/vm/gas.py b/src/ethereum/forks/bpo5/vm/gas.py index a2e5d1ab39a..9d87d29f244 100644 --- a/src/ethereum/forks/bpo5/vm/gas.py +++ b/src/ethereum/forks/bpo5/vm/gas.py @@ -66,7 +66,7 @@ GAS_COLD_ACCOUNT_ACCESS = Uint(2600) GAS_WARM_ACCESS = Uint(100) GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) +GAS_BLOBHASH = Uint(3) GAS_POINT_EVALUATION = Uint(50000) GAS_PER_BLOB = U64(2**17) @@ -84,6 +84,46 @@ GAS_BLS_G2_MUL = Uint(22500) GAS_BLS_G2_MAP = Uint(23800) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_CLZ = GAS_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_MCOPY = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + @dataclass class ExtendMemory: diff --git a/src/ethereum/forks/bpo5/vm/instructions/arithmetic.py b/src/ethereum/forks/bpo5/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/bpo5/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/bpo5/vm/instructions/bitwise.py b/src/ethereum/forks/bpo5/vm/instructions/bitwise.py index cc6fa2fbb23..3cb188b8579 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/bitwise.py +++ b/src/ethereum/forks/bpo5/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +264,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/bpo5/vm/instructions/block.py b/src/ethereum/forks/bpo5/vm/instructions/block.py index 84930244d4c..1e4da5970a3 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/block.py +++ b/src/ethereum/forks/bpo5/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/bpo5/vm/instructions/comparison.py b/src/ethereum/forks/bpo5/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/comparison.py +++ b/src/ethereum/forks/bpo5/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/bpo5/vm/instructions/control_flow.py b/src/ethereum/forks/bpo5/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/control_flow.py +++ b/src/ethereum/forks/bpo5/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/bpo5/vm/instructions/environment.py b/src/ethereum/forks/bpo5/vm/instructions/environment.py index 5848530a960..936297a73a6 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/environment.py +++ b/src/ethereum/forks/bpo5/vm/instructions/environment.py @@ -20,16 +20,15 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, - GAS_BLOBHASH_OPCODE, + GAS_BLOBHASH, GAS_COLD_ACCOUNT_ACCESS, GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_blob_gas_price, calculate_gas_extend_memory, @@ -176,7 +175,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -234,7 +233,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -292,7 +294,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -446,7 +451,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -561,7 +569,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GAS_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): diff --git a/src/ethereum/forks/bpo5/vm/instructions/keccak.py b/src/ethereum/forks/bpo5/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/keccak.py +++ b/src/ethereum/forks/bpo5/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo5/vm/instructions/log.py b/src/ethereum/forks/bpo5/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/log.py +++ b/src/ethereum/forks/bpo5/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/bpo5/vm/instructions/memory.py b/src/ethereum/forks/bpo5/vm/instructions/memory.py index 6e111051ee3..bccc5fd6f01 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/memory.py +++ b/src/ethereum/forks/bpo5/vm/instructions/memory.py @@ -16,11 +16,10 @@ from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, GAS_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +48,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +79,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +107,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -166,7 +165,10 @@ def mcopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_MCOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/bpo5/vm/instructions/stack.py b/src/ethereum/forks/bpo5/vm/instructions/stack.py index 0007a28acd4..3aaadbf69ab 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/stack.py +++ b/src/ethereum/forks/bpo5/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -65,7 +68,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: if num_bytes == 0: charge_gas(evm, GAS_BASE) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/bpo5/vm/instructions/storage.py b/src/ethereum/forks/bpo5/vm/instructions/storage.py index 084d58cc46c..8ad14c9dedd 100644 --- a/src/ethereum/forks/bpo5/vm/instructions/storage.py +++ b/src/ethereum/forks/bpo5/vm/instructions/storage.py @@ -20,17 +20,9 @@ set_storage, set_transient_storage, ) -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -50,10 +42,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -79,7 +71,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,35 +84,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -147,7 +143,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -174,7 +170,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/byzantium/vm/gas.py b/src/ethereum/forks/byzantium/vm/gas.py index b21cf5fd15d..adcff5dd650 100644 --- a/src/ethereum/forks/byzantium/vm/gas.py +++ b/src/ethereum/forks/byzantium/vm/gas.py @@ -64,6 +64,42 @@ GAS_RETURN_DATA_COPY = Uint(3) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/byzantium/vm/instructions/arithmetic.py b/src/ethereum/forks/byzantium/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/byzantium/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/byzantium/vm/instructions/bitwise.py b/src/ethereum/forks/byzantium/vm/instructions/bitwise.py index 2a506f55751..476d71d7603 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/bitwise.py +++ b/src/ethereum/forks/byzantium/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): diff --git a/src/ethereum/forks/byzantium/vm/instructions/block.py b/src/ethereum/forks/byzantium/vm/instructions/block.py index 0edcbf000d1..2e6460a4f7d 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/block.py +++ b/src/ethereum/forks/byzantium/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/byzantium/vm/instructions/comparison.py b/src/ethereum/forks/byzantium/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/comparison.py +++ b/src/ethereum/forks/byzantium/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/byzantium/vm/instructions/control_flow.py b/src/ethereum/forks/byzantium/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/control_flow.py +++ b/src/ethereum/forks/byzantium/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/byzantium/vm/instructions/environment.py b/src/ethereum/forks/byzantium/vm/instructions/environment.py index 0fa98ce55a5..9221133e41c 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/environment.py +++ b/src/ethereum/forks/byzantium/vm/instructions/environment.py @@ -18,7 +18,7 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BALANCE, @@ -26,7 +26,6 @@ GAS_COPY, GAS_EXTERNAL, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -167,7 +166,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -225,7 +224,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -283,7 +285,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -424,7 +429,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead diff --git a/src/ethereum/forks/byzantium/vm/instructions/keccak.py b/src/ethereum/forks/byzantium/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/keccak.py +++ b/src/ethereum/forks/byzantium/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/byzantium/vm/instructions/log.py b/src/ethereum/forks/byzantium/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/log.py +++ b/src/ethereum/forks/byzantium/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/byzantium/vm/instructions/memory.py b/src/ethereum/forks/byzantium/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/memory.py +++ b/src/ethereum/forks/byzantium/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/byzantium/vm/instructions/stack.py b/src/ethereum/forks/byzantium/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/stack.py +++ b/src/ethereum/forks/byzantium/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/byzantium/vm/instructions/storage.py b/src/ethereum/forks/byzantium/vm/instructions/storage.py index c62a67ae2d6..686420adcef 100644 --- a/src/ethereum/forks/byzantium/vm/instructions/storage.py +++ b/src/ethereum/forks/byzantium/vm/instructions/storage.py @@ -14,15 +14,9 @@ from ethereum_types.numeric import Uint from ...state import get_storage, set_storage -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext -from ..gas import ( - GAS_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -41,7 +35,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, gas.GAS_SLOAD) # OPERATION value = get_storage( @@ -72,12 +66,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = gas.GAS_STORAGE_SET else: - gas_cost = GAS_STORAGE_UPDATE + gas_cost = gas.GAS_STORAGE_UPDATE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) if evm.message.is_static: diff --git a/src/ethereum/forks/cancun/vm/gas.py b/src/ethereum/forks/cancun/vm/gas.py index cddb2b59e8c..d28192c2e67 100644 --- a/src/ethereum/forks/cancun/vm/gas.py +++ b/src/ethereum/forks/cancun/vm/gas.py @@ -65,7 +65,7 @@ GAS_COLD_ACCOUNT_ACCESS = Uint(2600) GAS_WARM_ACCESS = Uint(100) GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) +GAS_BLOBHASH = Uint(3) GAS_POINT_EVALUATION = Uint(50000) GAS_PER_BLOB = U64(2**17) @@ -74,6 +74,46 @@ BLOB_BASE_FEE_UPDATE_FRACTION = Uint(3338477) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_MCOPY = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/cancun/vm/instructions/arithmetic.py b/src/ethereum/forks/cancun/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/cancun/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/cancun/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/cancun/vm/instructions/bitwise.py b/src/ethereum/forks/cancun/vm/instructions/bitwise.py index 41dabe8185b..4e0a487a749 100644 --- a/src/ethereum/forks/cancun/vm/instructions/bitwise.py +++ b/src/ethereum/forks/cancun/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/cancun/vm/instructions/block.py b/src/ethereum/forks/cancun/vm/instructions/block.py index 4f971a9dbf4..1e04a4bc728 100644 --- a/src/ethereum/forks/cancun/vm/instructions/block.py +++ b/src/ethereum/forks/cancun/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/cancun/vm/instructions/comparison.py b/src/ethereum/forks/cancun/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/cancun/vm/instructions/comparison.py +++ b/src/ethereum/forks/cancun/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/cancun/vm/instructions/control_flow.py b/src/ethereum/forks/cancun/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/cancun/vm/instructions/control_flow.py +++ b/src/ethereum/forks/cancun/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/cancun/vm/instructions/environment.py b/src/ethereum/forks/cancun/vm/instructions/environment.py index 5848530a960..936297a73a6 100644 --- a/src/ethereum/forks/cancun/vm/instructions/environment.py +++ b/src/ethereum/forks/cancun/vm/instructions/environment.py @@ -20,16 +20,15 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, - GAS_BLOBHASH_OPCODE, + GAS_BLOBHASH, GAS_COLD_ACCOUNT_ACCESS, GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_blob_gas_price, calculate_gas_extend_memory, @@ -176,7 +175,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -234,7 +233,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -292,7 +294,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -446,7 +451,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -561,7 +569,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GAS_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): diff --git a/src/ethereum/forks/cancun/vm/instructions/keccak.py b/src/ethereum/forks/cancun/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/cancun/vm/instructions/keccak.py +++ b/src/ethereum/forks/cancun/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/cancun/vm/instructions/log.py b/src/ethereum/forks/cancun/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/cancun/vm/instructions/log.py +++ b/src/ethereum/forks/cancun/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/cancun/vm/instructions/memory.py b/src/ethereum/forks/cancun/vm/instructions/memory.py index 6e111051ee3..bccc5fd6f01 100644 --- a/src/ethereum/forks/cancun/vm/instructions/memory.py +++ b/src/ethereum/forks/cancun/vm/instructions/memory.py @@ -16,11 +16,10 @@ from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, GAS_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +48,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +79,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +107,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -166,7 +165,10 @@ def mcopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_MCOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/cancun/vm/instructions/stack.py b/src/ethereum/forks/cancun/vm/instructions/stack.py index 0007a28acd4..3aaadbf69ab 100644 --- a/src/ethereum/forks/cancun/vm/instructions/stack.py +++ b/src/ethereum/forks/cancun/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -65,7 +68,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: if num_bytes == 0: charge_gas(evm, GAS_BASE) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/cancun/vm/instructions/storage.py b/src/ethereum/forks/cancun/vm/instructions/storage.py index 084d58cc46c..8ad14c9dedd 100644 --- a/src/ethereum/forks/cancun/vm/instructions/storage.py +++ b/src/ethereum/forks/cancun/vm/instructions/storage.py @@ -20,17 +20,9 @@ set_storage, set_transient_storage, ) -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -50,10 +42,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -79,7 +71,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,35 +84,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -147,7 +143,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -174,7 +170,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/constantinople/vm/gas.py b/src/ethereum/forks/constantinople/vm/gas.py index 839cc3e3121..a6707988f46 100644 --- a/src/ethereum/forks/constantinople/vm/gas.py +++ b/src/ethereum/forks/constantinople/vm/gas.py @@ -65,6 +65,45 @@ GAS_CODE_HASH = Uint(400) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/constantinople/vm/instructions/arithmetic.py b/src/ethereum/forks/constantinople/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/constantinople/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/constantinople/vm/instructions/bitwise.py b/src/ethereum/forks/constantinople/vm/instructions/bitwise.py index 41dabe8185b..4e0a487a749 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/bitwise.py +++ b/src/ethereum/forks/constantinople/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/constantinople/vm/instructions/block.py b/src/ethereum/forks/constantinople/vm/instructions/block.py index 0edcbf000d1..2e6460a4f7d 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/block.py +++ b/src/ethereum/forks/constantinople/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/constantinople/vm/instructions/comparison.py b/src/ethereum/forks/constantinople/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/comparison.py +++ b/src/ethereum/forks/constantinople/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/constantinople/vm/instructions/control_flow.py b/src/ethereum/forks/constantinople/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/control_flow.py +++ b/src/ethereum/forks/constantinople/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/constantinople/vm/instructions/environment.py b/src/ethereum/forks/constantinople/vm/instructions/environment.py index d5572be1b4a..bcd2195bfdf 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/environment.py +++ b/src/ethereum/forks/constantinople/vm/instructions/environment.py @@ -19,7 +19,7 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BALANCE, @@ -28,7 +28,6 @@ GAS_COPY, GAS_EXTERNAL, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -169,7 +168,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -227,7 +226,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -285,7 +287,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -426,7 +431,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead diff --git a/src/ethereum/forks/constantinople/vm/instructions/keccak.py b/src/ethereum/forks/constantinople/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/keccak.py +++ b/src/ethereum/forks/constantinople/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/constantinople/vm/instructions/log.py b/src/ethereum/forks/constantinople/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/log.py +++ b/src/ethereum/forks/constantinople/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/constantinople/vm/instructions/memory.py b/src/ethereum/forks/constantinople/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/memory.py +++ b/src/ethereum/forks/constantinople/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/constantinople/vm/instructions/stack.py b/src/ethereum/forks/constantinople/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/stack.py +++ b/src/ethereum/forks/constantinople/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/constantinople/vm/instructions/storage.py b/src/ethereum/forks/constantinople/vm/instructions/storage.py index c62a67ae2d6..686420adcef 100644 --- a/src/ethereum/forks/constantinople/vm/instructions/storage.py +++ b/src/ethereum/forks/constantinople/vm/instructions/storage.py @@ -14,15 +14,9 @@ from ethereum_types.numeric import Uint from ...state import get_storage, set_storage -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext -from ..gas import ( - GAS_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -41,7 +35,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, gas.GAS_SLOAD) # OPERATION value = get_storage( @@ -72,12 +66,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = gas.GAS_STORAGE_SET else: - gas_cost = GAS_STORAGE_UPDATE + gas_cost = gas.GAS_STORAGE_UPDATE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) if evm.message.is_static: diff --git a/src/ethereum/forks/dao_fork/vm/gas.py b/src/ethereum/forks/dao_fork/vm/gas.py index 3c60482255b..687fae69ca8 100644 --- a/src/ethereum/forks/dao_fork/vm/gas.py +++ b/src/ethereum/forks/dao_fork/vm/gas.py @@ -63,6 +63,41 @@ GAS_IDENTITY_WORD = Uint(3) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/dao_fork/vm/instructions/arithmetic.py b/src/ethereum/forks/dao_fork/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/dao_fork/vm/instructions/bitwise.py b/src/ethereum/forks/dao_fork/vm/instructions/bitwise.py index 2a506f55751..476d71d7603 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/bitwise.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): diff --git a/src/ethereum/forks/dao_fork/vm/instructions/block.py b/src/ethereum/forks/dao_fork/vm/instructions/block.py index 0edcbf000d1..2e6460a4f7d 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/block.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/dao_fork/vm/instructions/comparison.py b/src/ethereum/forks/dao_fork/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/comparison.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/dao_fork/vm/instructions/control_flow.py b/src/ethereum/forks/dao_fork/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/control_flow.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/dao_fork/vm/instructions/environment.py b/src/ethereum/forks/dao_fork/vm/instructions/environment.py index 83eb5528226..a4cc54062b5 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/environment.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/environment.py @@ -18,13 +18,12 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BALANCE, GAS_BASE, GAS_COPY, GAS_EXTERNAL, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -165,7 +164,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -223,7 +222,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -281,7 +283,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/dao_fork/vm/instructions/keccak.py b/src/ethereum/forks/dao_fork/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/keccak.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/dao_fork/vm/instructions/log.py b/src/ethereum/forks/dao_fork/vm/instructions/log.py index 76c02e737a4..65d7658dcd8 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/log.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/log.py @@ -16,11 +16,8 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -58,9 +55,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/dao_fork/vm/instructions/memory.py b/src/ethereum/forks/dao_fork/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/memory.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/dao_fork/vm/instructions/stack.py b/src/ethereum/forks/dao_fork/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/stack.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/dao_fork/vm/instructions/storage.py b/src/ethereum/forks/dao_fork/vm/instructions/storage.py index 8748340fc27..dff35bd4fc9 100644 --- a/src/ethereum/forks/dao_fork/vm/instructions/storage.py +++ b/src/ethereum/forks/dao_fork/vm/instructions/storage.py @@ -14,14 +14,8 @@ from ethereum_types.numeric import Uint from ...state import get_storage, set_storage -from .. import Evm -from ..gas import ( - GAS_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +34,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, gas.GAS_SLOAD) # OPERATION value = get_storage( @@ -71,12 +65,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = gas.GAS_STORAGE_SET else: - gas_cost = GAS_STORAGE_UPDATE + gas_cost = gas.GAS_STORAGE_UPDATE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/frontier/vm/gas.py b/src/ethereum/forks/frontier/vm/gas.py index 3c60482255b..687fae69ca8 100644 --- a/src/ethereum/forks/frontier/vm/gas.py +++ b/src/ethereum/forks/frontier/vm/gas.py @@ -63,6 +63,41 @@ GAS_IDENTITY_WORD = Uint(3) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/frontier/vm/instructions/arithmetic.py b/src/ethereum/forks/frontier/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/frontier/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/frontier/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/frontier/vm/instructions/bitwise.py b/src/ethereum/forks/frontier/vm/instructions/bitwise.py index 2a506f55751..476d71d7603 100644 --- a/src/ethereum/forks/frontier/vm/instructions/bitwise.py +++ b/src/ethereum/forks/frontier/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): diff --git a/src/ethereum/forks/frontier/vm/instructions/block.py b/src/ethereum/forks/frontier/vm/instructions/block.py index 0edcbf000d1..2e6460a4f7d 100644 --- a/src/ethereum/forks/frontier/vm/instructions/block.py +++ b/src/ethereum/forks/frontier/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/frontier/vm/instructions/comparison.py b/src/ethereum/forks/frontier/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/frontier/vm/instructions/comparison.py +++ b/src/ethereum/forks/frontier/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/frontier/vm/instructions/control_flow.py b/src/ethereum/forks/frontier/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/frontier/vm/instructions/control_flow.py +++ b/src/ethereum/forks/frontier/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/frontier/vm/instructions/environment.py b/src/ethereum/forks/frontier/vm/instructions/environment.py index 83eb5528226..a4cc54062b5 100644 --- a/src/ethereum/forks/frontier/vm/instructions/environment.py +++ b/src/ethereum/forks/frontier/vm/instructions/environment.py @@ -18,13 +18,12 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BALANCE, GAS_BASE, GAS_COPY, GAS_EXTERNAL, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -165,7 +164,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -223,7 +222,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -281,7 +283,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/frontier/vm/instructions/keccak.py b/src/ethereum/forks/frontier/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/frontier/vm/instructions/keccak.py +++ b/src/ethereum/forks/frontier/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/frontier/vm/instructions/log.py b/src/ethereum/forks/frontier/vm/instructions/log.py index 76c02e737a4..65d7658dcd8 100644 --- a/src/ethereum/forks/frontier/vm/instructions/log.py +++ b/src/ethereum/forks/frontier/vm/instructions/log.py @@ -16,11 +16,8 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -58,9 +55,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/frontier/vm/instructions/memory.py b/src/ethereum/forks/frontier/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/frontier/vm/instructions/memory.py +++ b/src/ethereum/forks/frontier/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/frontier/vm/instructions/stack.py b/src/ethereum/forks/frontier/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/frontier/vm/instructions/stack.py +++ b/src/ethereum/forks/frontier/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/frontier/vm/instructions/storage.py b/src/ethereum/forks/frontier/vm/instructions/storage.py index 8748340fc27..dff35bd4fc9 100644 --- a/src/ethereum/forks/frontier/vm/instructions/storage.py +++ b/src/ethereum/forks/frontier/vm/instructions/storage.py @@ -14,14 +14,8 @@ from ethereum_types.numeric import Uint from ...state import get_storage, set_storage -from .. import Evm -from ..gas import ( - GAS_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +34,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, gas.GAS_SLOAD) # OPERATION value = get_storage( @@ -71,12 +65,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = gas.GAS_STORAGE_SET else: - gas_cost = GAS_STORAGE_UPDATE + gas_cost = gas.GAS_STORAGE_UPDATE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/gray_glacier/vm/gas.py b/src/ethereum/forks/gray_glacier/vm/gas.py index 1929dd5ca3b..c38b90d50d6 100644 --- a/src/ethereum/forks/gray_glacier/vm/gas.py +++ b/src/ethereum/forks/gray_glacier/vm/gas.py @@ -64,6 +64,45 @@ GAS_WARM_ACCESS = Uint(100) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/arithmetic.py b/src/ethereum/forks/gray_glacier/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/bitwise.py b/src/ethereum/forks/gray_glacier/vm/instructions/bitwise.py index 41dabe8185b..4e0a487a749 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/bitwise.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/block.py b/src/ethereum/forks/gray_glacier/vm/instructions/block.py index bbf01739ff2..24c154271d7 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/block.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -203,7 +203,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/comparison.py b/src/ethereum/forks/gray_glacier/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/comparison.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/control_flow.py b/src/ethereum/forks/gray_glacier/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/control_flow.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/environment.py b/src/ethereum/forks/gray_glacier/vm/instructions/environment.py index fe1b70c1269..31b236e66ca 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/environment.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/environment.py @@ -19,7 +19,7 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, @@ -27,7 +27,6 @@ GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_gas_extend_memory, charge_gas, @@ -173,7 +172,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -231,7 +230,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -289,7 +291,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -443,7 +448,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/keccak.py b/src/ethereum/forks/gray_glacier/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/keccak.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/log.py b/src/ethereum/forks/gray_glacier/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/log.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/memory.py b/src/ethereum/forks/gray_glacier/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/memory.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/stack.py b/src/ethereum/forks/gray_glacier/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/stack.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/gray_glacier/vm/instructions/storage.py b/src/ethereum/forks/gray_glacier/vm/instructions/storage.py index 6129ed5322c..93134c1b42b 100644 --- a/src/ethereum/forks/gray_glacier/vm/instructions/storage.py +++ b/src/ethereum/forks/gray_glacier/vm/instructions/storage.py @@ -14,17 +14,9 @@ from ethereum_types.numeric import Uint from ...state import get_storage, get_storage_original, set_storage -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -44,10 +36,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -73,7 +65,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -86,35 +78,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/homestead/vm/gas.py b/src/ethereum/forks/homestead/vm/gas.py index 3c60482255b..687fae69ca8 100644 --- a/src/ethereum/forks/homestead/vm/gas.py +++ b/src/ethereum/forks/homestead/vm/gas.py @@ -63,6 +63,41 @@ GAS_IDENTITY_WORD = Uint(3) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/homestead/vm/instructions/arithmetic.py b/src/ethereum/forks/homestead/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/homestead/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/homestead/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/homestead/vm/instructions/bitwise.py b/src/ethereum/forks/homestead/vm/instructions/bitwise.py index 2a506f55751..476d71d7603 100644 --- a/src/ethereum/forks/homestead/vm/instructions/bitwise.py +++ b/src/ethereum/forks/homestead/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): diff --git a/src/ethereum/forks/homestead/vm/instructions/block.py b/src/ethereum/forks/homestead/vm/instructions/block.py index 0edcbf000d1..2e6460a4f7d 100644 --- a/src/ethereum/forks/homestead/vm/instructions/block.py +++ b/src/ethereum/forks/homestead/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/homestead/vm/instructions/comparison.py b/src/ethereum/forks/homestead/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/homestead/vm/instructions/comparison.py +++ b/src/ethereum/forks/homestead/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/homestead/vm/instructions/control_flow.py b/src/ethereum/forks/homestead/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/homestead/vm/instructions/control_flow.py +++ b/src/ethereum/forks/homestead/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/homestead/vm/instructions/environment.py b/src/ethereum/forks/homestead/vm/instructions/environment.py index 83eb5528226..a4cc54062b5 100644 --- a/src/ethereum/forks/homestead/vm/instructions/environment.py +++ b/src/ethereum/forks/homestead/vm/instructions/environment.py @@ -18,13 +18,12 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BALANCE, GAS_BASE, GAS_COPY, GAS_EXTERNAL, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -165,7 +164,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -223,7 +222,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -281,7 +283,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/homestead/vm/instructions/keccak.py b/src/ethereum/forks/homestead/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/homestead/vm/instructions/keccak.py +++ b/src/ethereum/forks/homestead/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/homestead/vm/instructions/log.py b/src/ethereum/forks/homestead/vm/instructions/log.py index 76c02e737a4..65d7658dcd8 100644 --- a/src/ethereum/forks/homestead/vm/instructions/log.py +++ b/src/ethereum/forks/homestead/vm/instructions/log.py @@ -16,11 +16,8 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -58,9 +55,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/homestead/vm/instructions/memory.py b/src/ethereum/forks/homestead/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/homestead/vm/instructions/memory.py +++ b/src/ethereum/forks/homestead/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/homestead/vm/instructions/stack.py b/src/ethereum/forks/homestead/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/homestead/vm/instructions/stack.py +++ b/src/ethereum/forks/homestead/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/homestead/vm/instructions/storage.py b/src/ethereum/forks/homestead/vm/instructions/storage.py index 8748340fc27..dff35bd4fc9 100644 --- a/src/ethereum/forks/homestead/vm/instructions/storage.py +++ b/src/ethereum/forks/homestead/vm/instructions/storage.py @@ -14,14 +14,8 @@ from ethereum_types.numeric import Uint from ...state import get_storage, set_storage -from .. import Evm -from ..gas import ( - GAS_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +34,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, gas.GAS_SLOAD) # OPERATION value = get_storage( @@ -71,12 +65,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = gas.GAS_STORAGE_SET else: - gas_cost = GAS_STORAGE_UPDATE + gas_cost = gas.GAS_STORAGE_UPDATE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/istanbul/vm/gas.py b/src/ethereum/forks/istanbul/vm/gas.py index eb56b502d0a..a6f37ee39ab 100644 --- a/src/ethereum/forks/istanbul/vm/gas.py +++ b/src/ethereum/forks/istanbul/vm/gas.py @@ -67,6 +67,45 @@ GAS_BLAKE2_PER_ROUND = Uint(1) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/istanbul/vm/instructions/arithmetic.py b/src/ethereum/forks/istanbul/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/istanbul/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/istanbul/vm/instructions/bitwise.py b/src/ethereum/forks/istanbul/vm/instructions/bitwise.py index 41dabe8185b..4e0a487a749 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/bitwise.py +++ b/src/ethereum/forks/istanbul/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/istanbul/vm/instructions/block.py b/src/ethereum/forks/istanbul/vm/instructions/block.py index bbf01739ff2..24c154271d7 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/block.py +++ b/src/ethereum/forks/istanbul/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -203,7 +203,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/istanbul/vm/instructions/comparison.py b/src/ethereum/forks/istanbul/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/comparison.py +++ b/src/ethereum/forks/istanbul/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/istanbul/vm/instructions/control_flow.py b/src/ethereum/forks/istanbul/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/control_flow.py +++ b/src/ethereum/forks/istanbul/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/istanbul/vm/instructions/environment.py b/src/ethereum/forks/istanbul/vm/instructions/environment.py index f0cc93e67d8..9e720ab49c1 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/environment.py +++ b/src/ethereum/forks/istanbul/vm/instructions/environment.py @@ -19,7 +19,7 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BALANCE, @@ -29,7 +29,6 @@ GAS_EXTERNAL, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -170,7 +169,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -228,7 +227,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -286,7 +288,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -427,7 +432,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead diff --git a/src/ethereum/forks/istanbul/vm/instructions/keccak.py b/src/ethereum/forks/istanbul/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/keccak.py +++ b/src/ethereum/forks/istanbul/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/istanbul/vm/instructions/log.py b/src/ethereum/forks/istanbul/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/log.py +++ b/src/ethereum/forks/istanbul/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/istanbul/vm/instructions/memory.py b/src/ethereum/forks/istanbul/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/memory.py +++ b/src/ethereum/forks/istanbul/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/istanbul/vm/instructions/stack.py b/src/ethereum/forks/istanbul/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/stack.py +++ b/src/ethereum/forks/istanbul/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/istanbul/vm/instructions/storage.py b/src/ethereum/forks/istanbul/vm/instructions/storage.py index 9150b8cb578..97a5992c310 100644 --- a/src/ethereum/forks/istanbul/vm/instructions/storage.py +++ b/src/ethereum/forks/istanbul/vm/instructions/storage.py @@ -14,16 +14,9 @@ from ethereum_types.numeric import Uint from ...state import get_storage, get_storage_original, set_storage -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -42,7 +35,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, gas.GAS_SLOAD) # OPERATION value = get_storage( @@ -68,7 +61,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -79,30 +72,32 @@ def sstore(evm: Evm) -> None: if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = gas.GAS_STORAGE_SET else: - gas_cost = GAS_STORAGE_UPDATE + gas_cost = gas.GAS_STORAGE_UPDATE else: - gas_cost = GAS_SLOAD + gas_cost = gas.GAS_SLOAD # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_SLOAD) + evm.refund_counter += int(gas.GAS_STORAGE_SET - gas.GAS_SLOAD) else: # Slot was originally non-empty and was UPDATED earlier - evm.refund_counter += int(GAS_STORAGE_UPDATE - GAS_SLOAD) + evm.refund_counter += int( + gas.GAS_STORAGE_UPDATE - gas.GAS_SLOAD + ) charge_gas(evm, gas_cost) if evm.message.is_static: diff --git a/src/ethereum/forks/london/vm/gas.py b/src/ethereum/forks/london/vm/gas.py index 1929dd5ca3b..c38b90d50d6 100644 --- a/src/ethereum/forks/london/vm/gas.py +++ b/src/ethereum/forks/london/vm/gas.py @@ -64,6 +64,45 @@ GAS_WARM_ACCESS = Uint(100) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/london/vm/instructions/arithmetic.py b/src/ethereum/forks/london/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/london/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/london/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/london/vm/instructions/bitwise.py b/src/ethereum/forks/london/vm/instructions/bitwise.py index 41dabe8185b..4e0a487a749 100644 --- a/src/ethereum/forks/london/vm/instructions/bitwise.py +++ b/src/ethereum/forks/london/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/london/vm/instructions/block.py b/src/ethereum/forks/london/vm/instructions/block.py index bbf01739ff2..24c154271d7 100644 --- a/src/ethereum/forks/london/vm/instructions/block.py +++ b/src/ethereum/forks/london/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -203,7 +203,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/london/vm/instructions/comparison.py b/src/ethereum/forks/london/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/london/vm/instructions/comparison.py +++ b/src/ethereum/forks/london/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/london/vm/instructions/control_flow.py b/src/ethereum/forks/london/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/london/vm/instructions/control_flow.py +++ b/src/ethereum/forks/london/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/london/vm/instructions/environment.py b/src/ethereum/forks/london/vm/instructions/environment.py index fe1b70c1269..31b236e66ca 100644 --- a/src/ethereum/forks/london/vm/instructions/environment.py +++ b/src/ethereum/forks/london/vm/instructions/environment.py @@ -19,7 +19,7 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, @@ -27,7 +27,6 @@ GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_gas_extend_memory, charge_gas, @@ -173,7 +172,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -231,7 +230,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -289,7 +291,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -443,7 +448,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead diff --git a/src/ethereum/forks/london/vm/instructions/keccak.py b/src/ethereum/forks/london/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/london/vm/instructions/keccak.py +++ b/src/ethereum/forks/london/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/london/vm/instructions/log.py b/src/ethereum/forks/london/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/london/vm/instructions/log.py +++ b/src/ethereum/forks/london/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/london/vm/instructions/memory.py b/src/ethereum/forks/london/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/london/vm/instructions/memory.py +++ b/src/ethereum/forks/london/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/london/vm/instructions/stack.py b/src/ethereum/forks/london/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/london/vm/instructions/stack.py +++ b/src/ethereum/forks/london/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/london/vm/instructions/storage.py b/src/ethereum/forks/london/vm/instructions/storage.py index 6129ed5322c..93134c1b42b 100644 --- a/src/ethereum/forks/london/vm/instructions/storage.py +++ b/src/ethereum/forks/london/vm/instructions/storage.py @@ -14,17 +14,9 @@ from ethereum_types.numeric import Uint from ...state import get_storage, get_storage_original, set_storage -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -44,10 +36,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -73,7 +65,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -86,35 +78,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/muir_glacier/vm/gas.py b/src/ethereum/forks/muir_glacier/vm/gas.py index eb56b502d0a..a6f37ee39ab 100644 --- a/src/ethereum/forks/muir_glacier/vm/gas.py +++ b/src/ethereum/forks/muir_glacier/vm/gas.py @@ -67,6 +67,45 @@ GAS_BLAKE2_PER_ROUND = Uint(1) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/arithmetic.py b/src/ethereum/forks/muir_glacier/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/bitwise.py b/src/ethereum/forks/muir_glacier/vm/instructions/bitwise.py index 41dabe8185b..4e0a487a749 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/bitwise.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/block.py b/src/ethereum/forks/muir_glacier/vm/instructions/block.py index bbf01739ff2..24c154271d7 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/block.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -203,7 +203,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/comparison.py b/src/ethereum/forks/muir_glacier/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/comparison.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/control_flow.py b/src/ethereum/forks/muir_glacier/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/control_flow.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/environment.py b/src/ethereum/forks/muir_glacier/vm/instructions/environment.py index f0cc93e67d8..9e720ab49c1 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/environment.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/environment.py @@ -19,7 +19,7 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BALANCE, @@ -29,7 +29,6 @@ GAS_EXTERNAL, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -170,7 +169,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -228,7 +227,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -286,7 +288,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -427,7 +432,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/keccak.py b/src/ethereum/forks/muir_glacier/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/keccak.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/log.py b/src/ethereum/forks/muir_glacier/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/log.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/memory.py b/src/ethereum/forks/muir_glacier/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/memory.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/stack.py b/src/ethereum/forks/muir_glacier/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/stack.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/muir_glacier/vm/instructions/storage.py b/src/ethereum/forks/muir_glacier/vm/instructions/storage.py index 9150b8cb578..97a5992c310 100644 --- a/src/ethereum/forks/muir_glacier/vm/instructions/storage.py +++ b/src/ethereum/forks/muir_glacier/vm/instructions/storage.py @@ -14,16 +14,9 @@ from ethereum_types.numeric import Uint from ...state import get_storage, get_storage_original, set_storage -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -42,7 +35,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, gas.GAS_SLOAD) # OPERATION value = get_storage( @@ -68,7 +61,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -79,30 +72,32 @@ def sstore(evm: Evm) -> None: if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = gas.GAS_STORAGE_SET else: - gas_cost = GAS_STORAGE_UPDATE + gas_cost = gas.GAS_STORAGE_UPDATE else: - gas_cost = GAS_SLOAD + gas_cost = gas.GAS_SLOAD # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_SLOAD) + evm.refund_counter += int(gas.GAS_STORAGE_SET - gas.GAS_SLOAD) else: # Slot was originally non-empty and was UPDATED earlier - evm.refund_counter += int(GAS_STORAGE_UPDATE - GAS_SLOAD) + evm.refund_counter += int( + gas.GAS_STORAGE_UPDATE - gas.GAS_SLOAD + ) charge_gas(evm, gas_cost) if evm.message.is_static: diff --git a/src/ethereum/forks/osaka/vm/gas.py b/src/ethereum/forks/osaka/vm/gas.py index 5108bf63a7d..32673fe71b3 100644 --- a/src/ethereum/forks/osaka/vm/gas.py +++ b/src/ethereum/forks/osaka/vm/gas.py @@ -66,7 +66,7 @@ GAS_COLD_ACCOUNT_ACCESS = Uint(2600) GAS_WARM_ACCESS = Uint(100) GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) +GAS_BLOBHASH = Uint(3) GAS_POINT_EVALUATION = Uint(50000) GAS_PER_BLOB = U64(2**17) @@ -84,6 +84,46 @@ GAS_BLS_G2_MUL = Uint(22500) GAS_BLS_G2_MAP = Uint(23800) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_CLZ = GAS_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_MCOPY = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + @dataclass class ExtendMemory: diff --git a/src/ethereum/forks/osaka/vm/instructions/arithmetic.py b/src/ethereum/forks/osaka/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/osaka/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/osaka/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/osaka/vm/instructions/bitwise.py b/src/ethereum/forks/osaka/vm/instructions/bitwise.py index cc6fa2fbb23..3cb188b8579 100644 --- a/src/ethereum/forks/osaka/vm/instructions/bitwise.py +++ b/src/ethereum/forks/osaka/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_LOW, GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: @@ -262,7 +264,7 @@ def count_leading_zeros(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_CLZ) # OPERATION bit_length = U256(x.bit_length()) diff --git a/src/ethereum/forks/osaka/vm/instructions/block.py b/src/ethereum/forks/osaka/vm/instructions/block.py index 43be9e58e23..f7180611357 100644 --- a/src/ethereum/forks/osaka/vm/instructions/block.py +++ b/src/ethereum/forks/osaka/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/osaka/vm/instructions/comparison.py b/src/ethereum/forks/osaka/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/osaka/vm/instructions/comparison.py +++ b/src/ethereum/forks/osaka/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/osaka/vm/instructions/control_flow.py b/src/ethereum/forks/osaka/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/osaka/vm/instructions/control_flow.py +++ b/src/ethereum/forks/osaka/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/osaka/vm/instructions/environment.py b/src/ethereum/forks/osaka/vm/instructions/environment.py index 5848530a960..936297a73a6 100644 --- a/src/ethereum/forks/osaka/vm/instructions/environment.py +++ b/src/ethereum/forks/osaka/vm/instructions/environment.py @@ -20,16 +20,15 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, - GAS_BLOBHASH_OPCODE, + GAS_BLOBHASH, GAS_COLD_ACCOUNT_ACCESS, GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_blob_gas_price, calculate_gas_extend_memory, @@ -176,7 +175,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -234,7 +233,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -292,7 +294,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -446,7 +451,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -561,7 +569,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GAS_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): diff --git a/src/ethereum/forks/osaka/vm/instructions/keccak.py b/src/ethereum/forks/osaka/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/osaka/vm/instructions/keccak.py +++ b/src/ethereum/forks/osaka/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/osaka/vm/instructions/log.py b/src/ethereum/forks/osaka/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/osaka/vm/instructions/log.py +++ b/src/ethereum/forks/osaka/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/osaka/vm/instructions/memory.py b/src/ethereum/forks/osaka/vm/instructions/memory.py index 6e111051ee3..bccc5fd6f01 100644 --- a/src/ethereum/forks/osaka/vm/instructions/memory.py +++ b/src/ethereum/forks/osaka/vm/instructions/memory.py @@ -16,11 +16,10 @@ from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, GAS_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +48,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +79,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +107,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -166,7 +165,10 @@ def mcopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_MCOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/osaka/vm/instructions/stack.py b/src/ethereum/forks/osaka/vm/instructions/stack.py index 0007a28acd4..3aaadbf69ab 100644 --- a/src/ethereum/forks/osaka/vm/instructions/stack.py +++ b/src/ethereum/forks/osaka/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -65,7 +68,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: if num_bytes == 0: charge_gas(evm, GAS_BASE) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/osaka/vm/instructions/storage.py b/src/ethereum/forks/osaka/vm/instructions/storage.py index 084d58cc46c..8ad14c9dedd 100644 --- a/src/ethereum/forks/osaka/vm/instructions/storage.py +++ b/src/ethereum/forks/osaka/vm/instructions/storage.py @@ -20,17 +20,9 @@ set_storage, set_transient_storage, ) -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -50,10 +42,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -79,7 +71,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,35 +84,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -147,7 +143,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -174,7 +170,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/paris/vm/gas.py b/src/ethereum/forks/paris/vm/gas.py index 1929dd5ca3b..c38b90d50d6 100644 --- a/src/ethereum/forks/paris/vm/gas.py +++ b/src/ethereum/forks/paris/vm/gas.py @@ -64,6 +64,45 @@ GAS_WARM_ACCESS = Uint(100) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/paris/vm/instructions/arithmetic.py b/src/ethereum/forks/paris/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/paris/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/paris/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/paris/vm/instructions/bitwise.py b/src/ethereum/forks/paris/vm/instructions/bitwise.py index 41dabe8185b..4e0a487a749 100644 --- a/src/ethereum/forks/paris/vm/instructions/bitwise.py +++ b/src/ethereum/forks/paris/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/paris/vm/instructions/block.py b/src/ethereum/forks/paris/vm/instructions/block.py index 3aa1fb2f6b6..e1a9734341f 100644 --- a/src/ethereum/forks/paris/vm/instructions/block.py +++ b/src/ethereum/forks/paris/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/paris/vm/instructions/comparison.py b/src/ethereum/forks/paris/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/paris/vm/instructions/comparison.py +++ b/src/ethereum/forks/paris/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/paris/vm/instructions/control_flow.py b/src/ethereum/forks/paris/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/paris/vm/instructions/control_flow.py +++ b/src/ethereum/forks/paris/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/paris/vm/instructions/environment.py b/src/ethereum/forks/paris/vm/instructions/environment.py index ba2bb42a425..54bac51928d 100644 --- a/src/ethereum/forks/paris/vm/instructions/environment.py +++ b/src/ethereum/forks/paris/vm/instructions/environment.py @@ -19,7 +19,7 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, @@ -27,7 +27,6 @@ GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_gas_extend_memory, charge_gas, @@ -173,7 +172,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -231,7 +230,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -289,7 +291,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -443,7 +448,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead diff --git a/src/ethereum/forks/paris/vm/instructions/keccak.py b/src/ethereum/forks/paris/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/paris/vm/instructions/keccak.py +++ b/src/ethereum/forks/paris/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/paris/vm/instructions/log.py b/src/ethereum/forks/paris/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/paris/vm/instructions/log.py +++ b/src/ethereum/forks/paris/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/paris/vm/instructions/memory.py b/src/ethereum/forks/paris/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/paris/vm/instructions/memory.py +++ b/src/ethereum/forks/paris/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/paris/vm/instructions/stack.py b/src/ethereum/forks/paris/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/paris/vm/instructions/stack.py +++ b/src/ethereum/forks/paris/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/paris/vm/instructions/storage.py b/src/ethereum/forks/paris/vm/instructions/storage.py index 6129ed5322c..93134c1b42b 100644 --- a/src/ethereum/forks/paris/vm/instructions/storage.py +++ b/src/ethereum/forks/paris/vm/instructions/storage.py @@ -14,17 +14,9 @@ from ethereum_types.numeric import Uint from ...state import get_storage, get_storage_original, set_storage -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -44,10 +36,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -73,7 +65,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -86,35 +78,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/prague/vm/gas.py b/src/ethereum/forks/prague/vm/gas.py index ed1f651e23c..51ed3ee2d29 100644 --- a/src/ethereum/forks/prague/vm/gas.py +++ b/src/ethereum/forks/prague/vm/gas.py @@ -65,7 +65,7 @@ GAS_COLD_ACCOUNT_ACCESS = Uint(2600) GAS_WARM_ACCESS = Uint(100) GAS_CODE_INIT_PER_WORD = Uint(2) -GAS_BLOBHASH_OPCODE = Uint(3) +GAS_BLOBHASH = Uint(3) GAS_POINT_EVALUATION = Uint(50000) GAS_PER_BLOB = U64(2**17) @@ -81,6 +81,46 @@ GAS_BLS_G2_MAP = Uint(23800) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_MCOPY = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/prague/vm/instructions/arithmetic.py b/src/ethereum/forks/prague/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/prague/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/prague/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/prague/vm/instructions/bitwise.py b/src/ethereum/forks/prague/vm/instructions/bitwise.py index 41dabe8185b..4e0a487a749 100644 --- a/src/ethereum/forks/prague/vm/instructions/bitwise.py +++ b/src/ethereum/forks/prague/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/prague/vm/instructions/block.py b/src/ethereum/forks/prague/vm/instructions/block.py index b3bfb500a09..6d911057db4 100644 --- a/src/ethereum/forks/prague/vm/instructions/block.py +++ b/src/ethereum/forks/prague/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/prague/vm/instructions/comparison.py b/src/ethereum/forks/prague/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/prague/vm/instructions/comparison.py +++ b/src/ethereum/forks/prague/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/prague/vm/instructions/control_flow.py b/src/ethereum/forks/prague/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/prague/vm/instructions/control_flow.py +++ b/src/ethereum/forks/prague/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/prague/vm/instructions/environment.py b/src/ethereum/forks/prague/vm/instructions/environment.py index 5848530a960..936297a73a6 100644 --- a/src/ethereum/forks/prague/vm/instructions/environment.py +++ b/src/ethereum/forks/prague/vm/instructions/environment.py @@ -20,16 +20,15 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, - GAS_BLOBHASH_OPCODE, + GAS_BLOBHASH, GAS_COLD_ACCOUNT_ACCESS, GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_blob_gas_price, calculate_gas_extend_memory, @@ -176,7 +175,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -234,7 +233,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -292,7 +294,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -446,7 +451,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead @@ -561,7 +569,7 @@ def blob_hash(evm: Evm) -> None: index = pop(evm.stack) # GAS - charge_gas(evm, GAS_BLOBHASH_OPCODE) + charge_gas(evm, GAS_BLOBHASH) # OPERATION if int(index) < len(evm.message.tx_env.blob_versioned_hashes): diff --git a/src/ethereum/forks/prague/vm/instructions/keccak.py b/src/ethereum/forks/prague/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/prague/vm/instructions/keccak.py +++ b/src/ethereum/forks/prague/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/prague/vm/instructions/log.py b/src/ethereum/forks/prague/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/prague/vm/instructions/log.py +++ b/src/ethereum/forks/prague/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/prague/vm/instructions/memory.py b/src/ethereum/forks/prague/vm/instructions/memory.py index 6e111051ee3..bccc5fd6f01 100644 --- a/src/ethereum/forks/prague/vm/instructions/memory.py +++ b/src/ethereum/forks/prague/vm/instructions/memory.py @@ -16,11 +16,10 @@ from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, GAS_COPY, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -49,7 +48,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -80,7 +79,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -108,7 +107,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -166,7 +165,10 @@ def mcopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(source, length), (destination, length)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_MCOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/prague/vm/instructions/stack.py b/src/ethereum/forks/prague/vm/instructions/stack.py index 0007a28acd4..3aaadbf69ab 100644 --- a/src/ethereum/forks/prague/vm/instructions/stack.py +++ b/src/ethereum/forks/prague/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -65,7 +68,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: if num_bytes == 0: charge_gas(evm, GAS_BASE) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/prague/vm/instructions/storage.py b/src/ethereum/forks/prague/vm/instructions/storage.py index 084d58cc46c..8ad14c9dedd 100644 --- a/src/ethereum/forks/prague/vm/instructions/storage.py +++ b/src/ethereum/forks/prague/vm/instructions/storage.py @@ -20,17 +20,9 @@ set_storage, set_transient_storage, ) -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -50,10 +42,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -79,7 +71,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -92,35 +84,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) @@ -147,7 +143,7 @@ def tload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) # OPERATION value = get_transient_storage( @@ -174,7 +170,7 @@ def tstore(evm: Evm) -> None: new_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) if evm.message.is_static: raise WriteInStaticContext set_transient_storage( diff --git a/src/ethereum/forks/shanghai/vm/gas.py b/src/ethereum/forks/shanghai/vm/gas.py index bd3ea9ec341..8b695d5d05a 100644 --- a/src/ethereum/forks/shanghai/vm/gas.py +++ b/src/ethereum/forks/shanghai/vm/gas.py @@ -65,6 +65,45 @@ GAS_CODE_INIT_PER_WORD = Uint(2) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_SHL = GAS_VERY_LOW +GAS_OPCODE_SHR = GAS_VERY_LOW +GAS_OPCODE_SAR = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_RETURNDATACOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/shanghai/vm/instructions/arithmetic.py b/src/ethereum/forks/shanghai/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/shanghai/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/shanghai/vm/instructions/bitwise.py b/src/ethereum/forks/shanghai/vm/instructions/bitwise.py index 41dabe8185b..4e0a487a749 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/bitwise.py +++ b/src/ethereum/forks/shanghai/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): @@ -169,7 +171,7 @@ def bitwise_shl(evm: Evm) -> None: value = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHL) # OPERATION if shift < Uint(256): @@ -199,7 +201,7 @@ def bitwise_shr(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SHR) # OPERATION if shift < U256(256): @@ -229,7 +231,7 @@ def bitwise_sar(evm: Evm) -> None: signed_value = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SAR) # OPERATION if shift < 256: diff --git a/src/ethereum/forks/shanghai/vm/instructions/block.py b/src/ethereum/forks/shanghai/vm/instructions/block.py index de2569869bd..d351673e1dc 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/block.py +++ b/src/ethereum/forks/shanghai/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +40,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -89,7 +89,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -123,7 +123,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -156,7 +156,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -189,7 +189,7 @@ def prev_randao(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.prev_randao)) @@ -222,7 +222,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) @@ -252,7 +252,7 @@ def chain_id(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.chain_id)) diff --git a/src/ethereum/forks/shanghai/vm/instructions/comparison.py b/src/ethereum/forks/shanghai/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/comparison.py +++ b/src/ethereum/forks/shanghai/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/shanghai/vm/instructions/control_flow.py b/src/ethereum/forks/shanghai/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/control_flow.py +++ b/src/ethereum/forks/shanghai/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/shanghai/vm/instructions/environment.py b/src/ethereum/forks/shanghai/vm/instructions/environment.py index ba2bb42a425..54bac51928d 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/environment.py +++ b/src/ethereum/forks/shanghai/vm/instructions/environment.py @@ -19,7 +19,7 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfBoundsRead from ..gas import ( GAS_BASE, @@ -27,7 +27,6 @@ GAS_COPY, GAS_FAST_STEP, GAS_RETURN_DATA_COPY, - GAS_VERY_LOW, GAS_WARM_ACCESS, calculate_gas_extend_memory, charge_gas, @@ -173,7 +172,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -231,7 +230,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -289,7 +291,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -443,7 +448,10 @@ def returndatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_RETURNDATACOPY + copy_gas_cost + extend_memory.cost, + ) if Uint(return_data_start_position) + Uint(size) > ulen(evm.return_data): raise OutOfBoundsRead diff --git a/src/ethereum/forks/shanghai/vm/instructions/keccak.py b/src/ethereum/forks/shanghai/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/keccak.py +++ b/src/ethereum/forks/shanghai/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/shanghai/vm/instructions/log.py b/src/ethereum/forks/shanghai/vm/instructions/log.py index abc297df6fa..c96061d15b1 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/log.py +++ b/src/ethereum/forks/shanghai/vm/instructions/log.py @@ -16,12 +16,9 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..exceptions import WriteInStaticContext from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -59,9 +56,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/shanghai/vm/instructions/memory.py b/src/ethereum/forks/shanghai/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/memory.py +++ b/src/ethereum/forks/shanghai/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/shanghai/vm/instructions/stack.py b/src/ethereum/forks/shanghai/vm/instructions/stack.py index 0007a28acd4..3aaadbf69ab 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/stack.py +++ b/src/ethereum/forks/shanghai/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -65,7 +68,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: if num_bytes == 0: charge_gas(evm, GAS_BASE) else: - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -95,7 +98,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -127,7 +130,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/shanghai/vm/instructions/storage.py b/src/ethereum/forks/shanghai/vm/instructions/storage.py index 6129ed5322c..93134c1b42b 100644 --- a/src/ethereum/forks/shanghai/vm/instructions/storage.py +++ b/src/ethereum/forks/shanghai/vm/instructions/storage.py @@ -14,17 +14,9 @@ from ethereum_types.numeric import Uint from ...state import get_storage, get_storage_original, set_storage -from .. import Evm +from .. import Evm, gas from ..exceptions import OutOfGasError, WriteInStaticContext -from ..gas import ( - GAS_CALL_STIPEND, - GAS_COLD_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - GAS_WARM_ACCESS, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from ..gas import charge_gas from ..stack import pop, push @@ -44,10 +36,10 @@ def sload(evm: Evm) -> None: # GAS if (evm.message.current_target, key) in evm.accessed_storage_keys: - charge_gas(evm, GAS_WARM_ACCESS) + charge_gas(evm, gas.GAS_WARM_ACCESS) else: evm.accessed_storage_keys.add((evm.message.current_target, key)) - charge_gas(evm, GAS_COLD_SLOAD) + charge_gas(evm, gas.GAS_COLD_SLOAD) # OPERATION value = get_storage( @@ -73,7 +65,7 @@ def sstore(evm: Evm) -> None: # STACK key = pop(evm.stack).to_be_bytes32() new_value = pop(evm.stack) - if evm.gas_left <= GAS_CALL_STIPEND: + if evm.gas_left <= gas.GAS_CALL_STIPEND: raise OutOfGasError state = evm.message.block_env.state @@ -86,35 +78,39 @@ def sstore(evm: Evm) -> None: if (evm.message.current_target, key) not in evm.accessed_storage_keys: evm.accessed_storage_keys.add((evm.message.current_target, key)) - gas_cost += GAS_COLD_SLOAD + gas_cost += gas.GAS_COLD_SLOAD if original_value == current_value and current_value != new_value: if original_value == 0: - gas_cost += GAS_STORAGE_SET + gas_cost += gas.GAS_STORAGE_SET else: - gas_cost += GAS_STORAGE_UPDATE - GAS_COLD_SLOAD + gas_cost += gas.GAS_STORAGE_UPDATE - gas.GAS_COLD_SLOAD else: - gas_cost += GAS_WARM_ACCESS + gas_cost += gas.GAS_WARM_ACCESS # Refund Counter Calculation if current_value != new_value: if original_value != 0 and current_value != 0 and new_value == 0: # Storage is cleared for the first time in the transaction - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR if original_value != 0 and current_value == 0: # Gas refund issued earlier to be reversed - evm.refund_counter -= REFUND_STORAGE_CLEAR + evm.refund_counter -= gas.REFUND_STORAGE_CLEAR if original_value == new_value: # Storage slot being restored to its original value if original_value == 0: # Slot was originally empty and was SET earlier - evm.refund_counter += int(GAS_STORAGE_SET - GAS_WARM_ACCESS) + evm.refund_counter += int( + gas.GAS_STORAGE_SET - gas.GAS_WARM_ACCESS + ) else: # Slot was originally non-empty and was UPDATED earlier evm.refund_counter += int( - GAS_STORAGE_UPDATE - GAS_COLD_SLOAD - GAS_WARM_ACCESS + gas.GAS_STORAGE_UPDATE + - gas.GAS_COLD_SLOAD + - gas.GAS_WARM_ACCESS ) charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/spurious_dragon/vm/gas.py b/src/ethereum/forks/spurious_dragon/vm/gas.py index 7f9fe700db3..8799d3ee595 100644 --- a/src/ethereum/forks/spurious_dragon/vm/gas.py +++ b/src/ethereum/forks/spurious_dragon/vm/gas.py @@ -63,6 +63,41 @@ GAS_IDENTITY_WORD = Uint(3) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/arithmetic.py b/src/ethereum/forks/spurious_dragon/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/bitwise.py b/src/ethereum/forks/spurious_dragon/vm/instructions/bitwise.py index 2a506f55751..476d71d7603 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/bitwise.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/block.py b/src/ethereum/forks/spurious_dragon/vm/instructions/block.py index 0edcbf000d1..2e6460a4f7d 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/block.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/comparison.py b/src/ethereum/forks/spurious_dragon/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/comparison.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/control_flow.py b/src/ethereum/forks/spurious_dragon/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/control_flow.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/environment.py b/src/ethereum/forks/spurious_dragon/vm/instructions/environment.py index 83eb5528226..a4cc54062b5 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/environment.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/environment.py @@ -18,13 +18,12 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BALANCE, GAS_BASE, GAS_COPY, GAS_EXTERNAL, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -165,7 +164,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -223,7 +222,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -281,7 +283,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/keccak.py b/src/ethereum/forks/spurious_dragon/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/keccak.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/log.py b/src/ethereum/forks/spurious_dragon/vm/instructions/log.py index 76c02e737a4..65d7658dcd8 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/log.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/log.py @@ -16,11 +16,8 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -58,9 +55,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/memory.py b/src/ethereum/forks/spurious_dragon/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/memory.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/stack.py b/src/ethereum/forks/spurious_dragon/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/stack.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/spurious_dragon/vm/instructions/storage.py b/src/ethereum/forks/spurious_dragon/vm/instructions/storage.py index 8748340fc27..dff35bd4fc9 100644 --- a/src/ethereum/forks/spurious_dragon/vm/instructions/storage.py +++ b/src/ethereum/forks/spurious_dragon/vm/instructions/storage.py @@ -14,14 +14,8 @@ from ethereum_types.numeric import Uint from ...state import get_storage, set_storage -from .. import Evm -from ..gas import ( - GAS_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +34,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, gas.GAS_SLOAD) # OPERATION value = get_storage( @@ -71,12 +65,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = gas.GAS_STORAGE_SET else: - gas_cost = GAS_STORAGE_UPDATE + gas_cost = gas.GAS_STORAGE_UPDATE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost) diff --git a/src/ethereum/forks/tangerine_whistle/vm/gas.py b/src/ethereum/forks/tangerine_whistle/vm/gas.py index ac02500d623..8d8f4ab57a6 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/gas.py +++ b/src/ethereum/forks/tangerine_whistle/vm/gas.py @@ -63,6 +63,41 @@ GAS_IDENTITY_WORD = Uint(3) +# Opcode specific vars used for repricing +GAS_OPCODE_ADD = GAS_VERY_LOW +GAS_OPCODE_SUB = GAS_VERY_LOW +GAS_OPCODE_MUL = GAS_LOW +GAS_OPCODE_DIV = GAS_LOW +GAS_OPCODE_SDIV = GAS_LOW +GAS_OPCODE_MOD = GAS_LOW +GAS_OPCODE_SMOD = GAS_LOW +GAS_OPCODE_ADDMOD = GAS_MID +GAS_OPCODE_MULMOD = GAS_MID +GAS_OPCODE_SIGNEXTEND = GAS_LOW +GAS_OPCODE_LT = GAS_VERY_LOW +GAS_OPCODE_GT = GAS_VERY_LOW +GAS_OPCODE_SLT = GAS_VERY_LOW +GAS_OPCODE_SGT = GAS_VERY_LOW +GAS_OPCODE_EQ = GAS_VERY_LOW +GAS_OPCODE_ISZERO = GAS_VERY_LOW +GAS_OPCODE_AND = GAS_VERY_LOW +GAS_OPCODE_OR = GAS_VERY_LOW +GAS_OPCODE_XOR = GAS_VERY_LOW +GAS_OPCODE_NOT = GAS_VERY_LOW +GAS_OPCODE_BYTE = GAS_VERY_LOW +GAS_OPCODE_JUMP = GAS_MID +GAS_OPCODE_JUMPI = GAS_HIGH +GAS_OPCODE_CALLDATALOAD = GAS_VERY_LOW +GAS_OPCODE_CALLDATACOPY = GAS_VERY_LOW +GAS_OPCODE_CODECOPY = GAS_VERY_LOW +GAS_OPCODE_MLOAD = GAS_VERY_LOW +GAS_OPCODE_MSTORE = GAS_VERY_LOW +GAS_OPCODE_MSTORE8 = GAS_VERY_LOW +GAS_OPCODE_PUSH_N = GAS_VERY_LOW +GAS_OPCODE_DUP_N = GAS_VERY_LOW +GAS_OPCODE_SWAP_N = GAS_VERY_LOW + + @dataclass class ExtendMemory: """ diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/arithmetic.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/arithmetic.py index b7b1a370ad4..e1bf43acdad 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/arithmetic.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/arithmetic.py @@ -16,13 +16,10 @@ from ethereum.utils.numeric import get_sign -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_EXPONENTIATION, GAS_EXPONENTIATION_PER_BYTE, - GAS_LOW, - GAS_MID, - GAS_VERY_LOW, charge_gas, ) from ..stack import pop, push @@ -44,7 +41,7 @@ def add(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ADD) # OPERATION result = x.wrapping_add(y) @@ -71,7 +68,7 @@ def sub(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SUB) # OPERATION result = x.wrapping_sub(y) @@ -98,7 +95,7 @@ def mul(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MUL) # OPERATION result = x.wrapping_mul(y) @@ -125,7 +122,7 @@ def div(evm: Evm) -> None: divisor = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_DIV) # OPERATION if divisor == 0: @@ -158,7 +155,7 @@ def sdiv(evm: Evm) -> None: divisor = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SDIV) # OPERATION if divisor == 0: @@ -191,7 +188,7 @@ def mod(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_MOD) # OPERATION if y == 0: @@ -221,7 +218,7 @@ def smod(evm: Evm) -> None: y = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SMOD) # OPERATION if y == 0: @@ -252,7 +249,7 @@ def addmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_ADDMOD) # OPERATION if z == 0: @@ -283,7 +280,7 @@ def mulmod(evm: Evm) -> None: z = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_MULMOD) # OPERATION if z == 0: @@ -346,7 +343,7 @@ def signextend(evm: Evm) -> None: value = pop(evm.stack) # GAS - charge_gas(evm, GAS_LOW) + charge_gas(evm, gas.GAS_OPCODE_SIGNEXTEND) # OPERATION if byte_num > U256(31): diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/bitwise.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/bitwise.py index 2a506f55751..476d71d7603 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/bitwise.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/bitwise.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def bitwise_and(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_AND) # OPERATION push(evm.stack, x & y) @@ -59,7 +61,7 @@ def bitwise_or(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_OR) # OPERATION push(evm.stack, x | y) @@ -84,7 +86,7 @@ def bitwise_xor(evm: Evm) -> None: y = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_XOR) # OPERATION push(evm.stack, x ^ y) @@ -108,7 +110,7 @@ def bitwise_not(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_NOT) # OPERATION push(evm.stack, ~x) @@ -134,7 +136,7 @@ def get_byte(evm: Evm) -> None: word = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_BYTE) # OPERATION if byte_index >= U256(32): diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/block.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/block.py index 0edcbf000d1..2e6460a4f7d 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/block.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/block.py @@ -13,8 +13,8 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_BASE, GAS_BLOCK_HASH, charge_gas +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -33,7 +33,7 @@ def block_hash(evm: Evm) -> None: block_number = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_BLOCK_HASH) + charge_gas(evm, gas.GAS_BLOCK_HASH) # OPERATION max_block_number = block_number + Uint(256) @@ -75,7 +75,7 @@ def coinbase(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256.from_be_bytes(evm.message.block_env.coinbase)) @@ -102,7 +102,7 @@ def timestamp(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, evm.message.block_env.time) @@ -128,7 +128,7 @@ def number(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.number)) @@ -154,7 +154,7 @@ def difficulty(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.difficulty)) @@ -180,7 +180,7 @@ def gas_limit(evm: Evm) -> None: pass # GAS - charge_gas(evm, GAS_BASE) + charge_gas(evm, gas.GAS_BASE) # OPERATION push(evm.stack, U256(evm.message.block_env.block_gas_limit)) diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/comparison.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/comparison.py index a6a3d99bc86..f30d048f94f 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/comparison.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/comparison.py @@ -13,8 +13,10 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm -from ..gas import GAS_VERY_LOW, charge_gas +from .. import Evm, gas +from ..gas import ( + charge_gas, +) from ..stack import pop, push @@ -34,7 +36,7 @@ def less_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_LT) # OPERATION result = U256(left < right) @@ -60,7 +62,7 @@ def signed_less_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SLT) # OPERATION result = U256(left < right) @@ -87,7 +89,7 @@ def greater_than(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_GT) # OPERATION result = U256(left > right) @@ -113,7 +115,7 @@ def signed_greater_than(evm: Evm) -> None: right = pop(evm.stack).to_signed() # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SGT) # OPERATION result = U256(left > right) @@ -140,7 +142,7 @@ def equal(evm: Evm) -> None: right = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_EQ) # OPERATION result = U256(left == right) @@ -166,7 +168,7 @@ def is_zero(evm: Evm) -> None: x = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_ISZERO) # OPERATION result = U256(x == 0) diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/control_flow.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/control_flow.py index b3b1f2316a7..fabe929c4ce 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/control_flow.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/control_flow.py @@ -13,7 +13,12 @@ from ethereum_types.numeric import U256, Uint -from ...vm.gas import GAS_BASE, GAS_HIGH, GAS_JUMPDEST, GAS_MID, charge_gas +from ...vm import gas +from ...vm.gas import ( + GAS_BASE, + GAS_JUMPDEST, + charge_gas, +) from .. import Evm from ..exceptions import InvalidJumpDestError from ..stack import pop, push @@ -57,7 +62,7 @@ def jump(evm: Evm) -> None: jump_dest = Uint(pop(evm.stack)) # GAS - charge_gas(evm, GAS_MID) + charge_gas(evm, gas.GAS_OPCODE_JUMP) # OPERATION if jump_dest not in evm.valid_jump_destinations: @@ -84,7 +89,7 @@ def jumpi(evm: Evm) -> None: conditional_value = pop(evm.stack) # GAS - charge_gas(evm, GAS_HIGH) + charge_gas(evm, gas.GAS_OPCODE_JUMPI) # OPERATION if conditional_value == 0: diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/environment.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/environment.py index 83eb5528226..a4cc54062b5 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/environment.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/environment.py @@ -18,13 +18,12 @@ from ...state import get_account, get_code from ...utils.address import to_address_masked from ...vm.memory import buffer_read, memory_write -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BALANCE, GAS_BASE, GAS_COPY, GAS_EXTERNAL, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -165,7 +164,7 @@ def calldataload(evm: Evm) -> None: start_index = pop(evm.stack) # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_CALLDATALOAD) # OPERATION value = buffer_read(evm.message.data, start_index, U256(32)) @@ -223,7 +222,10 @@ def calldatacopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CALLDATACOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -281,7 +283,10 @@ def codecopy(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_VERY_LOW + copy_gas_cost + extend_memory.cost) + charge_gas( + evm, + gas.GAS_OPCODE_CODECOPY + copy_gas_cost + extend_memory.cost, + ) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/keccak.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/keccak.py index 8661c5d62f5..0f171699824 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/keccak.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/keccak.py @@ -16,10 +16,8 @@ from ethereum.crypto.hash import keccak256 from ethereum.utils.numeric import ceil32 -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_KECCAK256, - GAS_KECCAK256_PER_WORD, calculate_gas_extend_memory, charge_gas, ) @@ -46,11 +44,11 @@ def keccak(evm: Evm) -> None: # GAS words = ceil32(Uint(size)) // Uint(32) - word_gas_cost = GAS_KECCAK256_PER_WORD * words + word_gas_cost = gas.GAS_KECCAK256_PER_WORD * words extend_memory = calculate_gas_extend_memory( evm.memory, [(memory_start_index, size)] ) - charge_gas(evm, GAS_KECCAK256 + word_gas_cost + extend_memory.cost) + charge_gas(evm, gas.GAS_KECCAK256 + word_gas_cost + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/log.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/log.py index 76c02e737a4..65d7658dcd8 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/log.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/log.py @@ -16,11 +16,8 @@ from ethereum_types.numeric import Uint from ...blocks import Log -from .. import Evm +from .. import Evm, gas from ..gas import ( - GAS_LOG, - GAS_LOG_DATA_PER_BYTE, - GAS_LOG_TOPIC, calculate_gas_extend_memory, charge_gas, ) @@ -58,9 +55,9 @@ def log_n(evm: Evm, num_topics: int) -> None: ) charge_gas( evm, - GAS_LOG - + GAS_LOG_DATA_PER_BYTE * Uint(size) - + GAS_LOG_TOPIC * Uint(num_topics) + gas.GAS_LOG + + gas.GAS_LOG_DATA_PER_BYTE * Uint(size) + + gas.GAS_LOG_TOPIC * Uint(num_topics) + extend_memory.cost, ) diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/memory.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/memory.py index 3a242ba2f7a..90b2f06a271 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/memory.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/memory.py @@ -14,10 +14,9 @@ from ethereum_types.bytes import Bytes from ethereum_types.numeric import U256, Uint -from .. import Evm +from .. import Evm, gas from ..gas import ( GAS_BASE, - GAS_VERY_LOW, calculate_gas_extend_memory, charge_gas, ) @@ -46,7 +45,7 @@ def mstore(evm: Evm) -> None: evm.memory, [(start_position, U256(len(value)))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -77,7 +76,7 @@ def mstore8(evm: Evm) -> None: evm.memory, [(start_position, U256(1))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MSTORE8 + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by @@ -105,7 +104,7 @@ def mload(evm: Evm) -> None: extend_memory = calculate_gas_extend_memory( evm.memory, [(start_position, U256(32))] ) - charge_gas(evm, GAS_VERY_LOW + extend_memory.cost) + charge_gas(evm, gas.GAS_OPCODE_MLOAD + extend_memory.cost) # OPERATION evm.memory += b"\x00" * extend_memory.expand_by diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/stack.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/stack.py index 0fc0d3fe4b5..e102cc1a2c9 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/stack.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/stack.py @@ -15,9 +15,12 @@ from ethereum_types.numeric import U256, Uint -from .. import Evm, stack +from .. import Evm, gas, stack from ..exceptions import StackUnderflowError -from ..gas import GAS_BASE, GAS_VERY_LOW, charge_gas +from ..gas import ( + GAS_BASE, + charge_gas, +) from ..memory import buffer_read @@ -62,7 +65,7 @@ def push_n(evm: Evm, num_bytes: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_PUSH_N) # OPERATION data_to_push = U256.from_be_bytes( @@ -92,7 +95,7 @@ def dup_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_DUP_N) if item_number >= len(evm.stack): raise StackUnderflowError data_to_duplicate = evm.stack[len(evm.stack) - 1 - item_number] @@ -124,7 +127,7 @@ def swap_n(evm: Evm, item_number: int) -> None: pass # GAS - charge_gas(evm, GAS_VERY_LOW) + charge_gas(evm, gas.GAS_OPCODE_SWAP_N) if item_number >= len(evm.stack): raise StackUnderflowError evm.stack[-1], evm.stack[-1 - item_number] = ( diff --git a/src/ethereum/forks/tangerine_whistle/vm/instructions/storage.py b/src/ethereum/forks/tangerine_whistle/vm/instructions/storage.py index 8748340fc27..dff35bd4fc9 100644 --- a/src/ethereum/forks/tangerine_whistle/vm/instructions/storage.py +++ b/src/ethereum/forks/tangerine_whistle/vm/instructions/storage.py @@ -14,14 +14,8 @@ from ethereum_types.numeric import Uint from ...state import get_storage, set_storage -from .. import Evm -from ..gas import ( - GAS_SLOAD, - GAS_STORAGE_SET, - GAS_STORAGE_UPDATE, - REFUND_STORAGE_CLEAR, - charge_gas, -) +from .. import Evm, gas +from ..gas import charge_gas from ..stack import pop, push @@ -40,7 +34,7 @@ def sload(evm: Evm) -> None: key = pop(evm.stack).to_be_bytes32() # GAS - charge_gas(evm, GAS_SLOAD) + charge_gas(evm, gas.GAS_SLOAD) # OPERATION value = get_storage( @@ -71,12 +65,12 @@ def sstore(evm: Evm) -> None: state = evm.message.block_env.state current_value = get_storage(state, evm.message.current_target, key) if new_value != 0 and current_value == 0: - gas_cost = GAS_STORAGE_SET + gas_cost = gas.GAS_STORAGE_SET else: - gas_cost = GAS_STORAGE_UPDATE + gas_cost = gas.GAS_STORAGE_UPDATE if new_value == 0 and current_value != 0: - evm.refund_counter += REFUND_STORAGE_CLEAR + evm.refund_counter += gas.REFUND_STORAGE_CLEAR charge_gas(evm, gas_cost)