Skip to content

Commit 201e9f8

Browse files
committed
new(tests): Add precompile-absence test
1 parent cfddac5 commit 201e9f8

File tree

2 files changed

+74
-0
lines changed

2 files changed

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

0 commit comments

Comments
 (0)