miden_objects/transaction/
executed_tx.rs1use alloc::vec::Vec;
2
3use super::{
4 AccountDelta,
5 AccountHeader,
6 AccountId,
7 AdviceInputs,
8 BlockHeader,
9 InputNote,
10 InputNotes,
11 NoteId,
12 OutputNotes,
13 TransactionArgs,
14 TransactionId,
15 TransactionOutputs,
16};
17use crate::account::PartialAccount;
18use crate::asset::FungibleAsset;
19use crate::block::BlockNumber;
20use crate::transaction::TransactionInputs;
21use crate::utils::serde::{
22 ByteReader,
23 ByteWriter,
24 Deserializable,
25 DeserializationError,
26 Serializable,
27};
28
29#[derive(Debug, Clone, PartialEq)]
43pub struct ExecutedTransaction {
44 id: TransactionId,
45 tx_inputs: TransactionInputs,
46 tx_outputs: TransactionOutputs,
47 account_delta: AccountDelta,
48 tx_measurements: TransactionMeasurements,
49}
50
51impl ExecutedTransaction {
52 pub fn new(
60 tx_inputs: TransactionInputs,
61 tx_outputs: TransactionOutputs,
62 account_delta: AccountDelta,
63 tx_measurements: TransactionMeasurements,
64 ) -> Self {
65 assert_eq!(tx_inputs.account().id(), tx_outputs.account.id());
67
68 let id = TransactionId::new(
71 tx_inputs.account().initial_commitment(),
72 tx_outputs.account.commitment(),
73 tx_inputs.input_notes().commitment(),
74 tx_outputs.output_notes.commitment(),
75 );
76
77 Self {
78 id,
79 tx_inputs,
80 tx_outputs,
81 account_delta,
82 tx_measurements,
83 }
84 }
85
86 pub fn id(&self) -> TransactionId {
91 self.id
92 }
93
94 pub fn account_id(&self) -> AccountId {
96 self.initial_account().id()
97 }
98
99 pub fn initial_account(&self) -> &PartialAccount {
101 self.tx_inputs.account()
102 }
103
104 pub fn final_account(&self) -> &AccountHeader {
106 &self.tx_outputs.account
107 }
108
109 pub fn input_notes(&self) -> &InputNotes<InputNote> {
111 self.tx_inputs.input_notes()
112 }
113
114 pub fn output_notes(&self) -> &OutputNotes {
116 &self.tx_outputs.output_notes
117 }
118
119 pub fn fee(&self) -> FungibleAsset {
121 self.tx_outputs.fee
122 }
123
124 pub fn expiration_block_num(&self) -> BlockNumber {
126 self.tx_outputs.expiration_block_num
127 }
128
129 pub fn tx_args(&self) -> &TransactionArgs {
131 self.tx_inputs.tx_args()
132 }
133
134 pub fn block_header(&self) -> &BlockHeader {
136 self.tx_inputs.block_header()
137 }
138
139 pub fn account_delta(&self) -> &AccountDelta {
141 &self.account_delta
142 }
143
144 pub fn tx_inputs(&self) -> &TransactionInputs {
146 &self.tx_inputs
147 }
148
149 pub fn advice_witness(&self) -> &AdviceInputs {
152 self.tx_inputs.advice_inputs()
153 }
154
155 pub fn measurements(&self) -> &TransactionMeasurements {
158 &self.tx_measurements
159 }
160
161 pub fn into_parts(
166 self,
167 ) -> (TransactionInputs, TransactionOutputs, AccountDelta, TransactionMeasurements) {
168 (self.tx_inputs, self.tx_outputs, self.account_delta, self.tx_measurements)
169 }
170}
171
172impl From<ExecutedTransaction> for TransactionInputs {
173 fn from(tx: ExecutedTransaction) -> Self {
174 tx.tx_inputs
175 }
176}
177
178impl From<ExecutedTransaction> for TransactionMeasurements {
179 fn from(tx: ExecutedTransaction) -> Self {
180 let (_, _, _, tx_progress) = tx.into_parts();
181 tx_progress
182 }
183}
184
185impl Serializable for ExecutedTransaction {
186 fn write_into<W: ByteWriter>(&self, target: &mut W) {
187 self.tx_inputs.write_into(target);
188 self.tx_outputs.write_into(target);
189 self.account_delta.write_into(target);
190 self.tx_measurements.write_into(target);
191 }
192}
193
194impl Deserializable for ExecutedTransaction {
195 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
196 let tx_inputs = TransactionInputs::read_from(source)?;
197 let tx_outputs = TransactionOutputs::read_from(source)?;
198 let account_delta = AccountDelta::read_from(source)?;
199 let tx_measurements = TransactionMeasurements::read_from(source)?;
200
201 Ok(Self::new(tx_inputs, tx_outputs, account_delta, tx_measurements))
202 }
203}
204
205#[derive(Debug, Clone, PartialEq)]
211pub struct TransactionMeasurements {
212 pub prologue: usize,
213 pub notes_processing: usize,
214 pub note_execution: Vec<(NoteId, usize)>,
215 pub tx_script_processing: usize,
216 pub epilogue: usize,
217 pub auth_procedure: usize,
218 pub after_tx_cycles_obtained: usize,
224}
225
226impl TransactionMeasurements {
227 pub fn total_cycles(&self) -> usize {
229 self.prologue + self.notes_processing + self.tx_script_processing + self.epilogue
230 }
231
232 pub fn trace_length(&self) -> usize {
235 let total_cycles = self.total_cycles();
236 total_cycles.next_power_of_two()
237 }
238}
239
240impl Serializable for TransactionMeasurements {
241 fn write_into<W: ByteWriter>(&self, target: &mut W) {
242 self.prologue.write_into(target);
243 self.notes_processing.write_into(target);
244 self.note_execution.write_into(target);
245 self.tx_script_processing.write_into(target);
246 self.epilogue.write_into(target);
247 self.auth_procedure.write_into(target);
248 self.after_tx_cycles_obtained.write_into(target);
249 }
250}
251
252impl Deserializable for TransactionMeasurements {
253 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
254 let prologue = usize::read_from(source)?;
255 let notes_processing = usize::read_from(source)?;
256 let note_execution = Vec::<(NoteId, usize)>::read_from(source)?;
257 let tx_script_processing = usize::read_from(source)?;
258 let epilogue = usize::read_from(source)?;
259 let auth_procedure = usize::read_from(source)?;
260 let after_tx_cycles_obtained = usize::read_from(source)?;
261
262 Ok(Self {
263 prologue,
264 notes_processing,
265 note_execution,
266 tx_script_processing,
267 epilogue,
268 auth_procedure,
269 after_tx_cycles_obtained,
270 })
271 }
272}
273
274#[cfg(test)]
278mod tests {
279 use core::marker::PhantomData;
280
281 use crate::transaction::ExecutedTransaction;
282
283 fn ensure_send<T: Send>(_: PhantomData<T>) {}
284
285 #[allow(dead_code)]
287 fn compiletime_ensure_send_for_types() {
288 ensure_send::<ExecutedTransaction>(PhantomData);
289 }
290}