Skip to content

Commit 4ade831

Browse files
committed
Contract opcodes to compare gas cost for each precompile
Include all test cases and expect precompiles at addresses 01-0A
1 parent 3456e04 commit 4ade831

File tree

1 file changed

+300
-34
lines changed

1 file changed

+300
-34
lines changed

tests/precompiles/test_precompiles.py

+300-34
Original file line numberDiff line numberDiff line change
@@ -5,52 +5,320 @@
55
Alloc,
66
Environment,
77
StateTestFiller,
8-
TestParameterGroup,
98
Transaction,
10-
compute_create_address,
119
)
1210
from ethereum_test_tools.vm.opcode import Opcodes as Op
1311

1412

15-
def test_precompiles(state_test: StateTestFiller, pre: Alloc):
13+
@pytest.mark.parametrize(
14+
["address", "exists"],
15+
[
16+
("01", True),
17+
("02", True),
18+
("03", True),
19+
("04", True),
20+
("05", True),
21+
("06", True),
22+
("07", True),
23+
("08", True),
24+
("09", True),
25+
("0A", True),
26+
("0B", False),
27+
("0C", False),
28+
("0D", False),
29+
("0E", False),
30+
("0F", False),
31+
("10", False),
32+
("11", False),
33+
("12", False),
34+
("13", False),
35+
("14", False),
36+
("15", False),
37+
("16", False),
38+
("17", False),
39+
("18", False),
40+
("19", False),
41+
("1A", False),
42+
("1B", False),
43+
("1C", False),
44+
("1D", False),
45+
("1E", False),
46+
("1F", False),
47+
("20", False),
48+
("21", False),
49+
("22", False),
50+
("23", False),
51+
("24", False),
52+
("25", False),
53+
("26", False),
54+
("27", False),
55+
("28", False),
56+
("29", False),
57+
("2A", False),
58+
("2B", False),
59+
("2C", False),
60+
("2D", False),
61+
("2E", False),
62+
("2F", False),
63+
("30", False),
64+
("31", False),
65+
("32", False),
66+
("33", False),
67+
("34", False),
68+
("35", False),
69+
("36", False),
70+
("37", False),
71+
("38", False),
72+
("39", False),
73+
("3A", False),
74+
("3B", False),
75+
("3C", False),
76+
("3D", False),
77+
("3E", False),
78+
("3F", False),
79+
("40", False),
80+
("41", False),
81+
("42", False),
82+
("43", False),
83+
("44", False),
84+
("45", False),
85+
("46", False),
86+
("47", False),
87+
("48", False),
88+
("49", False),
89+
("4A", False),
90+
("4B", False),
91+
("4C", False),
92+
("4D", False),
93+
("4E", False),
94+
("4F", False),
95+
("50", False),
96+
("51", False),
97+
("52", False),
98+
("53", False),
99+
("54", False),
100+
("55", False),
101+
("56", False),
102+
("57", False),
103+
("58", False),
104+
("59", False),
105+
("5A", False),
106+
("5B", False),
107+
("5C", False),
108+
("5D", False),
109+
("5E", False),
110+
("5F", False),
111+
("60", False),
112+
("61", False),
113+
("62", False),
114+
("63", False),
115+
("64", False),
116+
("65", False),
117+
("66", False),
118+
("67", False),
119+
("68", False),
120+
("69", False),
121+
("6A", False),
122+
("6B", False),
123+
("6C", False),
124+
("6D", False),
125+
("6E", False),
126+
("6F", False),
127+
("70", False),
128+
("71", False),
129+
("72", False),
130+
("73", False),
131+
("74", False),
132+
("75", False),
133+
("76", False),
134+
("77", False),
135+
("78", False),
136+
("79", False),
137+
("7A", False),
138+
("7B", False),
139+
("7C", False),
140+
("7D", False),
141+
("7E", False),
142+
("7F", False),
143+
("80", False),
144+
("81", False),
145+
("82", False),
146+
("83", False),
147+
("84", False),
148+
("85", False),
149+
("86", False),
150+
("87", False),
151+
("88", False),
152+
("89", False),
153+
("8A", False),
154+
("8B", False),
155+
("8C", False),
156+
("8D", False),
157+
("8E", False),
158+
("8F", False),
159+
("90", False),
160+
("91", False),
161+
("92", False),
162+
("93", False),
163+
("94", False),
164+
("95", False),
165+
("96", False),
166+
("97", False),
167+
("98", False),
168+
("99", False),
169+
("9A", False),
170+
("9B", False),
171+
("9C", False),
172+
("9D", False),
173+
("9E", False),
174+
("9F", False),
175+
("A0", False),
176+
("A1", False),
177+
("A2", False),
178+
("A3", False),
179+
("A4", False),
180+
("A5", False),
181+
("A6", False),
182+
("A7", False),
183+
("A8", False),
184+
("A9", False),
185+
("AA", False),
186+
("AB", False),
187+
("AC", False),
188+
("AD", False),
189+
("AE", False),
190+
("AF", False),
191+
("B0", False),
192+
("B1", False),
193+
("B2", False),
194+
("B3", False),
195+
("B4", False),
196+
("B5", False),
197+
("B6", False),
198+
("B7", False),
199+
("B8", False),
200+
("B9", False),
201+
("BA", False),
202+
("BB", False),
203+
("BC", False),
204+
("BD", False),
205+
("BE", False),
206+
("BF", False),
207+
("C0", False),
208+
("C1", False),
209+
("C2", False),
210+
("C3", False),
211+
("C4", False),
212+
("C5", False),
213+
("C6", False),
214+
("C7", False),
215+
("C8", False),
216+
("C9", False),
217+
("CA", False),
218+
("CB", False),
219+
("CC", False),
220+
("CD", False),
221+
("CE", False),
222+
("CF", False),
223+
("D0", False),
224+
("D1", False),
225+
("D2", False),
226+
("D3", False),
227+
("D4", False),
228+
("D5", False),
229+
("D6", False),
230+
("D7", False),
231+
("D8", False),
232+
("D9", False),
233+
("DA", False),
234+
("DB", False),
235+
("DC", False),
236+
("DD", False),
237+
("DE", False),
238+
("DF", False),
239+
("E0", False),
240+
("E1", False),
241+
("E2", False),
242+
("E3", False),
243+
("E4", False),
244+
("E5", False),
245+
("E6", False),
246+
("E7", False),
247+
("E8", False),
248+
("E9", False),
249+
("EA", False),
250+
("EB", False),
251+
("EC", False),
252+
("ED", False),
253+
("EE", False),
254+
("EF", False),
255+
("F0", False),
256+
("F1", False),
257+
("F2", False),
258+
("F3", False),
259+
("F4", False),
260+
("F5", False),
261+
("F6", False),
262+
("F7", False),
263+
("F8", False),
264+
("F9", False),
265+
("FA", False),
266+
("FB", False),
267+
("FC", False),
268+
("FD", False),
269+
("FE", False),
270+
("FF", False),
271+
],
272+
)
273+
def test_precompiles(state_test: StateTestFiller, pre: Alloc, address: str, exists: bool):
16274
"""Test the MODEXP precompile."""
17275
env = Environment()
18276

19-
address = bytes.fromhex("01")
20-
address_10000 = bytes.fromhex("010000")
277+
address_10000 = 0x10000
278+
279+
input_buf = 0x1000
280+
output_buf = 0x2000
21281

22-
args_offset = bytes.fromhex("1000")
23-
args_size = bytes.fromhex("0040")
24-
output_offset = bytes.fromhex("2000")
25-
output_size = bytes.fromhex("0040")
282+
args_offset = 0x1000
283+
args_size = 0x20
284+
output_offset = 0x2000
285+
output_size = 0x20
26286

27-
gas_test = bytes.fromhex("0000")
28-
gas_10000 = bytes.fromhex("0020")
287+
gas_test = 0x20
288+
gas_10000 = 0x40
29289

30290
account = pre.deploy_contract(
31-
# Store all CALLDATA into memory (offset 0)
32-
# Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE())
33-
Op.MSTORE(args_size, 0x20)
34-
+ Op.MSTORE8(0xFF, 0xFF)
35-
+ Op.MSTORE8(0xFF, 0xFF)
36-
+ Op.BALANCE(address)
291+
Op.CALLDATACOPY(0, 0, Op.CALLDATASIZE())
292+
+ Op.MSTORE(args_size, 0x20)
293+
+ Op.MSTORE(input_buf, 0xFF)
294+
+ Op.MSTORE(output_buf, 0xFF)
295+
+ Op.MSTORE8(input_buf, 0xFF)
296+
+ Op.MSTORE8(output_buf, 0xFF)
297+
+ Op.BALANCE(Op.MLOAD(0))
37298
+ Op.BALANCE(address_10000)
38299
+ Op.MSTORE(gas_test, Op.GAS())
39300
# Setup stack to CALL into precompile with the CALLDATA and CALL into it (+ pop value)
40-
+ Op.CALL(Op.GAS(), address, 0, args_offset, args_size, output_offset, output_size)
301+
+ Op.CALL(
302+
address=Op.MLOAD(0),
303+
args_offset=args_offset,
304+
args_size=args_size,
305+
output_offset=output_offset,
306+
output_size=output_size,
307+
)
41308
+ Op.MSTORE(gas_test, (Op.SUB(Op.GAS(), Op.MLOAD(gas_test))))
42309
+ Op.MSTORE(gas_10000, Op.GAS())
43-
+ Op.CALL(Op.GAS(), address_10000, 0, args_offset, args_size, output_offset, output_size)
310+
+ Op.CALL(
311+
address=address_10000,
312+
args_offset=args_offset,
313+
args_size=args_size,
314+
output_offset=output_offset,
315+
output_size=output_size,
316+
)
44317
+ Op.MSTORE(gas_10000, (Op.SUB(Op.GAS(), Op.MLOAD(gas_10000))))
45-
+ Op.SSTORE(0, Op.MLOAD(0))
46-
# + Op.SSTORE(
47-
# 1,
48-
# Op.MLOAD(1000),
49-
# )
50-
# + Op.SSTORE(
51-
# 2,
52-
# Op.MLOAD(1032),
53-
# )
318+
+ Op.GT(Op.MLOAD(gas_test), Op.MLOAD(gas_10000))
319+
+ Op.JUMPI(Op.JUMPDEST(), 0x1)
320+
+ Op.SSTORE(0, Op.SUB(Op.MLOAD(gas_test), Op.MLOAD(gas_10000)))
321+
+ Op.SSTORE(0, Op.LT(Op.SLOAD(gas_test), 0x10))
54322
+ Op.STOP(),
55323
)
56324

@@ -59,17 +327,15 @@ def test_precompiles(state_test: StateTestFiller, pre: Alloc):
59327
tx = Transaction(
60328
ty=0x0,
61329
to=account,
62-
data=address,
330+
data=bytes.fromhex(address),
63331
gas_limit=500000,
64332
gas_price=10,
65333
protected=True,
66334
sender=sender,
67335
)
68336

69-
post = {}
70-
# if output.call_return_code != "0x00":
71-
# contract_address = compute_create_address(address=account, nonce=1)
72-
# post[contract_address] = Account(code=output.returned_data)
73-
post[account] = Account(storage={0: 0x01})
337+
# A high gas cost will result from calling a precompile
338+
# Expect 0x00 when a precompile exists at the address, 0x01 otherwise
339+
post = {account: Account(storage={0: "0x00" if exists else "0x01"})}
74340

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

0 commit comments

Comments
 (0)