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 block::BlockNumber,
11 utils::serde::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
12};
13
14#[derive(Debug, Clone, PartialEq)]
28pub struct ExecutedTransaction {
29 id: OnceCell<TransactionId>,
30 tx_inputs: TransactionInputs,
31 tx_outputs: TransactionOutputs,
32 account_delta: AccountDelta,
33 tx_args: TransactionArgs,
34 advice_witness: AdviceInputs,
35 tx_measurements: TransactionMeasurements,
36}
37
38impl ExecutedTransaction {
39 pub fn new(
47 tx_inputs: TransactionInputs,
48 tx_outputs: TransactionOutputs,
49 account_delta: AccountDelta,
50 tx_args: TransactionArgs,
51 advice_witness: AdviceInputs,
52 tx_measurements: TransactionMeasurements,
53 ) -> Self {
54 assert_eq!(tx_inputs.account().id(), tx_outputs.account.id());
56
57 Self {
58 id: OnceCell::new(),
59 tx_inputs,
60 tx_outputs,
61 account_delta,
62 tx_args,
63 advice_witness,
64 tx_measurements,
65 }
66 }
67
68 pub fn id(&self) -> TransactionId {
73 *self.id.get_or_init(|| self.into())
74 }
75
76 pub fn account_id(&self) -> AccountId {
78 self.initial_account().id()
79 }
80
81 pub fn initial_account(&self) -> &Account {
83 self.tx_inputs.account()
84 }
85
86 pub fn final_account(&self) -> &AccountHeader {
88 &self.tx_outputs.account
89 }
90
91 pub fn input_notes(&self) -> &InputNotes<InputNote> {
93 self.tx_inputs.input_notes()
94 }
95
96 pub fn output_notes(&self) -> &OutputNotes {
98 &self.tx_outputs.output_notes
99 }
100
101 pub fn expiration_block_num(&self) -> BlockNumber {
103 self.tx_outputs.expiration_block_num
104 }
105
106 pub fn tx_args(&self) -> &TransactionArgs {
108 &self.tx_args
109 }
110
111 pub fn block_header(&self) -> &BlockHeader {
113 self.tx_inputs.block_header()
114 }
115
116 pub fn account_delta(&self) -> &AccountDelta {
118 &self.account_delta
119 }
120
121 pub fn tx_inputs(&self) -> &TransactionInputs {
123 &self.tx_inputs
124 }
125
126 pub fn advice_witness(&self) -> &AdviceInputs {
129 &self.advice_witness
130 }
131
132 pub fn measurements(&self) -> &TransactionMeasurements {
135 &self.tx_measurements
136 }
137
138 pub fn into_parts(
143 self,
144 ) -> (AccountDelta, TransactionOutputs, TransactionWitness, TransactionMeasurements) {
145 let tx_witness = TransactionWitness {
146 tx_inputs: self.tx_inputs,
147 tx_args: self.tx_args,
148 advice_witness: self.advice_witness,
149 };
150 (self.account_delta, self.tx_outputs, tx_witness, self.tx_measurements)
151 }
152}
153
154impl From<ExecutedTransaction> for TransactionWitness {
155 fn from(tx: ExecutedTransaction) -> Self {
156 let (_, _, tx_witness, _) = tx.into_parts();
157 tx_witness
158 }
159}
160
161impl From<ExecutedTransaction> for TransactionMeasurements {
162 fn from(tx: ExecutedTransaction) -> Self {
163 let (_, _, _, tx_progress) = tx.into_parts();
164 tx_progress
165 }
166}
167
168impl Serializable for ExecutedTransaction {
169 fn write_into<W: ByteWriter>(&self, target: &mut W) {
170 self.tx_inputs.write_into(target);
171 self.tx_outputs.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_delta = AccountDelta::read_from(source)?;
184 let tx_args = TransactionArgs::read_from(source)?;
185 let advice_witness = AdviceInputs::read_from(source)?;
186 let tx_measurements = TransactionMeasurements::read_from(source)?;
187
188 Ok(Self::new(
189 tx_inputs,
190 tx_outputs,
191 account_delta,
192 tx_args,
193 advice_witness,
194 tx_measurements,
195 ))
196 }
197}
198
199#[derive(Debug, Clone, PartialEq)]
205pub struct TransactionMeasurements {
206 pub prologue: usize,
207 pub notes_processing: usize,
208 pub note_execution: Vec<(NoteId, usize)>,
209 pub tx_script_processing: usize,
210 pub epilogue: usize,
211}
212
213impl TransactionMeasurements {
214 pub fn total_cycles(&self) -> usize {
216 self.prologue + self.notes_processing + self.tx_script_processing + self.epilogue
217 }
218
219 pub fn trace_length(&self) -> usize {
222 let total_cycles = self.total_cycles();
223 total_cycles.next_power_of_two()
224 }
225}
226
227impl Serializable for TransactionMeasurements {
228 fn write_into<W: ByteWriter>(&self, target: &mut W) {
229 self.prologue.write_into(target);
230 self.notes_processing.write_into(target);
231 self.note_execution.write_into(target);
232 self.tx_script_processing.write_into(target);
233 self.epilogue.write_into(target);
234 }
235}
236
237impl Deserializable for TransactionMeasurements {
238 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
239 let prologue = usize::read_from(source)?;
240 let notes_processing = usize::read_from(source)?;
241 let note_execution = Vec::<(NoteId, usize)>::read_from(source)?;
242 let tx_script_processing = usize::read_from(source)?;
243 let epilogue = usize::read_from(source)?;
244
245 Ok(Self {
246 prologue,
247 notes_processing,
248 note_execution,
249 tx_script_processing,
250 epilogue,
251 })
252 }
253}