Skip to content

Commit ceb39e1

Browse files
authored
new(tests): Add generic precompile-absence test (#1036)
* new(tests): Add precompile-absence test * more parametrize * fix(tests): Use zero gas to guarantee failure in case of unexpected precompile * docs: Changelog * fix: ruff
1 parent aff955b commit ceb39e1

File tree

3 files changed

+76
-0
lines changed

3 files changed

+76
-0
lines changed

docs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Test fixtures for use by clients are available for each release on the [Github r
1919
-[EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) set code of non-empty-storage account test ([#948](https://github.com/ethereum/execution-spec-tests/pull/948))
2020
-[EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) Remove delegation behavior of EXTCODE* ([#984](https://github.com/ethereum/execution-spec-tests/pull/984))
2121
-[EIP-7623](https://eips.ethereum.org/EIPS/eip-7623) Increase calldata cost ([#1004](https://github.com/ethereum/execution-spec-tests/pull/1004))
22+
- ✨ Add generic precompile-absence test ([#1036](https://github.com/ethereum/execution-spec-tests/pull/1036))
2223
- ✨ Add test for [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) which uses the full discount table of G2 MSM ([#1038](https://github.com/ethereum/execution-spec-tests/pull/1038))
2324

2425
### 🛠️ Framework
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Test for precompiles that apply for all forks starting from Frontier."""
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""abstract: Test Calling Precompile Range (close to zero)."""
2+
3+
import pytest
4+
5+
from ethereum_test_forks import Fork
6+
from ethereum_test_tools import (
7+
Account,
8+
Address,
9+
Alloc,
10+
Bytecode,
11+
StateTestFiller,
12+
Storage,
13+
Transaction,
14+
)
15+
from ethereum_test_tools import Opcodes as Op
16+
17+
UPPER_BOUND = 0x101
18+
RETURNDATASIZE_OFFSET = 0x10000000000000000 # Must be greater than UPPER_BOUND
19+
20+
21+
@pytest.mark.parametrize(
22+
"calldata_size",
23+
[
24+
pytest.param(0, id="empty_calldata"),
25+
pytest.param(31, id="31_bytes"),
26+
pytest.param(32, id="32_bytes"),
27+
],
28+
)
29+
@pytest.mark.valid_from("Byzantium")
30+
def test_precompile_absence(
31+
state_test: StateTestFiller,
32+
pre: Alloc,
33+
fork: Fork,
34+
calldata_size: int,
35+
):
36+
"""Test that addresses close to zero are not precompiles unless active in the fork."""
37+
active_precompiles = fork.precompiles()
38+
storage = Storage()
39+
call_code = Bytecode()
40+
for address in range(1, UPPER_BOUND + 1):
41+
if Address(address) in active_precompiles:
42+
continue
43+
call_code += Op.SSTORE(
44+
address,
45+
Op.CALL(gas=0, address=address, args_size=calldata_size),
46+
)
47+
storage[address] = 1
48+
if Op.RETURNDATASIZE in fork.valid_opcodes():
49+
call_code += Op.SSTORE(
50+
address + RETURNDATASIZE_OFFSET,
51+
Op.RETURNDATASIZE,
52+
)
53+
storage[address + RETURNDATASIZE_OFFSET] = 0
54+
55+
call_code += Op.STOP
56+
57+
entry_point_address = pre.deploy_contract(call_code, storage=storage.canary())
58+
59+
tx = Transaction(
60+
to=entry_point_address,
61+
gas_limit=10_000_000,
62+
sender=pre.fund_eoa(),
63+
protected=True,
64+
)
65+
66+
state_test(
67+
pre=pre,
68+
tx=tx,
69+
post={
70+
entry_point_address: Account(
71+
storage=storage,
72+
)
73+
},
74+
)

0 commit comments

Comments
 (0)