Skip to main content

miden_protocol/batch/
batch_id.rs

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