Skip to content

Commit e589892

Browse files
refactor(tests): update checklist item for eip7939 (#2097)
* feat: update checklist item for clz * feat: add new checklist items * refactor: update checklist items for eip7939 * refactor: update checklist not applicable itemss * feat(checklist): Add checklist warnings * feat(checklist): ad coverage and reentry notes to eip7939 checklist * fix linting issue * refactor(checklist): remove duplicate ban check items --------- Co-authored-by: Mario Vega <[email protected]>
1 parent 110b5d4 commit e589892

File tree

7 files changed

+66
-14
lines changed

7 files changed

+66
-14
lines changed

docs/writing_tests/checklist_templates/eip_testing_checklist_template.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ Verify opcode operation in a subcall frame originated from a `STATICCALL` opcode
108108

109109
| ID | Description | Status | Tests |
110110
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------ | ----- |
111+
| `opcode/test/execution_context/staticcall` | `STATICCALL`. | | |
111112
| `opcode/test/execution_context/staticcall/ban_check` | Verify exceptional abort if the opcode attempts to modify the code, storage or balance of an account. | | |
112113
| `opcode/test/execution_context/staticcall/ban_no_modification` | If the opcode is completely banned from static contexts, verify that even when its inputs would not cause any account modification, the opcode still results in exceptional abort of the execution (e.g. `PAY` with zero value, or `SSTORE` to the value it already has in the storage). | | |
113114
| `opcode/test/execution_context/staticcall/sub_calls` | Verify sub-calls using other opcodes (e.g. `CALL`, `DELEGATECALL`, etc) also results in the same exceptional abort behavior. | | |
@@ -193,6 +194,14 @@ Verify that the memory expansion correctly follows the gas calculation.
193194
| -------------------------------------------- | ----------------- | ------ | ----- |
194195
| `opcode/test/gas_usage/memory_expansion` | Memory expansion. | | |
195196

197+
##### Extra Gas
198+
199+
Verify that attempting to execute the opcode when gas available is 1 more than the required gas results in exceptional abort.
200+
201+
| ID | Description | Status | Tests |
202+
| ------------------------------------------------ | ----------------------------------- | ------ | ----- |
203+
| `opcode/test/gas_usage/extra_gas` | extra gas should not fail the execution | | |
204+
196205
##### Out-Of-Gas
197206

198207
Verify that attempting to execute the opcode when gas available is 1 less than the required gas results in exceptional abort.

src/ethereum_test_checklists/eip_checklist.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,11 @@ class OutOfGasMemory(ChecklistItem):
386386

387387
pass
388388

389+
class ExtraGas(ChecklistItem):
390+
"""Extra gas usage tests."""
391+
392+
pass
393+
389394
class OrderOfOperations(ChecklistItem):
390395
"""Order of operations tests."""
391396

src/ethereum_test_checklists/eip_checklist.pyi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ class EIPChecklist:
138138
Invalid: _CallableChecklistItem
139139

140140
class GasUsage(_CallableChecklistItem):
141+
ExtraGas: _CallableChecklistItem
141142
MemoryExpansion: _CallableChecklistItem
142143
Normal: _CallableChecklistItem
143144
OutOfGasExecution: _CallableChecklistItem

src/pytest_plugins/filler/eip_checklist.py

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ def __str__(self) -> str:
118118
status = "❓"
119119
else:
120120
status = "✅"
121-
tests = ", ".join(sorted(map(resolve_test_link, self.tests)))
121+
tests = ", ".join(sorted(self.tests))
122122
elif self.not_applicable:
123123
status = "N/A"
124124
tests = self.not_applicable_reason
@@ -160,17 +160,6 @@ def resolve_id(item_id: str) -> Set[str]:
160160
return covered_ids
161161

162162

163-
def resolve_test_link(test_id: str) -> str:
164-
"""Resolve a test ID to a test link."""
165-
# test_id example: tests/fork/eip1234_some_eip/test_file.py::test_function[test_param1-...]
166-
# Relative path: ../../../../tests/fork/eip1234_some_eip/test_file/test_function/
167-
pattern = r"(.*)\.py::(\w+)"
168-
match = re.match(pattern, test_id)
169-
if not match:
170-
return test_id
171-
return f"[{test_id}](../../../../{match.group(1)}/{match.group(2)}/)"
172-
173-
174163
ALL_CHECKLIST_WARNINGS: Dict[str, Type["ChecklistWarning"]] = {}
175164

176165

@@ -222,8 +211,7 @@ def from_items(cls, all_items: Dict[str, EIPItem]) -> ChecklistWarning | None:
222211
for item in conflicting_items:
223212
details.append(
224213
f"| {item.id} | {item.description} | "
225-
+ f"{item.not_applicable_reason} | "
226-
+ f"{', '.join(sorted(map(resolve_test_link, item.tests)))} |"
214+
+ f"{item.not_applicable_reason} | {', '.join(sorted(item.tests))} |"
227215
)
228216

229217
return cls(details=details)
@@ -245,6 +233,7 @@ def add_covered_test(self, checklist_id: str, node_id: str) -> None:
245233
def covered_items(self) -> int:
246234
"""Return the number of covered items."""
247235
return sum(1 for item in self.items.values() if item.covered and not item.not_applicable)
236+
return sum(1 for item in self.items.values() if item.covered and not item.not_applicable)
248237

249238
@property
250239
def total_items(self) -> int:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
general/code_coverage/eels = Please check https://app.codecov.io/gh/ethereum/execution-specs/pull/1388/blob/src/ethereum/osaka/vm/instructions/bitwise.py#L243 for relevant test coverage
2+
general/code_coverage/test_coverage = Please run the test with `--cov` flag for final coverage
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
system_contract = EIP does not introduce a new system contract
2+
precompile = EIP does not introduce a new precompile
3+
removed_precompile = EIP does not remove a precompile
4+
transaction_type = EIP does not introduce a new transaction type
5+
block_header_field = EIP does not add any new block header fields
6+
block_body_field = EIP does not add any new block body fields
7+
gas_cost_changes = EIP does not modify existing gas costs, only introduces new opcode with fixed cost
8+
gas_refunds_changes = EIP does not introduce any gas refund changes
9+
blob_count_changes = EIP does not introduce any blob count changes
10+
execution_layer_request = EIP does not introduce an execution layer request
11+
new_transaction_validity_constraint = EIP does not introduce a new transaction validity constraint
12+
modified_transaction_validity_constraint = EIP does not introduce a modified transaction validity constraint
13+
opcode/test/mem_exp = CLZ does not read/write to memory component
14+
opcode/test/stack_overflow = CLZ takes one args and pushes one args to stack, not increasing stack element, hence no overflow issue
15+
opcode/test/stack_complex_operations/data_portion_variables = there is no data portion for CLZ
16+
opcode/test/execution_context/delegatecall/code = CLZ does not modify code
17+
opcode/test/execution_context/tx_context = CLZ does not change behavior depending on transaction property
18+
opcode/test/execution_context/block_context = CLZ does not change behavior depending on block property
19+
opcode/test/execution_context/initcode/reentry = CLZ is not a stateful opcode
20+
opcode/test/gas_usage/memory_expansion = no memory read/write for CLZ
21+
opcode/test/gas_usage/out_of_gas_memory = no memory read/write for CLZ
22+
opcode/test/gas_usage/order_of_operations = the order will not affect result of CLZ
23+
opcode/test/return_data = although we could verify the return buffer is not affected, but it is more like testing memory write operation, as CLZ does not write to memory directly
24+
opcode/test/terminating = not such opcode
25+
opcode/test/terminating/rollback = CLZ is not a terminating opcode, so no rollback behavior
26+
opcode/test/out_of_bounds = takes one element from stack, no specific boundary
27+
opcode/test/exceptional_abort = underflow is the only exceptional abort scenario and it is included already
28+
opcode/test/data_portion = no data portion
29+
opcode/test/contract_creation = no contract created in execution

tests/osaka/eip7939_count_leading_zeros/test_count_leading_zeros.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import pytest
77

88
from ethereum_test_base_types import Storage
9+
from ethereum_test_checklists import EIPChecklist
910
from ethereum_test_forks import Fork
1011
from ethereum_test_tools import (
1112
Account,
@@ -144,6 +145,9 @@ def test_clz_gas_cost(state_test: StateTestFiller, pre: Alloc, fork: Fork):
144145
state_test(pre=pre, post=post, tx=tx)
145146

146147

148+
@EIPChecklist.Opcode.Test.GasUsage.Normal()
149+
@EIPChecklist.Opcode.Test.GasUsage.OutOfGasExecution()
150+
@EIPChecklist.Opcode.Test.GasUsage.ExtraGas()
147151
@pytest.mark.valid_from("Osaka")
148152
@pytest.mark.parametrize("bits", [0, 64, 128, 255])
149153
@pytest.mark.parametrize("gas_cost_delta", [-2, -1, 0, 1, 2])
@@ -178,6 +182,8 @@ def test_clz_gas_cost_boundary(
178182
state_test(pre=pre, post=post, tx=tx)
179183

180184

185+
@EIPChecklist.Opcode.Test.StackUnderflow()
186+
@EIPChecklist.Opcode.Test.StackComplexOperations.StackHeights.Zero()
181187
@pytest.mark.valid_from("Osaka")
182188
def test_clz_stack_underflow(state_test: StateTestFiller, pre: Alloc):
183189
"""Test CLZ opcode with empty stack (should revert due to stack underflow)."""
@@ -202,6 +208,8 @@ def test_clz_stack_underflow(state_test: StateTestFiller, pre: Alloc):
202208
state_test(pre=pre, post=post, tx=tx)
203209

204210

211+
@EIPChecklist.Opcode.Test.StackComplexOperations.StackHeights.Odd()
212+
@EIPChecklist.Opcode.Test.StackComplexOperations.StackHeights.Even()
205213
@pytest.mark.valid_from("Osaka")
206214
def test_clz_stack_not_overflow(state_test: StateTestFiller, pre: Alloc, fork: Fork):
207215
"""Test CLZ opcode never causes stack overflow."""
@@ -260,6 +268,8 @@ def test_clz_push_operation_same_value(state_test: StateTestFiller, pre: Alloc):
260268
state_test(pre=pre, post=post, tx=tx)
261269

262270

271+
@EIPChecklist.Opcode.Test.ForkTransition.Invalid()
272+
@EIPChecklist.Opcode.Test.ForkTransition.At()
263273
@pytest.mark.valid_at_transition_to("Osaka", subsequent_forks=True)
264274
def test_clz_fork_transition(blockchain_test: BlockchainTestFiller, pre: Alloc):
265275
"""Test CLZ opcode behavior at fork transition."""
@@ -386,6 +396,7 @@ def test_clz_jump_operation(
386396
auth_account_start_balance = 0
387397

388398

399+
@EIPChecklist.Opcode.Test.ExecutionContext.SetCode()
389400
@pytest.mark.valid_from("Osaka")
390401
def test_clz_from_set_code(
391402
state_test: StateTestFiller,
@@ -530,6 +541,7 @@ def test_clz_with_memory_operation(state_test: StateTestFiller, pre: Alloc, bits
530541
state_test(pre=pre, post=post, tx=tx)
531542

532543

544+
@EIPChecklist.Opcode.Test.ExecutionContext.Initcode.Behavior.Tx()
533545
@pytest.mark.valid_from("Osaka")
534546
def test_clz_initcode_context(state_test: StateTestFiller, pre: Alloc):
535547
"""Test CLZ opcode behavior when creating a contract."""
@@ -559,6 +571,7 @@ def test_clz_initcode_context(state_test: StateTestFiller, pre: Alloc):
559571
state_test(pre=pre, post=post, tx=tx)
560572

561573

574+
@EIPChecklist.Opcode.Test.ExecutionContext.Initcode.Behavior.Opcode()
562575
@pytest.mark.valid_from("Osaka")
563576
@pytest.mark.parametrize("opcode", [Op.CREATE, Op.CREATE2])
564577
def test_clz_initcode_create(state_test: StateTestFiller, pre: Alloc, opcode: Op):
@@ -609,6 +622,10 @@ class CallingContext:
609622
no_context = 3 # STATICCALL
610623

611624

625+
@EIPChecklist.Opcode.Test.ExecutionContext.Call()
626+
@EIPChecklist.Opcode.Test.ExecutionContext.Delegatecall()
627+
@EIPChecklist.Opcode.Test.ExecutionContext.Callcode()
628+
@EIPChecklist.Opcode.Test.ExecutionContext.Staticcall()
612629
@pytest.mark.valid_from("Osaka")
613630
@pytest.mark.parametrize(
614631
"opcode,context",

0 commit comments

Comments
 (0)