6
6
import fnmatch
7
7
import json
8
8
import os
9
- from typing import Any , TextIO
9
+ from typing import Any , Final , TextIO
10
10
11
11
from ethereum_rlp import rlp
12
12
from ethereum_types .numeric import U64 , U256 , Uint
24
24
parse_hex_or_int ,
25
25
)
26
26
from .env import Env
27
+ from .evm_trace .count import evm_trace as evm_trace_count
28
+ from .evm_trace .count import results as count_results
27
29
from .evm_trace .eip3155 import Eip3155Tracer
30
+ from .evm_trace .group import GroupTracer
28
31
from .t8n_types import Alloc , Result , Txs
29
32
30
33
@@ -72,12 +75,16 @@ def t8n_arguments(subparsers: argparse._SubParsersAction) -> None:
72
75
t8n_parser .add_argument ("--trace.nostack" , action = "store_true" )
73
76
t8n_parser .add_argument ("--trace.returndata" , action = "store_true" )
74
77
78
+ t8n_parser .add_argument ("--opcode.count" , dest = "opcode_count" , type = str )
79
+
75
80
t8n_parser .add_argument ("--state-test" , action = "store_true" )
76
81
77
82
78
83
class T8N (Load ):
79
84
"""The class that carries out the transition"""
80
85
86
+ tracers : Final [GroupTracer | None ]
87
+
81
88
def __init__ (
82
89
self , options : Any , out_file : TextIO , in_file : TextIO
83
90
) -> None :
@@ -100,18 +107,33 @@ def __init__(
100
107
)
101
108
self .fork = ForkLoad (fork_module )
102
109
110
+ tracers = GroupTracer ()
111
+
103
112
if self .options .trace :
104
113
trace_memory = getattr (self .options , "trace.memory" , False )
105
114
trace_stack = not getattr (self .options , "trace.nostack" , False )
106
115
trace_return_data = getattr (self .options , "trace.returndata" )
107
- trace . set_evm_trace (
116
+ tracers . add (
108
117
Eip3155Tracer (
109
118
trace_memory = trace_memory ,
110
119
trace_stack = trace_stack ,
111
120
trace_return_data = trace_return_data ,
112
121
output_basedir = self .options .output_basedir ,
113
122
)
114
123
)
124
+
125
+ if self .options .opcode_count is not None :
126
+ tracers .add (evm_trace_count )
127
+
128
+ maybe_tracers : GroupTracer | None
129
+ if tracers .tracers :
130
+ trace .set_evm_trace (tracers )
131
+ maybe_tracers = tracers
132
+ else :
133
+ maybe_tracers = None
134
+
135
+ self .tracers = maybe_tracers
136
+
115
137
self .logger = get_stream_logger ("T8N" )
116
138
117
139
super ().__init__ (
@@ -310,7 +332,7 @@ def run(self) -> int:
310
332
json_state = self .alloc .to_json ()
311
333
json_result = self .result .to_json ()
312
334
313
- json_output = {}
335
+ json_output : dict [ str , object ] = {}
314
336
315
337
if self .options .output_body == "stdout" :
316
338
txs_rlp = "0x" + rlp .encode (self .txs .all_txs ).hex ()
@@ -347,6 +369,18 @@ def run(self) -> int:
347
369
json .dump (json_result , f , indent = 4 )
348
370
self .logger .info (f"Wrote result to { result_output_path } " )
349
371
372
+ opcode_count_results = count_results ()
373
+ if self .options .opcode_count == "stdout" :
374
+ json_output ["opcodes" ] = opcode_count_results
375
+ elif self .options .opcode_count is not None :
376
+ result_output_path = os .path .join (
377
+ self .options .output_basedir ,
378
+ self .options .opcode_count ,
379
+ )
380
+ with open (result_output_path , "w" ) as f :
381
+ json .dump (opcode_count_results , f , indent = 4 )
382
+ self .logger .info (f"Wrote opcode counts to { result_output_path } " )
383
+
350
384
if json_output :
351
385
json .dump (json_output , self .out_file , indent = 4 )
352
386
0 commit comments