Skip to content

Commit 78b9734

Browse files
authored
Merge pull request #15 from marioevz/vm-opcodes
Add EVM Opcodes
2 parents 144369f + c7040bc commit 78b9734

File tree

9 files changed

+408
-175
lines changed

9 files changed

+408
-175
lines changed

fillers/eips/eip3651.py

Lines changed: 18 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
to_address,
1919
to_hash,
2020
)
21+
from ethereum_test_tools.vm.opcode import Opcodes as Op
2122

2223

2324
@test_from(fork="merged")
@@ -170,131 +171,50 @@ def test_warm_coinbase_gas_usage(fork):
170171
# List of opcodes that are affected by
171172
gas_measured_opcodes: Dict[str, CodeGasMeasure] = {
172173
"EXTCODESIZE": CodeGasMeasure(
173-
code=bytes(
174-
[
175-
0x41, # addr: COINBASE
176-
0x3B, # EXTCODESIZE
177-
]
178-
),
174+
code=Op.COINBASE + Op.EXTCODESIZE,
179175
overhead_cost=2,
180176
extra_stack_items=1,
181177
),
182178
"EXTCODECOPY": CodeGasMeasure(
183-
code=bytes(
184-
[
185-
0x60, # length
186-
0x00,
187-
0x60, # offset
188-
0x00,
189-
0x60, # offset
190-
0x00,
191-
0x41, # addr: COINBASE
192-
0x3C, # EXTCODECOPY
193-
]
194-
),
179+
code=Op.PUSH1(0x00) * 3 + Op.COINBASE + Op.EXTCODECOPY,
195180
overhead_cost=2 + 3 + 3 + 3,
196181
),
197182
"EXTCODEHASH": CodeGasMeasure(
198-
code=bytes(
199-
[
200-
0x41, # addr: COINBASE
201-
0x3F, # EXTCODEHASH
202-
]
203-
),
183+
code=Op.COINBASE + Op.EXTCODEHASH,
204184
overhead_cost=2,
205185
extra_stack_items=1,
206186
),
207187
"BALANCE": CodeGasMeasure(
208-
code=bytes(
209-
[
210-
0x41, # addr: COINBASE
211-
0x31, # BALANCE
212-
]
213-
),
188+
code=Op.COINBASE + Op.BALANCE,
214189
overhead_cost=2,
215190
extra_stack_items=1,
216191
),
217192
"CALL": CodeGasMeasure(
218-
code=bytes(
219-
[
220-
0x60, # returnLength
221-
0x00,
222-
0x60, # returnOffset
223-
0x00,
224-
0x60, # argsLength
225-
0x00,
226-
0x60, # argsOffset
227-
0x00,
228-
0x60, # value
229-
0x00,
230-
0x41, # addr: COINBASE
231-
0x60, # gas
232-
0xFF,
233-
0xF1, # CALL
234-
]
235-
),
193+
code=Op.PUSH1(0x00) * 5 + Op.COINBASE + Op.PUSH1(0xFF) + Op.CALL,
236194
overhead_cost=3 + 2 + 3 + 3 + 3 + 3 + 3,
237195
extra_stack_items=1,
238196
),
239197
"CALLCODE": CodeGasMeasure(
240-
code=bytes(
241-
[
242-
0x60, # returnLength
243-
0x00,
244-
0x60, # returnOffset
245-
0x00,
246-
0x60, # argsLength
247-
0x00,
248-
0x60, # argsOffset
249-
0x00,
250-
0x60, # value
251-
0x00,
252-
0x41, # addr: COINBASE
253-
0x60, # gas
254-
0xFF,
255-
0xF2, # CALLCODE
256-
]
257-
),
198+
code=Op.PUSH1(0x00) * 5
199+
+ Op.COINBASE
200+
+ Op.PUSH1(0xFF)
201+
+ Op.CALLCODE,
258202
overhead_cost=3 + 2 + 3 + 3 + 3 + 3 + 3,
259203
extra_stack_items=1,
260204
),
261205
"DELEGATECALL": CodeGasMeasure(
262-
code=bytes(
263-
[
264-
0x60, # returnLength
265-
0x00,
266-
0x60, # returnOffset
267-
0x00,
268-
0x60, # argsLength
269-
0x00,
270-
0x60, # argsOffset
271-
0x00,
272-
0x41, # addr: COINBASE
273-
0x60, # gas
274-
0xFF,
275-
0xF4, # DELEGATECALL
276-
]
277-
),
206+
code=Op.PUSH1(0x00) * 4
207+
+ Op.COINBASE
208+
+ Op.PUSH1(0xFF)
209+
+ Op.DELEGATECALL,
278210
overhead_cost=3 + 2 + 3 + 3 + 3 + 3,
279211
extra_stack_items=1,
280212
),
281213
"STATICCALL": CodeGasMeasure(
282-
code=bytes(
283-
[
284-
0x60, # returnLength
285-
0x00,
286-
0x60, # returnOffset
287-
0x00,
288-
0x60, # argsLength
289-
0x00,
290-
0x60, # argsOffset
291-
0x00,
292-
0x41, # addr: COINBASE
293-
0x60, # gas
294-
0xFF,
295-
0xFA, # STATICCALL
296-
]
297-
),
214+
code=Op.PUSH1(0x00) * 4
215+
+ Op.COINBASE
216+
+ Op.PUSH1(0xFF)
217+
+ Op.STATICCALL,
298218
overhead_cost=3 + 2 + 3 + 3 + 3 + 3,
299219
extra_stack_items=1,
300220
),

fillers/eips/eip3855.py

Lines changed: 26 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
test_from,
1616
to_address,
1717
)
18+
from ethereum_test_tools.vm.opcode import Opcodes as Op
1819

1920

2021
@test_from(fork="shanghai", eips=[3855])
@@ -39,14 +40,7 @@ def test_push0(fork):
3940
"""
4041
Test case 1: Simple PUSH0 as key to SSTORE
4142
"""
42-
code = bytes(
43-
[
44-
0x60, # PUSH1
45-
0x01,
46-
0x5F, # PUSH0
47-
0x55, # SSTORE
48-
]
49-
)
43+
code = Op.PUSH1(1) + Op.PUSH0 + Op.SSTORE
5044

5145
pre[addr_1] = Account(code=code)
5246
post[addr_1] = Account(storage={0x00: 0x01})
@@ -59,16 +53,9 @@ def test_push0(fork):
5953
Test case 2: Fill stack with PUSH0, then OR all values and save using
6054
SSTORE
6155
"""
62-
code = bytes([0x5F] * 1024) # PUSH0
63-
code += bytes([0x17] * 1023) # OR
64-
code += bytes(
65-
[
66-
0x60, # PUSH1
67-
0x01,
68-
0x90, # SWAP1
69-
0x55, # SSTORE
70-
]
71-
)
56+
code = Op.PUSH0 * 1024
57+
code += Op.OR * 1023
58+
code += Op.PUSH1(1) + Op.SWAP1 + Op.SSTORE
7259

7360
pre[addr_1] = Account(code=code)
7461
post[addr_1] = Account(storage={0x00: 0x01})
@@ -80,15 +67,8 @@ def test_push0(fork):
8067
"""
8168
Test case 3: Stack overflow by using PUSH0 1025 times
8269
"""
83-
code = bytes(
84-
[
85-
0x60, # PUSH1
86-
0x01,
87-
0x5F, # PUSH0
88-
0x55, # SSTORE
89-
]
90-
)
91-
code += bytes([0x5F] * 1025) # PUSH0, stack overflow
70+
code = Op.PUSH1(1) + Op.PUSH0 + Op.SSTORE
71+
code += Op.PUSH0 * 1025
9272

9373
pre[addr_1] = Account(code=code)
9474
post[addr_1] = Account(storage={0x00: 0x00})
@@ -100,17 +80,8 @@ def test_push0(fork):
10080
"""
10181
Test case 4: Update already existing storage value
10282
"""
103-
code = bytes(
104-
[
105-
0x60, # PUSH1
106-
0x02,
107-
0x5F, # PUSH0
108-
0x55, # SSTORE
109-
0x5F, # PUSH0
110-
0x60, # PUSH1
111-
0x01,
112-
0x55, # SSTORE
113-
]
83+
code = (
84+
Op.PUSH1(2) + Op.PUSH0 + Op.SSTORE + Op.PUSH0 + Op.PUSH1(1) + Op.SSTORE
11485
)
11586

11687
pre[addr_1] = Account(code=code, storage={0x00: 0x0A, 0x01: 0x0A})
@@ -133,18 +104,13 @@ def test_push0(fork):
133104
}
134105
"""
135106
)
136-
code_2 = bytes(
137-
[
138-
0x60, # PUSH1
139-
0xFF,
140-
0x5F, # PUSH0
141-
0x53, # MSTORE8
142-
0x60, # PUSH1
143-
0x01,
144-
0x60, # PUSH1
145-
0x00,
146-
0xF3, # RETURN
147-
]
107+
code_2 = (
108+
Op.PUSH1(0xFF)
109+
+ Op.PUSH0
110+
+ Op.MSTORE8
111+
+ Op.PUSH1(1)
112+
+ Op.PUSH1(0)
113+
+ Op.RETURN
148114
)
149115

150116
pre[addr_1] = Account(code=code_1)
@@ -160,19 +126,15 @@ def test_push0(fork):
160126
"""
161127
Test case 6: Jump to a JUMPDEST next to a PUSH0, must succeed.
162128
"""
163-
code = bytes(
164-
[
165-
0x60, # PUSH1
166-
0x04,
167-
0x56, # JUMP
168-
0x5F, # PUSH0
169-
0x5B, # JUMPDEST
170-
0x60, # PUSH1
171-
0x01,
172-
0x5F, # PUSH0
173-
0x55, # SSTORE
174-
0x00, # STOP
175-
]
129+
code = (
130+
Op.PUSH1(4)
131+
+ Op.JUMP
132+
+ Op.PUSH0
133+
+ Op.JUMPDEST
134+
+ Op.PUSH1(1)
135+
+ Op.PUSH0
136+
+ Op.SSTORE
137+
+ Op.STOP
176138
)
177139

178140
pre[addr_1] = Account(code=code)
@@ -186,7 +148,7 @@ def test_push0(fork):
186148
Test case 7: PUSH0 gas cost
187149
"""
188150
code = CodeGasMeasure(
189-
code=bytes([0x5F]), # PUSH0
151+
code=Op.PUSH0,
190152
extra_stack_items=1,
191153
)
192154

fillers/eips/eip3860.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
test_from,
2626
to_address,
2727
)
28+
from ethereum_test_tools.vm.opcode import Opcodes as Op
2829

2930
"""
3031
General constants used for testing purposes
@@ -33,7 +34,7 @@
3334
MAX_INITCODE_SIZE = 49152
3435
INITCODE_WORD_COST = 2
3536
KECCAK_WORD_COST = 6
36-
INITCODE_RESULTING_DEPLOYED_CODE = bytes([0x00])
37+
INITCODE_RESULTING_DEPLOYED_CODE = Op.STOP
3738

3839
BASE_TRANSACTION_GAS = 21000
3940
CREATE_CONTRACT_BASE_GAS = 32000
@@ -168,7 +169,7 @@ def calculate_create_tx_execution_cost(
168169
deploy_code=bytes(),
169170
name="single_byte_initcode",
170171
)
171-
SINGLE_BYTE_INITCODE.bytecode = bytes([0x00])
172+
SINGLE_BYTE_INITCODE.bytecode = Op.STOP
172173
SINGLE_BYTE_INITCODE.deployment_gas = 0
173174
SINGLE_BYTE_INITCODE.execution_gas = 0
174175

@@ -217,7 +218,7 @@ def generate_tx_initcode_limit_test_cases(
217218
else:
218219
# Initcode is at or below the max size, tx inclusion in the block
219220
# is ok and the contract is successfully created.
220-
post[created_contract_address] = Account(code="0x00")
221+
post[created_contract_address] = Account(code=Op.STOP)
221222

222223
yield BlockchainTest(
223224
pre=pre,

src/ethereum_test_tools/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from .filling.decorators import test_from, test_only
2323
from .filling.fill import fill_test
2424
from .spec import BlockchainTest, StateTest
25+
from .vm import Opcode, Opcodes
2526
from .vm.fork import is_fork
2627

2728
__all__ = (
@@ -33,6 +34,8 @@
3334
"Environment",
3435
"Initcode",
3536
"JSONEncoder",
37+
"Opcode",
38+
"Opcodes",
3639
"StateTest",
3740
"Storage",
3841
"TestAddress",

src/ethereum_test_tools/code/code.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ def code_to_bytes(code: str | bytes | Code) -> bytes:
5656
if isinstance(code, Code):
5757
return code.assemble()
5858

59-
if type(code) is bytes:
60-
return code
59+
if isinstance(code, bytes):
60+
return bytes(code)
6161

6262
if type(code) is str:
6363
# We can have a hex representation of bytecode with spaces for
@@ -80,7 +80,7 @@ def code_to_hex(code: str | bytes | Code) -> str:
8080
if isinstance(code, Code):
8181
return "0x" + code.assemble().hex()
8282

83-
if type(code) is bytes:
83+
if isinstance(code, bytes):
8484
return "0x" + code.hex()
8585

8686
if type(code) is str:

0 commit comments

Comments
 (0)