miden_objects/transaction/
executed_tx.rs1use alloc::vec::Vec;
2
3use super::{
4 Account,
5 AccountDelta,
6 AccountHeader,
7 AccountId,
8 AdviceInputs,
9 BlockHeader,
10 InputNote,
11 InputNotes,
12 NoteId,
13 OutputNotes,
14 TransactionArgs,
15 TransactionId,
16 TransactionInputs,
17 TransactionOutputs,
18 TransactionWitness,
19};
20use crate::asset::FungibleAsset;
21use crate::block::BlockNumber;
22use crate::utils::serde::{
23 ByteReader,
24 ByteWriter,
25 Deserializable,
26 DeserializationError,
27 Serializable,
28};
29
30#[derive(Debug, Clone, PartialEq)]
44pub struct ExecutedTransaction {
45 id: TransactionId,
46 tx_inputs: TransactionInputs,
47 tx_outputs: TransactionOutputs,
48 account_delta: AccountDelta,
49 tx_args: TransactionArgs,
50 advice_witness: AdviceInputs,
51 tx_measurements: TransactionMeasurements,
52}
53
54impl ExecutedTransaction {
55 pub fn new(
63 tx_inputs: TransactionInputs,
64 tx_outputs: TransactionOutputs,
65 account_delta: AccountDelta,
66 tx_args: TransactionArgs,
67 advice_witness: AdviceInputs,
68 tx_measurements: TransactionMeasurements,
69 ) -> Self {
70 assert_eq!(tx_inputs.account().id(), tx_outputs.account.id());
72
73 let id = TransactionId::new(
76 tx_inputs.account().init_commitment(),
77 tx_outputs.account.commitment(),
78 tx_inputs.input_notes().commitment(),
79 tx_outputs.output_notes.commitment(),
80 );
81
82 Self {
83 id,
84 tx_inputs,
85 tx_outputs,
86 account_delta,
87 tx_args,
88 advice_witness,
89 tx_measurements,
90 }
91 }
92
93 pub fn id(&self) -> TransactionId {
98 self.id
99 }
100
101 pub fn account_id(&self) -> AccountId {
103 self.initial_account().id()
104 }
105
106 pub fn initial_account(&self) -> &Account {
108 self.tx_inputs.account()
109 }
110
111 pub fn final_account(&self) -> &AccountHeader {
113 &self.tx_outputs.account
114 }
115
116 pub fn input_notes(&self) -> &InputNotes<InputNote> {
118 self.tx_inputs.input_notes()
119 }
120
121 pub fn output_notes(&self) -> &OutputNotes {
123 &self.tx_outputs.output_notes
124 }
125
126 pub fn fee(&self) -> FungibleAsset {
128 self.tx_outputs.fee
129 }
130
131 pub fn expiration_block_num(&self) -> BlockNumber {
133 self.tx_outputs.expiration_block_num
134 }
135
136 pub fn tx_args(&self) -> &TransactionArgs {
138 &self.tx_args
139 }
140
141 pub fn block_header(&self) -> &BlockHeader {
143 self.tx_inputs.block_header()
144 }
145
146 pub fn account_delta(&self) -> &AccountDelta {
148 &self.account_delta
149 }
150
151 pub fn tx_inputs(&self) -> &TransactionInputs {
153 &self.tx_inputs
154 }
155
156 pub fn advice_witness(&self) -> &AdviceInputs {
159 &self.advice_witness
160 }
161
162 pub fn measurements(&self) -> &TransactionMeasurements {
165 &self.tx_measurements
166 }
167
168 pub fn into_parts(
173 self,
174 ) -> (AccountDelta, TransactionOutputs, TransactionWitness, TransactionMeasurements) {
175 let tx_witness = TransactionWitness {
176 tx_inputs: self.tx_inputs,
177 tx_args: self.tx_args,
178 advice_witness: self.advice_witness,
179 };
180 (self.account_delta, self.tx_outputs, tx_witness, self.tx_measurements)
181 }
182}
183
184impl From<ExecutedTransaction> for TransactionWitness {
185 fn from(tx: ExecutedTransaction) -> Self {
186 let (_, _, tx_witness, _) = tx.into_parts();
187 tx_witness
188 }
189}
190
191impl From<ExecutedTransaction> for TransactionMeasurements {
192 fn from(tx: ExecutedTransaction) -> Self {
193 let (_, _, _, tx_progress) = tx.into_parts();
194 tx_progress
195 }
196}
197
198impl Serializable for ExecutedTransaction {
199 fn write_into<W: ByteWriter>(&self, target: &mut W) {
200 self.tx_inputs.write_into(target);
201 self.tx_outputs.write_into(target);
202 self.account_delta.write_into(target);
203 self.tx_args.write_into(target);
204 self.advice_witness.write_into(target);
205 self.tx_measurements.write_into(target);
206 }
207}
208
209impl Deserializable for ExecutedTransaction {
210 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
211 let tx_inputs = TransactionInputs::read_from(source)?;
212 let tx_outputs = TransactionOutputs::read_from(source)?;
213 let account_delta = AccountDelta::read_from(source)?;
214 let tx_args = TransactionArgs::read_from(source)?;
215 let advice_witness = AdviceInputs::read_from(source)?;
216 let tx_measurements = TransactionMeasurements::read_from(source)?;
217
218 Ok(Self::new(
219 tx_inputs,
220 tx_outputs,
221 account_delta,
222 tx_args,
223 advice_witness,
224 tx_measurements,
225 ))
226 }
227}
228
229#[derive(Debug, Clone, PartialEq)]
235pub struct TransactionMeasurements {
236 pub prologue: usize,
237 pub notes_processing: usize,
238 pub note_execution: Vec<(NoteId, usize)>,
239 pub tx_script_processing: usize,
240 pub epilogue: usize,
241 pub after_tx_cycles_obtained: usize,
247}
248
249impl TransactionMeasurements {
250 pub fn total_cycles(&self) -> usize {
252 self.prologue + self.notes_processing + self.tx_script_processing + self.epilogue
253 }
254
255 pub fn trace_length(&self) -> usize {
258 let total_cycles = self.total_cycles();
259 total_cycles.next_power_of_two()
260 }
261}
262
263impl Serializable for TransactionMeasurements {
264 fn write_into<W: ByteWriter>(&self, target: &mut W) {
265 self.prologue.write_into(target);
266 self.notes_processing.write_into(target);
267 self.note_execution.write_into(target);
268 self.tx_script_processing.write_into(target);
269 self.epilogue.write_into(target);
270 self.after_tx_cycles_obtained.write_into(target);
271 }
272}
273
274impl Deserializable for TransactionMeasurements {
275 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
276 let prologue = usize::read_from(source)?;
277 let notes_processing = usize::read_from(source)?;
278 let note_execution = Vec::<(NoteId, usize)>::read_from(source)?;
279 let tx_script_processing = usize::read_from(source)?;
280 let epilogue = usize::read_from(source)?;
281 let after_tx_cycles_obtained = usize::read_from(source)?;
282
283 Ok(Self {
284 prologue,
285 notes_processing,
286 note_execution,
287 tx_script_processing,
288 epilogue,
289 after_tx_cycles_obtained,
290 })
291 }
292}
293
294#[cfg(test)]
298mod tests {
299 use core::marker::PhantomData;
300
301 use crate::transaction::ExecutedTransaction;
302
303 fn ensure_send<T: Send>(_: PhantomData<T>) {}
304
305 #[allow(dead_code)]
307 fn compiletime_ensure_send_for_types() {
308 ensure_send::<ExecutedTransaction>(PhantomData);
309 }
310}