miden_tx/host/
tx_progress.rs

1pub use alloc::vec::Vec;
2
3use super::{NoteId, RowIndex, TransactionMeasurements};
4
5// TRANSACTION PROGRESS
6// ================================================================================================
7
8/// Contains the information about the number of cycles for each of the transaction execution
9/// stages.
10#[derive(Clone, Default, Debug)]
11pub struct TransactionProgress {
12    prologue: CycleInterval,
13    notes_processing: CycleInterval,
14    note_execution: Vec<(NoteId, CycleInterval)>,
15    tx_script_processing: CycleInterval,
16    epilogue: CycleInterval,
17}
18
19impl TransactionProgress {
20    // STATE ACCESSORS
21    // --------------------------------------------------------------------------------------------
22
23    pub fn prologue(&self) -> &CycleInterval {
24        &self.prologue
25    }
26
27    pub fn notes_processing(&self) -> &CycleInterval {
28        &self.notes_processing
29    }
30
31    pub fn note_execution(&self) -> &Vec<(NoteId, CycleInterval)> {
32        &self.note_execution
33    }
34
35    pub fn tx_script_processing(&self) -> &CycleInterval {
36        &self.tx_script_processing
37    }
38
39    pub fn epilogue(&self) -> &CycleInterval {
40        &self.epilogue
41    }
42
43    // STATE MUTATORS
44    // --------------------------------------------------------------------------------------------
45
46    pub fn start_prologue(&mut self, cycle: RowIndex) {
47        self.prologue.set_start(cycle);
48    }
49
50    pub fn end_prologue(&mut self, cycle: RowIndex) {
51        self.prologue.set_end(cycle);
52    }
53
54    pub fn start_notes_processing(&mut self, cycle: RowIndex) {
55        self.notes_processing.set_start(cycle);
56    }
57
58    pub fn end_notes_processing(&mut self, cycle: RowIndex) {
59        self.notes_processing.set_end(cycle);
60    }
61
62    pub fn start_note_execution(&mut self, cycle: RowIndex, note_id: NoteId) {
63        self.note_execution.push((note_id, CycleInterval::new(cycle)));
64    }
65
66    pub fn end_note_execution(&mut self, cycle: RowIndex) {
67        if let Some((_, interval)) = self.note_execution.last_mut() {
68            interval.set_end(cycle)
69        }
70    }
71
72    pub fn start_tx_script_processing(&mut self, cycle: RowIndex) {
73        self.tx_script_processing.set_start(cycle);
74    }
75
76    pub fn end_tx_script_processing(&mut self, cycle: RowIndex) {
77        self.tx_script_processing.set_end(cycle);
78    }
79
80    pub fn start_epilogue(&mut self, cycle: RowIndex) {
81        self.epilogue.set_start(cycle);
82    }
83
84    pub fn end_epilogue(&mut self, cycle: RowIndex) {
85        self.epilogue.set_end(cycle);
86    }
87}
88
89impl From<TransactionProgress> for TransactionMeasurements {
90    fn from(tx_progress: TransactionProgress) -> Self {
91        let prologue = tx_progress.prologue().len();
92
93        let notes_processing = tx_progress.notes_processing().len();
94
95        let note_execution = tx_progress
96            .note_execution()
97            .iter()
98            .map(|(note_id, interval)| (*note_id, interval.len()))
99            .collect();
100
101        let tx_script_processing = tx_progress.tx_script_processing().len();
102
103        let epilogue = tx_progress.epilogue().len();
104
105        Self {
106            prologue,
107            notes_processing,
108            note_execution,
109            tx_script_processing,
110            epilogue,
111        }
112    }
113}
114
115/// Stores the cycles corresponding to the start and the end of an interval.
116#[derive(Clone, Default, Debug)]
117pub struct CycleInterval {
118    start: Option<RowIndex>,
119    end: Option<RowIndex>,
120}
121
122impl CycleInterval {
123    pub fn new(start: RowIndex) -> Self {
124        Self { start: Some(start), end: None }
125    }
126
127    pub fn set_start(&mut self, s: RowIndex) {
128        self.start = Some(s);
129    }
130
131    pub fn set_end(&mut self, e: RowIndex) {
132        self.end = Some(e);
133    }
134
135    pub fn start(&self) -> Option<RowIndex> {
136        self.start
137    }
138
139    pub fn end(&self) -> Option<RowIndex> {
140        self.end
141    }
142
143    /// Calculate the length of the interval
144    pub fn len(&self) -> usize {
145        if let Some(start) = self.start {
146            if let Some(end) = self.end {
147                if end >= start {
148                    return end - start;
149                }
150            }
151        }
152        0
153    }
154}