miden_processor/fast/tracer.rs
1use alloc::sync::Arc;
2
3use miden_core::{
4 Felt, Word,
5 crypto::merkle::MerklePath,
6 mast::{MastForest, MastNodeId},
7};
8
9use crate::{
10 continuation_stack::ContinuationStack,
11 fast::{FastProcessor, trace_state::NodeExecutionState},
12};
13
14/// A trait for tracing the execution of a [FastProcessor].
15pub trait Tracer {
16 /// Signals the start of a new clock cycle.
17 ///
18 /// This is guaranteed to be called before executing the operation at the given clock cycle.
19 /// Additionally, [miden_core::mast::ExternalNode] nodes are guaranteed to be resolved before
20 /// this method is called.
21 fn start_clock_cycle(
22 &mut self,
23 processor: &FastProcessor,
24 execution_state: NodeExecutionState,
25 continuation_stack: &mut ContinuationStack,
26 current_forest: &Arc<MastForest>,
27 );
28
29 /// When execution encounters a [miden_core::mast::ExternalNode], the external node gets
30 /// resolved to the MAST node it refers to in the new MAST forest. Hence, a clock cycle where
31 /// execution encounters an external node effectively has 2 nodes associated with it.
32 /// [Tracer::start_clock_cycle] is called on the resolved node (i.e. *not* the external node).
33 /// This method is called on the external node before it is resolved, and hence is guaranteed to
34 /// be called before [Tracer::start_clock_cycle] for clock cycles involving an external node.
35 fn record_external_node_resolution(&mut self, node_id: MastNodeId, forest: &Arc<MastForest>);
36
37 // HASHER METHODS
38 // -----------------------------------------------
39
40 /// Records the result of a call to `Hasher::permute()`.
41 fn record_hasher_permute(&mut self, hashed_state: [Felt; 12]);
42
43 /// Records the result of a call to `Hasher::build_merkle_root()`.
44 ///
45 /// The `path` is an `Option` to support environments where the `Hasher` is not present, such as
46 /// in the context of parallel trace generation.
47 fn record_hasher_build_merkle_root(&mut self, path: Option<&MerklePath>, root: Word);
48
49 /// Records the result of a call to `Hasher::update_merkle_root()`.
50 ///
51 /// The `path` is an `Option` to support environments where the `Hasher` is not present, such as
52 /// in the context of parallel trace generation.
53 fn record_hasher_update_merkle_root(
54 &mut self,
55 path: Option<&MerklePath>,
56 old_root: Word,
57 new_root: Word,
58 );
59
60 // MEMORY METHODS
61 // -----------------------------------------------
62
63 /// Records the element read from memory at the given address.
64 fn record_memory_read_element(&mut self, element: Felt, addr: Felt);
65
66 /// Records the word read from memory at the given address.
67 fn record_memory_read_word(&mut self, word: Word, addr: Felt);
68
69 // ADVICE PROVIDER METHODS
70 // -----------------------------------------------
71
72 /// Records the value returned by a [crate::host::advice::AdviceProvider::pop_stack] operation.
73 fn record_advice_pop_stack(&mut self, value: Felt);
74 /// Records the value returned by a [crate::host::advice::AdviceProvider::pop_stack_word]
75 /// operation.
76 fn record_advice_pop_stack_word(&mut self, word: Word);
77 /// Records the value returned by a [crate::host::advice::AdviceProvider::pop_stack_dword]
78 /// operation.
79 fn record_advice_pop_stack_dword(&mut self, words: [Word; 2]);
80
81 // MISCELLANEOUS
82 // -----------------------------------------------
83
84 /// Signals that the processor clock is being incremented.
85 fn increment_clk(&mut self);
86
87 /// Signals that the stack depth is incremented as a result of pushing a new element.
88 fn increment_stack_size(&mut self, processor: &FastProcessor);
89
90 /// Signals that the stack depth is decremented as a result of popping an element off the stack.
91 ///
92 /// Note that if the stack depth is already [miden_core::stack::MIN_STACK_DEPTH], then the stack
93 /// depth is unchanged; the top element is popped off, and a ZERO is shifted in at the bottom.
94 fn decrement_stack_size(&mut self);
95
96 /// Signals the start of a new execution context, as a result of a CALL, SYSCALL or DYNCALL
97 /// operation being executed.
98 fn start_context(&mut self);
99
100 /// Signals the end of an execution context, as a result of an END operation associated with a
101 /// CALL, SYSCALL or DYNCALL.
102 fn restore_context(&mut self);
103}
104
105/// A [Tracer] that does nothing.
106pub struct NoopTracer;
107
108impl Tracer for NoopTracer {
109 #[inline(always)]
110 fn start_clock_cycle(
111 &mut self,
112 _processor: &FastProcessor,
113 _execution_state: NodeExecutionState,
114 _continuation_stack: &mut ContinuationStack,
115 _current_forest: &Arc<MastForest>,
116 ) {
117 // do nothing
118 }
119
120 #[inline(always)]
121 fn record_external_node_resolution(&mut self, _node_id: MastNodeId, _forest: &Arc<MastForest>) {
122 // do nothing
123 }
124
125 #[inline(always)]
126 fn record_hasher_permute(&mut self, _hashed_state: [Felt; 12]) {
127 // do nothing
128 }
129
130 #[inline(always)]
131 fn record_hasher_build_merkle_root(&mut self, _path: Option<&MerklePath>, _root: Word) {
132 // do nothing
133 }
134
135 #[inline(always)]
136 fn record_hasher_update_merkle_root(
137 &mut self,
138 _path: Option<&MerklePath>,
139 _old_root: Word,
140 _new_root: Word,
141 ) {
142 // do nothing
143 }
144
145 #[inline(always)]
146 fn record_memory_read_element(&mut self, _element: Felt, _addr: Felt) {
147 // do nothing
148 }
149
150 #[inline(always)]
151 fn record_memory_read_word(&mut self, _word: Word, _addr: Felt) {
152 // do nothing
153 }
154
155 #[inline(always)]
156 fn record_advice_pop_stack(&mut self, _value: Felt) {
157 // do nothing
158 }
159
160 #[inline(always)]
161 fn record_advice_pop_stack_word(&mut self, _word: Word) {
162 // do nothing
163 }
164
165 #[inline(always)]
166 fn record_advice_pop_stack_dword(&mut self, _words: [Word; 2]) {
167 // do nothing
168 }
169
170 #[inline(always)]
171 fn increment_clk(&mut self) {
172 // do nothing
173 }
174
175 #[inline(always)]
176 fn increment_stack_size(&mut self, _processor: &FastProcessor) {
177 // do nothing
178 }
179
180 #[inline(always)]
181 fn decrement_stack_size(&mut self) {
182 // do nothing
183 }
184
185 #[inline(always)]
186 fn start_context(&mut self) {
187 // do nothing
188 }
189
190 #[inline(always)]
191 fn restore_context(&mut self) {
192 // do nothing
193 }
194}