miden_protocol/batch/
proven_batch.rs1use alloc::collections::BTreeMap;
2use alloc::string::ToString;
3use alloc::vec::Vec;
4
5use crate::account::AccountId;
6use crate::batch::{BatchAccountUpdate, BatchId};
7use crate::block::BlockNumber;
8use crate::errors::ProvenBatchError;
9use crate::note::Nullifier;
10use crate::transaction::{InputNoteCommitment, InputNotes, OrderedTransactionHeaders, OutputNote};
11use crate::utils::serde::{
12 ByteReader,
13 ByteWriter,
14 Deserializable,
15 DeserializationError,
16 Serializable,
17};
18use crate::vm::ExecutionProof;
19use crate::{MIN_PROOF_SECURITY_LEVEL, Word};
20
21#[derive(Debug, Clone, PartialEq, Eq)]
24pub struct ProvenBatch {
25 id: BatchId,
26 reference_block_commitment: Word,
27 reference_block_num: BlockNumber,
28 account_updates: BTreeMap<AccountId, BatchAccountUpdate>,
29 input_notes: InputNotes<InputNoteCommitment>,
30 output_notes: Vec<OutputNote>,
31 batch_expiration_block_num: BlockNumber,
32 transactions: OrderedTransactionHeaders,
33 proof: ExecutionProof,
34}
35
36impl ProvenBatch {
37 #[allow(clippy::too_many_arguments)]
50 pub fn new_unchecked(
51 id: BatchId,
52 reference_block_commitment: Word,
53 reference_block_num: BlockNumber,
54 account_updates: BTreeMap<AccountId, BatchAccountUpdate>,
55 input_notes: InputNotes<InputNoteCommitment>,
56 output_notes: Vec<OutputNote>,
57 batch_expiration_block_num: BlockNumber,
58 transactions: OrderedTransactionHeaders,
59 proof: ExecutionProof,
60 ) -> Result<Self, ProvenBatchError> {
61 if batch_expiration_block_num <= reference_block_num {
63 return Err(ProvenBatchError::InvalidBatchExpirationBlockNum {
64 batch_expiration_block_num,
65 reference_block_num,
66 });
67 }
68
69 Ok(Self {
70 id,
71 reference_block_commitment,
72 reference_block_num,
73 account_updates,
74 input_notes,
75 output_notes,
76 batch_expiration_block_num,
77 transactions,
78 proof,
79 })
80 }
81
82 pub fn id(&self) -> BatchId {
87 self.id
88 }
89
90 pub fn reference_block_commitment(&self) -> Word {
92 self.reference_block_commitment
93 }
94
95 pub fn reference_block_num(&self) -> BlockNumber {
97 self.reference_block_num
98 }
99
100 pub fn batch_expiration_block_num(&self) -> BlockNumber {
102 self.batch_expiration_block_num
103 }
104
105 pub fn updated_accounts(&self) -> impl Iterator<Item = AccountId> + use<'_> {
107 self.account_updates.keys().copied()
108 }
109
110 pub fn proof_security_level(&self) -> u32 {
112 MIN_PROOF_SECURITY_LEVEL
113 }
114
115 pub fn account_updates(&self) -> &BTreeMap<AccountId, BatchAccountUpdate> {
125 &self.account_updates
126 }
127
128 pub fn input_notes(&self) -> &InputNotes<InputNoteCommitment> {
130 &self.input_notes
131 }
132
133 pub fn created_nullifiers(&self) -> impl Iterator<Item = Nullifier> + use<'_> {
135 self.input_notes.iter().map(InputNoteCommitment::nullifier)
136 }
137
138 pub fn output_notes(&self) -> &[OutputNote] {
143 &self.output_notes
144 }
145
146 pub fn transactions(&self) -> &OrderedTransactionHeaders {
148 &self.transactions
149 }
150
151 pub fn proof(&self) -> &ExecutionProof {
153 &self.proof
154 }
155
156 pub fn into_transactions(self) -> OrderedTransactionHeaders {
161 self.transactions
162 }
163}
164
165impl Serializable for ProvenBatch {
169 fn write_into<W: ByteWriter>(&self, target: &mut W) {
170 self.reference_block_commitment.write_into(target);
171 self.reference_block_num.write_into(target);
172 self.account_updates.write_into(target);
173 self.input_notes.write_into(target);
174 self.output_notes.write_into(target);
175 self.batch_expiration_block_num.write_into(target);
176 self.transactions.write_into(target);
177 self.proof.write_into(target);
178 }
179}
180
181impl Deserializable for ProvenBatch {
182 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
183 let reference_block_commitment = Word::read_from(source)?;
184 let reference_block_num = BlockNumber::read_from(source)?;
185 let account_updates = BTreeMap::read_from(source)?;
186 let input_notes = InputNotes::<InputNoteCommitment>::read_from(source)?;
187 let output_notes = Vec::<OutputNote>::read_from(source)?;
188 let batch_expiration_block_num = BlockNumber::read_from(source)?;
189 let transactions = OrderedTransactionHeaders::read_from(source)?;
190 let proof = ExecutionProof::read_from(source)?;
191
192 let id =
193 BatchId::from_ids(transactions.as_slice().iter().map(|tx| (tx.id(), tx.account_id())));
194
195 Self::new_unchecked(
196 id,
197 reference_block_commitment,
198 reference_block_num,
199 account_updates,
200 input_notes,
201 output_notes,
202 batch_expiration_block_num,
203 transactions,
204 proof,
205 )
206 .map_err(|e| DeserializationError::UnknownError(e.to_string()))
207 }
208}