diff --git a/tests/cancun/eip1153_tstore/test_basic_tload.py b/tests/cancun/eip1153_tstore/test_basic_tload.py index 70ca6685536..6cd9eddd647 100644 --- a/tests/cancun/eip1153_tstore/test_basic_tload.py +++ b/tests/cancun/eip1153_tstore/test_basic_tload.py @@ -11,12 +11,13 @@ Address, Alloc, Environment, + Fork, Op, StateTestFiller, Transaction, ) -from .spec import Spec, ref_spec_1153 +from .spec import ref_spec_1153 REFERENCE_SPEC_GIT_PATH = ref_spec_1153.git_path REFERENCE_SPEC_VERSION = ref_spec_1153.version @@ -195,6 +196,7 @@ def test_basic_tload_other_after_tstore( def test_basic_tload_gasprice( state_test: StateTestFiller, pre: Alloc, + fork: Fork, ) -> None: """ Ported .json vectors. @@ -261,8 +263,8 @@ def test_basic_tload_gasprice( post = { address_to: Account( storage={ - slot_tload_nonzero_gas_price_result: Spec.TLOAD_GAS_COST, - slot_tload_zero_gas_price_result: Spec.TLOAD_GAS_COST, + slot_tload_nonzero_gas_price_result: Op.TLOAD.gas_cost(fork), + slot_tload_zero_gas_price_result: Op.TLOAD.gas_cost(fork), slot_code_worked: 0x01, } ) diff --git a/tests/cancun/eip1153_tstore/test_tstorage.py b/tests/cancun/eip1153_tstore/test_tstorage.py index c77e6ba6389..2f5db226390 100644 --- a/tests/cancun/eip1153_tstore/test_tstorage.py +++ b/tests/cancun/eip1153_tstore/test_tstorage.py @@ -21,7 +21,7 @@ ) from . import PytestParameterEnum -from .spec import Spec, ref_spec_1153 +from .spec import ref_spec_1153 REFERENCE_SPEC_GIT_PATH = ref_spec_1153.git_path REFERENCE_SPEC_VERSION = ref_spec_1153.version @@ -217,33 +217,25 @@ class GasMeasureTestCases(PytestParameterEnum): "description": "Test that tload() of an empty slot consumes " "the expected gas.", "bytecode": Op.TLOAD(10), - "overhead_cost": 3, # 1 x PUSH1 "extra_stack_items": 1, - "expected_gas": Spec.TLOAD_GAS_COST, } TSTORE_TLOAD = { "description": "Test that tload() of a used slot consumes " "the expected gas.", "bytecode": Op.TSTORE(10, 10) + Op.TLOAD(10), - "overhead_cost": 3 * 3, # 3 x PUSH1 "extra_stack_items": 1, - "expected_gas": Spec.TSTORE_GAS_COST + Spec.TLOAD_GAS_COST, } TSTORE_COLD = { "description": "Test that tstore() of a previously unused " "slot consumes the expected gas.", "bytecode": Op.TSTORE(10, 10), - "overhead_cost": 2 * 3, # 2 x PUSH1 "extra_stack_items": 0, - "expected_gas": Spec.TSTORE_GAS_COST, } TSTORE_WARM = { "description": "Test that tstore() of a previously used slot " "consumes the expected gas.", "bytecode": Op.TSTORE(10, 10) + Op.TSTORE(10, 11), - "overhead_cost": 4 * 3, # 4 x PUSH1 "extra_stack_items": 0, - "expected_gas": 2 * Spec.TSTORE_GAS_COST, } @@ -251,15 +243,14 @@ class GasMeasureTestCases(PytestParameterEnum): def test_gas_usage( state_test: StateTestFiller, pre: Alloc, + fork: Fork, bytecode: Bytecode, - expected_gas: int, - overhead_cost: int, extra_stack_items: int, ) -> None: """Test that tstore and tload consume the expected gas.""" + expected_gas = bytecode.gas_cost(fork) gas_measure_bytecode = CodeGasMeasure( code=bytecode, - overhead_cost=overhead_cost, extra_stack_items=extra_stack_items, ) diff --git a/tests/cancun/eip1153_tstore/test_tstorage_execution_contexts.py b/tests/cancun/eip1153_tstore/test_tstorage_execution_contexts.py index 59c77782396..f35a2ed53fa 100644 --- a/tests/cancun/eip1153_tstore/test_tstorage_execution_contexts.py +++ b/tests/cancun/eip1153_tstore/test_tstorage_execution_contexts.py @@ -3,7 +3,7 @@ """ from enum import EnumMeta, unique -from typing import Any, Dict, Mapping +from typing import Any, Callable, Dict, Mapping import pytest from execution_testing import ( @@ -12,6 +12,7 @@ Alloc, Bytecode, Environment, + Fork, Hash, Op, StateTestFiller, @@ -19,15 +20,13 @@ ) from . import PytestParameterEnum -from .spec import Spec, ref_spec_1153 +from .spec import ref_spec_1153 REFERENCE_SPEC_GIT_PATH = ref_spec_1153.git_path REFERENCE_SPEC_VERSION = ref_spec_1153.version pytestmark = [pytest.mark.valid_from("Cancun")] -PUSH_OPCODE_COST = 3 - class DynamicCallContextTestCases(EnumMeta): """ @@ -186,25 +185,30 @@ def __new__( # noqa: D102 "expected_callee_storage": {}, } - gas_limit = Spec.TSTORE_GAS_COST + (PUSH_OPCODE_COST * 2) - 1 - contract_call = call_opcode( - gas=gas_limit, address=Op.CALLDATALOAD(0) - ) + callee_bytecode = Op.TSTORE(1, 69) + Op.STOP classdict[f"{call_opcode._name_}_WITH_OUT_OF_GAS"] = { "description": ( "Transient storage usage is discarded from sub-call with " f"{call_opcode._name_} upon out of gas during TSTORE. " "Note: Gas passed to sub-call is capped." ), - "caller_bytecode": ( + "caller_bytecode": lambda fork, + call_opcode=call_opcode, + callee_bytecode=callee_bytecode: ( Op.TSTORE(0, 420) + Op.TSTORE(1, 420) - + Op.SSTORE(0, contract_call) + + Op.SSTORE( + 0, + call_opcode( + gas=callee_bytecode.gas_cost(fork) - 1, + address=Op.CALLDATALOAD(0), + ), + ) + Op.SSTORE(1, Op.TLOAD(0)) + Op.SSTORE(2, Op.TLOAD(1)) + Op.STOP ), - "callee_bytecode": Op.TSTORE(1, 69) + Op.STOP, + "callee_bytecode": callee_bytecode, "expected_caller_storage": {0: 0, 1: 420, 2: 420}, "expected_callee_storage": {}, } @@ -320,8 +324,15 @@ def __init__(self, value: dict[str, Any]) -> None: @pytest.fixture() -def caller_address(pre: Alloc, caller_bytecode: Bytecode) -> Address: +def caller_address( + pre: Alloc, + fork: Fork, + caller_bytecode: Bytecode | Callable[[Fork], Bytecode], +) -> Address: """Address used to call the test bytecode on every test case.""" + if not isinstance(caller_bytecode, Bytecode): + assert callable(caller_bytecode) + caller_bytecode = caller_bytecode(fork) return pre.deploy_contract(caller_bytecode) diff --git a/tests/cancun/eip4844_blobs/test_blobhash_opcode.py b/tests/cancun/eip4844_blobs/test_blobhash_opcode.py index 6cc1c55a113..20404301577 100644 --- a/tests/cancun/eip4844_blobs/test_blobhash_opcode.py +++ b/tests/cancun/eip4844_blobs/test_blobhash_opcode.py @@ -188,9 +188,9 @@ def test_blobhash_gas_cost( ensuring it matches `HASH_OPCODE_GAS = 3`. Includes both valid and invalid random index sizes from the range `[0, 2**256-1]`, for tx types 2 and 3. """ + blobhash_code = Op.BLOBHASH(blobhash_index) gas_measure_code = CodeGasMeasure( - code=Op.BLOBHASH(blobhash_index), - overhead_cost=3, + code=blobhash_code, extra_stack_items=1, ) @@ -223,7 +223,7 @@ def test_blobhash_gas_cost( ] tx = Transaction(**tx_kwargs) - post = {address: Account(storage={0: Spec.HASH_GAS_COST})} + post = {address: Account(storage={0: blobhash_code.gas_cost(fork)})} state_test( env=Environment(), diff --git a/tests/cancun/eip7516_blobgasfee/test_blobgasfee_opcode.py b/tests/cancun/eip7516_blobgasfee/test_blobgasfee_opcode.py index d053c964424..ca483e637da 100644 --- a/tests/cancun/eip7516_blobgasfee/test_blobgasfee_opcode.py +++ b/tests/cancun/eip7516_blobgasfee/test_blobgasfee_opcode.py @@ -15,6 +15,7 @@ BlockchainTestFiller, Bytecode, Environment, + Fork, Op, StateTestFiller, Storage, @@ -24,8 +25,6 @@ REFERENCE_SPEC_GIT_PATH = "EIPS/eip-7516.md" REFERENCE_SPEC_VERSION = "dcd2f4ede58a6ed908acd3cc2c198e9f605cbf3b" -BLOBBASEFEE_GAS = 2 - @pytest.fixture def call_gas() -> int: @@ -127,22 +126,39 @@ def test_blobbasefee_stack_overflow( @pytest.mark.parametrize( - "call_gas,call_fails", + "call_fails", [ - pytest.param(BLOBBASEFEE_GAS, False, id="enough_gas"), - pytest.param(BLOBBASEFEE_GAS - 1, True, id="out_of_gas"), + pytest.param(False, id="enough_gas"), + pytest.param(True, id="out_of_gas"), ], ) @pytest.mark.valid_from("Cancun") def test_blobbasefee_out_of_gas( state_test: StateTestFiller, pre: Alloc, - caller_address: Address, - callee_address: Address, - tx: Transaction, + fork: Fork, call_fails: bool, ) -> None: """Tests that the BLOBBASEFEE opcode fails with insufficient gas.""" + blobbasefee_gas = Op.BLOBBASEFEE.gas_cost(fork) + call_gas = blobbasefee_gas - 1 if call_fails else blobbasefee_gas + + callee_code = Op.BLOBBASEFEE + Op.STOP + callee_address = pre.deploy_contract(callee_code) + + caller_code = Op.SSTORE( + Op.SELFBALANCE, + Op.CALL(gas=call_gas, address=callee_address), + ) + caller_address = pre.deploy_contract(caller_code) + + tx = Transaction( + sender=pre.fund_eoa(), + gas_limit=1_000_000, + to=caller_address, + value=1, + ) + post = { caller_address: Account( storage={1: 0 if call_fails else 1}, diff --git a/tests/osaka/eip7823_modexp_upper_bounds/conftest.py b/tests/osaka/eip7823_modexp_upper_bounds/conftest.py index f9528d8e92a..461537c9049 100644 --- a/tests/osaka/eip7823_modexp_upper_bounds/conftest.py +++ b/tests/osaka/eip7823_modexp_upper_bounds/conftest.py @@ -87,12 +87,18 @@ def gas_measure_contract( 0, ) - gas_costs = fork.gas_costs() extra_gas = ( - gas_costs.G_WARM_ACCOUNT_ACCESS - + (gas_costs.G_VERY_LOW * (len(Op.CALL.kwargs) - 1)) - + gas_costs.G_BASE # CALLDATASIZE - + gas_costs.G_BASE # GAS + Op.CALL( + precompile_gas, + Spec.MODEXP_ADDRESS, + 0, + 0, + Op.CALLDATASIZE(), + 0, + 0, + address_warm=True, + ).gas_cost(fork) + + Op.GAS.gas_cost(fork) # second GAS in measurement ) # Build the gas measurement contract code diff --git a/tests/osaka/eip7825_transaction_gas_limit_cap/test_tx_gas_limit.py b/tests/osaka/eip7825_transaction_gas_limit_cap/test_tx_gas_limit.py index 8e8f8d01ce5..91ec1afa83d 100644 --- a/tests/osaka/eip7825_transaction_gas_limit_cap/test_tx_gas_limit.py +++ b/tests/osaka/eip7825_transaction_gas_limit_cap/test_tx_gas_limit.py @@ -254,8 +254,10 @@ def test_maximum_gas_refund( # Base Operation: SSTORE(slot, 0) iteration_cost = ( - gas_costs.G_STORAGE_RESET + gas_costs.G_BASE + gas_costs.G_VERY_LOW - ) + Op.SSTORE(key_warm=True, original_value=1, new_value=0) + + Op.PUSH0 + + Op.PUSH1(0) + ).gas_cost(fork) gas_refund = gas_costs.R_STORAGE_CLEAR # EIP-3529: Reduction in refunds diff --git a/tests/osaka/eip7883_modexp_gas_increase/conftest.py b/tests/osaka/eip7883_modexp_gas_increase/conftest.py index b686cb1f43a..a94e3aa7252 100644 --- a/tests/osaka/eip7883_modexp_gas_increase/conftest.py +++ b/tests/osaka/eip7883_modexp_gas_increase/conftest.py @@ -61,9 +61,7 @@ def total_tx_gas_needed( ) memory_expansion_gas_calculator = fork.memory_expansion_gas_calculator() # `gas_measure_contract` does at most 4 SSTOREs to cold slots. - sstore_gas = ( - fork.gas_costs().G_STORAGE_SET + fork.gas_costs().G_COLD_SLOAD - ) * 4 + sstore_gas = Op.SSTORE(key_warm=False).gas_cost(fork) * 4 # Ensures that the precompile call is not starved by the 63/64 rule. precompile_gas_with_margin = precompile_gas * 64 // 63 extra_gas = 100_000 @@ -157,12 +155,18 @@ def gas_measure_contract( 0, ) - gas_costs = fork.gas_costs() extra_gas = ( - gas_costs.G_WARM_ACCOUNT_ACCESS - + (gas_costs.G_VERY_LOW * (len(call_opcode.kwargs) - 1)) - + gas_costs.G_BASE # CALLDATASIZE - + gas_costs.G_BASE # GAS + call_opcode( + gas_used, + Spec.MODEXP_ADDRESS, + *value, + 0, + Op.CALLDATASIZE(), + 0, + 0, + address_warm=True, + ).gas_cost(fork) + + Op.GAS.gas_cost(fork) # second GAS in measurement ) # Build the gas measurement contract code diff --git a/tests/osaka/eip7883_modexp_gas_increase/test_modexp_thresholds_transition.py b/tests/osaka/eip7883_modexp_gas_increase/test_modexp_thresholds_transition.py index 128d1306a74..f0e87e4cbc1 100644 --- a/tests/osaka/eip7883_modexp_gas_increase/test_modexp_thresholds_transition.py +++ b/tests/osaka/eip7883_modexp_gas_increase/test_modexp_thresholds_transition.py @@ -55,11 +55,13 @@ def test_modexp_fork_transition( args_size=Op.CALLDATASIZE, ) - gas_costs = fork.gas_costs() extra_gas = ( - gas_costs.G_WARM_ACCOUNT_ACCESS - + (gas_costs.G_VERY_LOW * (len(Op.CALL.kwargs) - 2)) - + (gas_costs.G_BASE * 3) + Op.CALL( + address=Spec.MODEXP_ADDRESS, + args_size=Op.CALLDATASIZE, + address_warm=True, + ).gas_cost(fork) + + Op.GAS.gas_cost(fork) # second GAS in measurement ) code = ( Op.CALLDATACOPY(dest_offset=0, offset=0, size=Op.CALLDATASIZE) diff --git a/tests/prague/eip7623_increase_calldata_cost/test_refunds.py b/tests/prague/eip7623_increase_calldata_cost/test_refunds.py index 5d11c57cf4a..fd1c3c952da 100644 --- a/tests/prague/eip7623_increase_calldata_cost/test_refunds.py +++ b/tests/prague/eip7623_increase_calldata_cost/test_refunds.py @@ -111,12 +111,14 @@ def prefix_code_gas(fork: Fork, refund_type: RefundType) -> int: """Return the minimum execution gas cost due to the refund type.""" if RefundType.STORAGE_CLEAR in refund_type: # Minimum code to generate a storage clear is Op.SSTORE(0, 0). - gas_costs = fork.gas_costs() return ( - gas_costs.G_COLD_SLOAD - + gas_costs.G_STORAGE_RESET - + (gas_costs.G_VERY_LOW * 2) - ) + Op.SSTORE( + key_warm=False, + original_value=1, + new_value=0, + ) + + Op.PUSH1(0) * 2 + ).gas_cost(fork) return 0 diff --git a/tests/prague/eip7702_set_code_tx/test_eip_mainnet.py b/tests/prague/eip7702_set_code_tx/test_eip_mainnet.py index 6470700815b..8702fd15149 100644 --- a/tests/prague/eip7702_set_code_tx/test_eip_mainnet.py +++ b/tests/prague/eip7702_set_code_tx/test_eip_mainnet.py @@ -50,17 +50,18 @@ def test_eip_7702( signer=auth_signer, ), ] - gas_costs = fork.gas_costs() intrinsic_gas_cost_calc = fork.transaction_intrinsic_cost_calculator() intrinsic_gas_cost = intrinsic_gas_cost_calc( access_list=[], authorization_list_or_count=authorization_list, ) execution_cost = ( - (gas_costs.G_COLD_SLOAD + gas_costs.G_STORAGE_SET) * 3 - + (gas_costs.G_VERY_LOW * 3) - + (gas_costs.G_BASE * 3) - ) + Op.SSTORE(key_warm=False) * 3 + + Op.PUSH1(0) * 3 + + Op.ORIGIN + + Op.CALLER + + Op.CALLVALUE + ).gas_cost(fork) tx = Transaction( gas_limit=intrinsic_gas_cost + execution_cost, diff --git a/tests/prague/eip7702_set_code_tx/test_gas.py b/tests/prague/eip7702_set_code_tx/test_gas.py index eb694b93535..ff3c3b93eba 100644 --- a/tests/prague/eip7702_set_code_tx/test_gas.py +++ b/tests/prague/eip7702_set_code_tx/test_gas.py @@ -883,20 +883,14 @@ def test_gas_cost( # SSTORE opcodes in order to make sure that the refund is less than one # fifth (EIP-3529) of the total gas used, so we can see the full discount # being reflected in most of the tests. - gas_costs = fork.gas_costs() - gas_opcode_cost = gas_costs.G_BASE + gas_opcode_cost = Op.GAS.gas_cost(fork) sstore_opcode_count = 10 push_opcode_count = (2 * (sstore_opcode_count)) - 1 - push_opcode_cost = gas_costs.G_VERY_LOW * push_opcode_count - sstore_opcode_cost = gas_costs.G_STORAGE_SET * sstore_opcode_count - cold_storage_cost = gas_costs.G_COLD_SLOAD * sstore_opcode_count - execution_gas = ( - gas_opcode_cost - + push_opcode_cost - + sstore_opcode_cost - + cold_storage_cost - ) + Op.GAS + + Op.PUSH1(0) * push_opcode_count + + Op.SSTORE(key_warm=False) * sstore_opcode_count + ).gas_cost(fork) # The first opcode that executes in the code is the GAS opcode, which costs # 2 gas, so we subtract that from the expected gas measure. @@ -1245,21 +1239,20 @@ def test_call_to_pre_authorized_oog( # Callee tries to call the auth_signer which delegates # to the delegation contract. The call instruction should out-of-gas # because of the addition cost of the delegation account access. - callee_code = Bytecode( - Op.SSTORE(0, call_opcode(gas=0, address=auth_signer)), - ) + callee_code = Op.SSTORE(0, call_opcode(gas=0, address=auth_signer)) callee_storage = Storage() callee_storage[0] = 0xFF # Value other than 0 or 1. Should not be changed. callee_address = pre.deploy_contract(callee_code, storage=callee_storage) - gas_costs = fork.gas_costs() intrinsic_gas_cost_calculator = ( fork.transaction_intrinsic_cost_calculator() ) tx_gas_limit = ( intrinsic_gas_cost_calculator() - + len(call_opcode.kwargs) * gas_costs.G_VERY_LOW - + (gas_costs.G_COLD_ACCOUNT_ACCESS * 2) + + ( + Op.PUSH1(0) * len(call_opcode.kwargs) + + call_opcode(address_warm=False, delegated_address=True) + ).gas_cost(fork) - 1 ) tx = Transaction( diff --git a/tests/prague/eip7702_set_code_tx/test_set_code_txs.py b/tests/prague/eip7702_set_code_tx/test_set_code_txs.py index 647b39ed8b3..d9275f4ea46 100644 --- a/tests/prague/eip7702_set_code_tx/test_set_code_txs.py +++ b/tests/prague/eip7702_set_code_tx/test_set_code_txs.py @@ -676,12 +676,9 @@ def test_delegated_eoa_can_send_creating_tx( ) assert initcode_len == len(initcode) - gas_costs = fork.gas_costs() - tx = Transaction( ty=tx_type, - gas_limit=200_000 - + (gas_costs.G_STORAGE_SET + gas_costs.G_COLD_SLOAD) * 7, + gas_limit=200_000 + (Op.SSTORE(key_warm=False) * 7).gas_cost(fork), to=None, value=0, data=initcode, diff --git a/tests/prague/eip7702_set_code_tx/test_set_code_txs_2.py b/tests/prague/eip7702_set_code_tx/test_set_code_txs_2.py index eca78f7e571..988dbf868bc 100644 --- a/tests/prague/eip7702_set_code_tx/test_set_code_txs_2.py +++ b/tests/prague/eip7702_set_code_tx/test_set_code_txs_2.py @@ -18,7 +18,6 @@ Conditional, Environment, Fork, - GasCosts, Hash, Macros, Op, @@ -697,85 +696,60 @@ def test_gas_diff_pointer_vs_direct_call( sender = pre.fund_eoa() pointer_a = pre.fund_eoa() call_worked = 1 - gas_costs: GasCosts = fork.gas_costs() - + # The contract code is: + # Op.SSTORE(call_worked, Op.ADD(Op.SLOAD(call_worked), 1)) + # The opcodes_price captures the remaining push/add overhead. opcodes_price = 37 + + direct_account_warm = access_list_rule in [ + AccessListCall.IN_NORMAL_TX_ONLY, + AccessListCall.IN_BOTH_TX, + ] + direct_storage_warm = direct_account_warm direct_call_gas: int = ( - # 20_000 + 2_600 + 2_100 + 37 = 24737 - gas_costs.G_STORAGE_SET - + ( - # access account price - # If storage and account is declared in access list then discount - gas_costs.G_WARM_ACCOUNT_ACCESS + gas_costs.G_WARM_SLOAD - if access_list_rule - in [AccessListCall.IN_NORMAL_TX_ONLY, AccessListCall.IN_BOTH_TX] - else gas_costs.G_COLD_ACCOUNT_ACCESS + gas_costs.G_COLD_SLOAD - ) + Op.SSTORE(key_warm=True).gas_cost(fork) # key warmed by prior SLOAD + + Op.CALL(address_warm=direct_account_warm).gas_cost(fork) + + Op.SLOAD(key_warm=direct_storage_warm).gas_cost(fork) + opcodes_price ) + pointer_account_warm = ( + pointer_definition + in [ + PointerDefinition.IN_BOTH_TX, + PointerDefinition.IN_POINTER_TX_ONLY, + ] + or access_list_rule + in [ + AccessListCall.IN_BOTH_TX, + AccessListCall.IN_POINTER_TX_ONLY, + ] + and access_list_to == AccessListTo.POINTER_ADDRESS + ) + pointer_storage_warm = ( + access_list_rule + in [ + AccessListCall.IN_BOTH_TX, + AccessListCall.IN_POINTER_TX_ONLY, + ] + and access_list_to == AccessListTo.POINTER_ADDRESS + ) + pointer_contract_warm = ( + access_list_rule + in [ + AccessListCall.IN_BOTH_TX, + AccessListCall.IN_POINTER_TX_ONLY, + ] + and access_list_to == AccessListTo.CONTRACT_ADDRESS + ) pointer_call_gas: int = ( - # sstore + addr + addr + sload + op - # no access list, no pointer, all accesses are hot - # 20_000 + 2_600 * 2 + 2_100 + 37 = 27_337 - # - # access list for pointer, pointer is set - # additional 2_600 charged for access of contract - # 20_000 + 100 + 2_600 + 100 + 37 = 22_837 - # - # no access list, pointer is set - # pointer access is hot, sload and contract are hot - # 20_000 + 100 + 2_600 + 2_100 + 37 = 24_837 - # - # access list for contract, pointer is set - # contract call is hot, pointer call is call because pointer is set - # only sload is hot because access list is for contract - # 20_000 + 100 + 100 + 2100 + 37 = 22_337 - gas_costs.G_STORAGE_SET + Op.SSTORE(key_warm=True).gas_cost(fork) # key warmed by prior SLOAD # pointer address access - + ( - gas_costs.G_WARM_ACCOUNT_ACCESS - if ( - pointer_definition - in [ - PointerDefinition.IN_BOTH_TX, - PointerDefinition.IN_POINTER_TX_ONLY, - ] - or access_list_rule - in [ - AccessListCall.IN_BOTH_TX, - AccessListCall.IN_POINTER_TX_ONLY, - ] - and access_list_to == AccessListTo.POINTER_ADDRESS - ) - else gas_costs.G_COLD_ACCOUNT_ACCESS - ) + + Op.CALL(address_warm=pointer_account_warm).gas_cost(fork) # storage access - + ( - gas_costs.G_WARM_SLOAD - if ( - access_list_rule - in [ - AccessListCall.IN_BOTH_TX, - AccessListCall.IN_POINTER_TX_ONLY, - ] - and access_list_to == AccessListTo.POINTER_ADDRESS - ) - else gas_costs.G_COLD_SLOAD - ) + + Op.SLOAD(key_warm=pointer_storage_warm).gas_cost(fork) # contract address access - + ( - gas_costs.G_WARM_ACCOUNT_ACCESS - if ( - access_list_rule - in [ - AccessListCall.IN_BOTH_TX, - AccessListCall.IN_POINTER_TX_ONLY, - ] - and access_list_to == AccessListTo.CONTRACT_ADDRESS - ) - else gas_costs.G_COLD_ACCOUNT_ACCESS - ) + + Op.CALL(address_warm=pointer_contract_warm).gas_cost(fork) + opcodes_price ) @@ -918,22 +892,19 @@ def test_pointer_call_followed_by_direct_call( sender = pre.fund_eoa() pointer_a = pre.fund_eoa() - gas_costs: GasCosts = fork.gas_costs() call_worked = 1 opcodes_price: int = 37 pointer_call_gas = ( - gas_costs.G_STORAGE_SET - + gas_costs.G_WARM_ACCOUNT_ACCESS # pointer is warm - + gas_costs.G_COLD_ACCOUNT_ACCESS # contract is cold - + gas_costs.G_COLD_SLOAD # storage access under pointer call is cold + Op.SSTORE(key_warm=True).gas_cost(fork) # key warmed by prior SLOAD + + Op.CALL(address_warm=True).gas_cost(fork) # pointer is warm + + Op.CALL(address_warm=False).gas_cost(fork) # contract is cold + + Op.SLOAD(key_warm=False).gas_cost(fork) # storage is cold + opcodes_price ) direct_call_gas = ( - gas_costs.G_STORAGE_SET - + gas_costs.G_WARM_ACCOUNT_ACCESS # since previous pointer call, - # contract is now warm - + gas_costs.G_COLD_SLOAD # but storage is cold, because it's - # contract's direct + Op.SSTORE(key_warm=True).gas_cost(fork) # key warmed by prior SLOAD + + Op.CALL(address_warm=True).gas_cost(fork) # contract is now warm + + Op.SLOAD(key_warm=False).gas_cost(fork) # storage is cold + opcodes_price ) @@ -2142,11 +2113,9 @@ def test_delegation_replacement_call_previous_contract( auth_signer = pre.fund_eoa(delegation=pre_set_delegation_address) sender = pre.fund_eoa() - gsc = fork.gas_costs() - overhead_cost = gsc.G_VERY_LOW * len(Op.CALL.kwargs) + call_code = Op.CALL(gas=0, address=pre_set_delegation_address) set_code = CodeGasMeasure( - code=Op.CALL(gas=0, address=pre_set_delegation_address), - overhead_cost=overhead_cost, + code=call_code, extra_stack_items=1, ) @@ -2174,7 +2143,7 @@ def test_delegation_replacement_call_previous_contract( tx=tx, post={ auth_signer: Account( - storage={0: gsc.G_COLD_ACCOUNT_ACCESS}, + storage={0: call_code.gas_cost(fork)}, ) }, )