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