Skip to content

Commit

Permalink
new(tests) Call Gas Testing for EXT*CALL
Browse files Browse the repository at this point in the history
Test call gas for EXT*CALL, using a legacy harness.

Signed-off-by: Danno Ferrin <[email protected]>
  • Loading branch information
shemnon committed Jul 25, 2024
1 parent bbad63b commit 9bab1b8
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 0 deletions.
2 changes: 2 additions & 0 deletions tests/prague/eip7692_eof_v1/eip7069_extcall/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
slot_call_status = next(_slot)
slot_calldata_1 = next(_slot)
slot_calldata_2 = next(_slot)
slot_cold_gas = next(_slot)
slot_warm_gas = next(_slot)

slot_last_slot = next(_slot)

Expand Down
129 changes: 129 additions & 0 deletions tests/prague/eip7692_eof_v1/eip7069_extcall/test_gas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
"""
abstract: Tests [EIP-7069: Revamped CALL instructions](https://eips.ethereum.org/EIPS/eip-7069)
Tests gas comsumption
""" # noqa: E501

import pytest

from ethereum_test_tools import Account, Alloc, Environment, StateTestFiller, Transaction
from ethereum_test_tools.eof.v1 import Container, Section
from ethereum_test_tools.vm.opcode import Opcodes as Op
from ethereum_test_vm import Opcodes, Bytecode

from .. import EOF_FORK_NAME
from . import REFERENCE_SPEC_GIT_PATH, REFERENCE_SPEC_VERSION
from .helpers import (
slot_cold_gas,
slot_warm_gas,
)

REFERENCE_SPEC_GIT_PATH = REFERENCE_SPEC_GIT_PATH
REFERENCE_SPEC_VERSION = REFERENCE_SPEC_VERSION

pytestmark = pytest.mark.valid_from(EOF_FORK_NAME)


def gas_test(
state_test: StateTestFiller,
pre: Alloc,
setup_code: Bytecode,
subject_code: Bytecode,
tear_down_code: Bytecode,
cold_gas: int,
warm_gas: int | None = None,
):
if cold_gas <= 0:
raise ValueError(f"Target gas allocations (warm_gas) must be > 0, got {cold_gas}")
if warm_gas is None:
warm_gas = cold_gas

env = Environment()

sender = pre.fund_eoa(10**18)

address_baseline = pre.deploy_contract(
Container(sections=[Section.Code(code=setup_code + tear_down_code)])
)
address_subject = pre.deploy_contract(
Container(sections=[Section.Code(code=setup_code + subject_code + tear_down_code)])
)
address_legacy_harness = pre.deploy_contract(
code=
# warm subject and baseline without executing
(Op.BALANCE(address_subject) + Op.POP + Op.BALANCE(address_baseline) + Op.POP)
# cold gas run
+ (
Op.GAS
+ Op.CALL(address=address_subject, gas=500_000)
+ Op.POP
+ Op.GAS
+ Op.SWAP1
+ Op.SUB
)
# Baseline gas run
+ (
Op.GAS
+ Op.CALL(address=address_baseline, gas=500_000)
+ Op.POP
+ Op.GAS
+ Op.SWAP1
+ Op.SUB
)
# warm gas run
+ (
Op.GAS
+ Op.CALL(address=address_subject, gas=500_000)
+ Op.POP
+ Op.GAS
+ Op.SWAP1
+ Op.SUB
)
# Store warm gas
+ (Op.DUP2 + Op.SWAP1 + Op.SUB + Op.PUSH2(slot_warm_gas) + Op.SSTORE)
# store cold gas
+ (Op.SWAP1 + Op.SUB + Op.PUSH2(slot_cold_gas) + Op.SSTORE)
+ Op.STOP
)

post = {
address_legacy_harness: Account(
storage={
slot_warm_gas: cold_gas if warm_gas is None else warm_gas,
slot_cold_gas: cold_gas,
},
),
}

tx = Transaction(to=address_legacy_harness, gas_limit=2_000_000, sender=sender)

state_test(env=env, pre=pre, tx=tx, post=post)


@pytest.mark.parametrize(
["opcode", "pre_setup", "cold_gas", "warm_gas"],
[
pytest.param(Op.EXTCALL, Op.PUSH0, 2600, 100, id="EXTCALL"),
pytest.param(Op.EXTCALL, Op.PUSH1(1), 2600 + 9000, 100 + 9000, id="EXTCALL_with_value"),
pytest.param(Op.EXTDELEGATECALL, Op.NOOP, 2600, 100, id="EXTSTATICCALL"),
pytest.param(Op.EXTSTATICCALL, Op.NOOP, 2600, 100, id="EXTDELEGATECALL"),
],
)
def test_ext_calls_gas(
state_test: StateTestFiller,
pre: Alloc,
opcode: Op,
pre_setup: Op,
cold_gas: int,
warm_gas: int | None,
):
address_target = pre.deploy_contract(Container(sections=[Section.Code(code=Op.STOP)]))

gas_test(
state_test,
pre,
setup_code=pre_setup + Op.PUSH0 + Op.PUSH0 + Op.PUSH20(address_target),
subject_code=opcode,
tear_down_code=Op.STOP,
cold_gas=cold_gas,
warm_gas=warm_gas,
)

0 comments on commit 9bab1b8

Please sign in to comment.