miden_objects/batch/
proven_batch.rs

1use alloc::{collections::BTreeMap, vec::Vec};
2
3use crate::{
4    Digest,
5    account::AccountId,
6    batch::{BatchAccountUpdate, BatchId},
7    block::BlockNumber,
8    note::Nullifier,
9    transaction::{InputNoteCommitment, InputNotes, OutputNote},
10    utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
11};
12
13/// A transaction batch with an execution proof.
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct ProvenBatch {
16    id: BatchId,
17    reference_block_commitment: Digest,
18    reference_block_num: BlockNumber,
19    account_updates: BTreeMap<AccountId, BatchAccountUpdate>,
20    input_notes: InputNotes<InputNoteCommitment>,
21    output_notes: Vec<OutputNote>,
22    batch_expiration_block_num: BlockNumber,
23}
24
25impl ProvenBatch {
26    // CONSTRUCTORS
27    // --------------------------------------------------------------------------------------------
28
29    /// Creates a new [`ProvenBatch`] from the provided parts.
30    #[allow(clippy::too_many_arguments)]
31    pub fn new_unchecked(
32        id: BatchId,
33        reference_block_commitment: Digest,
34        reference_block_num: BlockNumber,
35        account_updates: BTreeMap<AccountId, BatchAccountUpdate>,
36        input_notes: InputNotes<InputNoteCommitment>,
37        output_notes: Vec<OutputNote>,
38        batch_expiration_block_num: BlockNumber,
39    ) -> Self {
40        Self {
41            id,
42            reference_block_commitment,
43            reference_block_num,
44            account_updates,
45            input_notes,
46            output_notes,
47            batch_expiration_block_num,
48        }
49    }
50
51    // PUBLIC ACCESSORS
52    // --------------------------------------------------------------------------------------------
53
54    /// The ID of this batch. See [`BatchId`] for details on how it is computed.
55    pub fn id(&self) -> BatchId {
56        self.id
57    }
58
59    /// Returns the commitment to the reference block of the batch.
60    pub fn reference_block_commitment(&self) -> Digest {
61        self.reference_block_commitment
62    }
63
64    /// Returns the number of the reference block of the batch.
65    pub fn reference_block_num(&self) -> BlockNumber {
66        self.reference_block_num
67    }
68
69    /// Returns the block number at which the batch will expire.
70    pub fn batch_expiration_block_num(&self) -> BlockNumber {
71        self.batch_expiration_block_num
72    }
73
74    /// Returns an iterator over the IDs of all accounts updated in this batch.
75    pub fn updated_accounts(&self) -> impl Iterator<Item = AccountId> + use<'_> {
76        self.account_updates.keys().copied()
77    }
78
79    /// Returns the map of account IDs mapped to their [`BatchAccountUpdate`]s.
80    ///
81    /// If an account was updated by multiple transactions, the [`BatchAccountUpdate`] is the result
82    /// of merging the individual updates.
83    ///
84    /// For example, suppose an account's state before this batch is `A` and the batch contains two
85    /// transactions that updated it. Applying the first transaction results in intermediate state
86    /// `B`, and applying the second one results in state `C`. Then the returned update represents
87    /// the state transition from `A` to `C`.
88    pub fn account_updates(&self) -> &BTreeMap<AccountId, BatchAccountUpdate> {
89        &self.account_updates
90    }
91
92    /// Returns the [`InputNotes`] of this batch.
93    pub fn input_notes(&self) -> &InputNotes<InputNoteCommitment> {
94        &self.input_notes
95    }
96
97    /// Returns an iterator over the nullifiers created in this batch.
98    pub fn created_nullifiers(&self) -> impl Iterator<Item = Nullifier> + use<'_> {
99        self.input_notes.iter().map(InputNoteCommitment::nullifier)
100    }
101
102    /// Returns the output notes of the batch.
103    ///
104    /// This is the aggregation of all output notes by the transactions in the batch, except the
105    /// ones that were consumed within the batch itself.
106    pub fn output_notes(&self) -> &[OutputNote] {
107        &self.output_notes
108    }
109}
110
111// SERIALIZATION
112// ================================================================================================
113
114impl Serializable for ProvenBatch {
115    fn write_into<W: ByteWriter>(&self, target: &mut W) {
116        self.id.write_into(target);
117        self.reference_block_commitment.write_into(target);
118        self.reference_block_num.write_into(target);
119        self.account_updates.write_into(target);
120        self.input_notes.write_into(target);
121        self.output_notes.write_into(target);
122        self.batch_expiration_block_num.write_into(target);
123    }
124}
125
126impl Deserializable for ProvenBatch {
127    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
128        let id = BatchId::read_from(source)?;
129        let reference_block_commitment = Digest::read_from(source)?;
130        let reference_block_num = BlockNumber::read_from(source)?;
131        let account_updates = BTreeMap::read_from(source)?;
132        let input_notes = InputNotes::<InputNoteCommitment>::read_from(source)?;
133        let output_notes = Vec::<OutputNote>::read_from(source)?;
134        let batch_expiration_block_num = BlockNumber::read_from(source)?;
135
136        Ok(Self::new_unchecked(
137            id,
138            reference_block_commitment,
139            reference_block_num,
140            account_updates,
141            input_notes,
142            output_notes,
143            batch_expiration_block_num,
144        ))
145    }
146}