miden_objects/batch/
account_update.rs1use alloc::boxed::Box;
2
3use crate::Word;
4use crate::account::AccountId;
5use crate::account::delta::AccountUpdateDetails;
6use crate::errors::BatchAccountUpdateError;
7use crate::transaction::ProvenTransaction;
8use crate::utils::serde::{
9    ByteReader,
10    ByteWriter,
11    Deserializable,
12    DeserializationError,
13    Serializable,
14};
15
16#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct BatchAccountUpdate {
22    account_id: AccountId,
24
25    initial_state_commitment: Word,
29
30    final_state_commitment: Word,
32
33    details: AccountUpdateDetails,
37}
38
39impl BatchAccountUpdate {
40    pub fn from_transaction(transaction: &ProvenTransaction) -> Self {
46        Self {
47            account_id: transaction.account_id(),
48            initial_state_commitment: transaction.account_update().initial_state_commitment(),
49            final_state_commitment: transaction.account_update().final_state_commitment(),
50            details: transaction.account_update().details().clone(),
51        }
52    }
53
54    #[cfg(any(feature = "testing", test))]
56    pub fn new_unchecked(
57        account_id: AccountId,
58        initial_state_commitment: Word,
59        final_state_commitment: Word,
60        details: AccountUpdateDetails,
61    ) -> Self {
62        Self {
63            account_id,
64            initial_state_commitment,
65            final_state_commitment,
66            details,
67        }
68    }
69
70    pub fn account_id(&self) -> AccountId {
75        self.account_id
76    }
77
78    pub fn initial_state_commitment(&self) -> Word {
82        self.initial_state_commitment
83    }
84
85    pub fn final_state_commitment(&self) -> Word {
87        self.final_state_commitment
88    }
89
90    pub fn details(&self) -> &AccountUpdateDetails {
94        &self.details
95    }
96
97    pub fn is_private(&self) -> bool {
99        self.details.is_private()
100    }
101
102    pub fn merge_proven_tx(
116        &mut self,
117        tx: &ProvenTransaction,
118    ) -> Result<(), BatchAccountUpdateError> {
119        if self.account_id != tx.account_id() {
120            return Err(BatchAccountUpdateError::AccountUpdateIdMismatch {
121                transaction: tx.id(),
122                expected_account_id: self.account_id,
123                actual_account_id: tx.account_id(),
124            });
125        }
126
127        if self.final_state_commitment != tx.account_update().initial_state_commitment() {
128            return Err(BatchAccountUpdateError::AccountUpdateInitialStateMismatch(tx.id()));
129        }
130
131        self.details = self.details.clone().merge(tx.account_update().details().clone()).map_err(
132            |source_err| {
133                BatchAccountUpdateError::TransactionUpdateMergeError(tx.id(), Box::new(source_err))
134            },
135        )?;
136        self.final_state_commitment = tx.account_update().final_state_commitment();
137
138        Ok(())
139    }
140
141    pub fn into_update(self) -> AccountUpdateDetails {
146        self.details
147    }
148}
149
150impl Serializable for BatchAccountUpdate {
154    fn write_into<W: ByteWriter>(&self, target: &mut W) {
155        self.account_id.write_into(target);
156        self.initial_state_commitment.write_into(target);
157        self.final_state_commitment.write_into(target);
158        self.details.write_into(target);
159    }
160}
161
162impl Deserializable for BatchAccountUpdate {
163    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
164        Ok(Self {
165            account_id: AccountId::read_from(source)?,
166            initial_state_commitment: Word::read_from(source)?,
167            final_state_commitment: Word::read_from(source)?,
168            details: AccountUpdateDetails::read_from(source)?,
169        })
170    }
171}