miden_objects/transaction/
executed_tx.rs1use alloc::vec::Vec;
2use core::cell::OnceCell;
3
4use vm_core::utils::{ByteReader, ByteWriter, Deserializable, Serializable};
5use vm_processor::DeserializationError;
6
7use super::{
8 Account, AccountDelta, AccountHeader, AccountId, AdviceInputs, BlockHeader, InputNote,
9 InputNotes, NoteId, OutputNotes, TransactionArgs, TransactionId, TransactionInputs,
10 TransactionOutputs, TransactionWitness,
11};
12use crate::account::AccountCode;
13
14#[derive(Debug, Clone, PartialEq)]
28pub struct ExecutedTransaction {
29 id: OnceCell<TransactionId>,
30 tx_inputs: TransactionInputs,
31 tx_outputs: TransactionOutputs,
32 account_codes: Vec<AccountCode>,
33 account_delta: AccountDelta,
34 tx_args: TransactionArgs,
35 advice_witness: AdviceInputs,
36 tx_measurements: TransactionMeasurements,
37}
38
39impl ExecutedTransaction {
40 pub fn new(
48 tx_inputs: TransactionInputs,
49 tx_outputs: TransactionOutputs,
50 account_codes: Vec<AccountCode>,
51 account_delta: AccountDelta,
52 tx_args: TransactionArgs,
53 advice_witness: AdviceInputs,
54 tx_measurements: TransactionMeasurements,
55 ) -> Self {
56 assert_eq!(tx_inputs.account().id(), tx_outputs.account.id());
58
59 Self {
60 id: OnceCell::new(),
61 tx_inputs,
62 tx_outputs,
63 account_codes,
64 account_delta,
65 tx_args,
66 advice_witness,
67 tx_measurements,
68 }
69 }
70
71 pub fn id(&self) -> TransactionId {
76 *self.id.get_or_init(|| self.into())
77 }
78
79 pub fn account_id(&self) -> AccountId {
81 self.initial_account().id()
82 }
83
84 pub fn initial_account(&self) -> &Account {
86 self.tx_inputs.account()
87 }
88
89 pub fn final_account(&self) -> &AccountHeader {
91 &self.tx_outputs.account
92 }
93
94 pub fn input_notes(&self) -> &InputNotes<InputNote> {
96 self.tx_inputs.input_notes()
97 }
98
99 pub fn output_notes(&self) -> &OutputNotes {
101 &self.tx_outputs.output_notes
102 }
103
104 pub fn tx_args(&self) -> &TransactionArgs {
106 &self.tx_args
107 }
108
109 pub fn block_header(&self) -> &BlockHeader {
111 self.tx_inputs.block_header()
112 }
113
114 pub fn account_delta(&self) -> &AccountDelta {
116 &self.account_delta
117 }
118
119 pub fn tx_inputs(&self) -> &TransactionInputs {
121 &self.tx_inputs
122 }
123
124 pub fn advice_witness(&self) -> &AdviceInputs {
127 &self.advice_witness
128 }
129
130 pub fn measurements(&self) -> &TransactionMeasurements {
133 &self.tx_measurements
134 }
135
136 pub fn into_parts(
141 self,
142 ) -> (AccountDelta, TransactionOutputs, TransactionWitness, TransactionMeasurements) {
143 let tx_witness = TransactionWitness {
144 tx_inputs: self.tx_inputs,
145 tx_args: self.tx_args,
146 advice_witness: self.advice_witness,
147 account_codes: self.account_codes,
148 };
149 (self.account_delta, self.tx_outputs, tx_witness, self.tx_measurements)
150 }
151}
152
153impl From<ExecutedTransaction> for TransactionWitness {
154 fn from(tx: ExecutedTransaction) -> Self {
155 let (_, _, tx_witness, _) = tx.into_parts();
156 tx_witness
157 }
158}
159
160impl From<ExecutedTransaction> for TransactionMeasurements {
161 fn from(tx: ExecutedTransaction) -> Self {
162 let (_, _, _, tx_progress) = tx.into_parts();
163 tx_progress
164 }
165}
166
167impl Serializable for ExecutedTransaction {
168 fn write_into<W: ByteWriter>(&self, target: &mut W) {
169 self.tx_inputs.write_into(target);
170 self.tx_outputs.write_into(target);
171 self.account_codes.write_into(target);
172 self.account_delta.write_into(target);
173 self.tx_args.write_into(target);
174 self.advice_witness.write_into(target);
175 self.tx_measurements.write_into(target);
176 }
177}
178
179impl Deserializable for ExecutedTransaction {
180 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
181 let tx_inputs = TransactionInputs::read_from(source)?;
182 let tx_outputs = TransactionOutputs::read_from(source)?;
183 let account_codes = Vec::<AccountCode>::read_from(source)?;
184 let account_delta = AccountDelta::read_from(source)?;
185 let tx_args = TransactionArgs::read_from(source)?;
186 let advice_witness = AdviceInputs::read_from(source)?;
187 let tx_measurements = TransactionMeasurements::read_from(source)?;
188
189 Ok(Self::new(
190 tx_inputs,
191 tx_outputs,
192 account_codes,
193 account_delta,
194 tx_args,
195 advice_witness,
196 tx_measurements,
197 ))
198 }
199}
200
201#[derive(Debug, Clone, PartialEq)]
207pub struct TransactionMeasurements {
208 pub prologue: usize,
209 pub notes_processing: usize,
210 pub note_execution: Vec<(NoteId, usize)>,
211 pub tx_script_processing: usize,
212 pub epilogue: usize,
213}
214
215impl TransactionMeasurements {
216 pub fn total_cycles(&self) -> usize {
218 self.prologue + self.notes_processing + self.tx_script_processing + self.epilogue
219 }
220
221 pub fn trace_length(&self) -> usize {
224 let total_cycles = self.total_cycles();
225 total_cycles.next_power_of_two()
226 }
227}
228
229impl Serializable for TransactionMeasurements {
230 fn write_into<W: ByteWriter>(&self, target: &mut W) {
231 self.prologue.write_into(target);
232 self.notes_processing.write_into(target);
233 self.note_execution.write_into(target);
234 self.tx_script_processing.write_into(target);
235 self.epilogue.write_into(target);
236 }
237}
238
239impl Deserializable for TransactionMeasurements {
240 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
241 let prologue = usize::read_from(source)?;
242 let notes_processing = usize::read_from(source)?;
243 let note_execution = Vec::<(NoteId, usize)>::read_from(source)?;
244 let tx_script_processing = usize::read_from(source)?;
245 let epilogue = usize::read_from(source)?;
246
247 Ok(Self {
248 prologue,
249 notes_processing,
250 note_execution,
251 tx_script_processing,
252 epilogue,
253 })
254 }
255}