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}