Skip to main content

miden_protocol/batch/
batch_id.rs

1use alloc::string::String;
2
3use miden_crypto_derive::WordWrapper;
4
5use crate::Word;
6use crate::account::AccountId;
7use crate::transaction::{OrderedTransactionHeaders, ProvenTransaction, TransactionId};
8use crate::utils::serde::{
9    ByteReader,
10    ByteWriter,
11    Deserializable,
12    DeserializationError,
13    Serializable,
14};
15
16// BATCH ID
17// ================================================================================================
18
19/// Uniquely identifies a batch of transactions, i.e. both
20/// [`ProposedBatch`](crate::batch::ProposedBatch) and [`ProvenBatch`](crate::batch::ProvenBatch).
21///
22/// This is a sequential hash of the tuple `(TRANSACTION_ID || [account_id_suffix,
23/// account_id_prefix, 0, 0])` of all transactions and the accounts their executed against in the
24/// batch.
25#[derive(Debug, Copy, Clone, Eq, Ord, PartialEq, PartialOrd, Hash, WordWrapper)]
26pub struct BatchId(Word);
27
28impl BatchId {
29    /// Calculates a batch ID from the given set of transactions.
30    pub fn from_transactions<'tx, T>(txs: T) -> Self
31    where
32        T: Iterator<Item = &'tx ProvenTransaction>,
33    {
34        Self::from_ids(txs.map(|tx| (tx.id(), tx.account_id())))
35    }
36
37    /// Calculates a batch ID from the given transaction ID and account ID tuple.
38    pub fn from_ids(iter: impl IntoIterator<Item = (TransactionId, AccountId)>) -> Self {
39        // A batch ID commits to the set of transaction it contains which is the same computation as
40        // in OrderedTransactionHeaders, so it is reused.
41        Self(OrderedTransactionHeaders::compute_commitment(iter))
42    }
43}
44
45impl core::fmt::Display for BatchId {
46    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
47        write!(f, "{}", self.to_hex())
48    }
49}
50
51// SERIALIZATION
52// ================================================================================================
53
54impl Serializable for BatchId {
55    fn write_into<W: ByteWriter>(&self, target: &mut W) {
56        self.0.write_into(target);
57    }
58}
59
60impl Deserializable for BatchId {
61    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
62        Ok(Self(Word::read_from(source)?))
63    }
64}