miden_objects/transaction/inputs/
account.rs

1use crate::Word;
2use crate::account::{AccountCode, AccountId, PartialAccount, PartialStorage};
3use crate::asset::PartialVault;
4use crate::block::AccountWitness;
5use crate::crypto::merkle::{SmtProof, SmtProofError};
6use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
7
8// ACCOUNT INPUTS
9// ================================================================================================
10
11/// Contains information about an account, with everything required to execute a transaction.
12///
13/// `AccountInputs` combines a partial account representation with the merkle proof that verifies
14/// the account's inclusion in the account tree. The partial account should contain verifiable
15/// access to the parts of the state of the account of which the transaction will make use.
16#[derive(Clone, Debug, PartialEq, Eq)]
17pub struct AccountInputs {
18    /// Partial representation of the account's state.
19    partial_account: PartialAccount,
20    /// Proof of the account's inclusion in the account tree for this account's state commitment.
21    witness: AccountWitness,
22}
23
24impl AccountInputs {
25    /// Creates a new instance of `AccountInputs` with the specified partial account and witness.
26    pub fn new(partial_account: PartialAccount, witness: AccountWitness) -> AccountInputs {
27        AccountInputs { partial_account, witness }
28    }
29
30    /// Returns the account ID.
31    pub fn id(&self) -> AccountId {
32        self.partial_account.id()
33    }
34
35    /// Returns a reference to the partial account representation.
36    pub fn account(&self) -> &PartialAccount {
37        &self.partial_account
38    }
39
40    /// Returns a reference to the account code.
41    pub fn code(&self) -> &AccountCode {
42        self.partial_account.code()
43    }
44
45    /// Returns a reference to the partial representation of the account storage.
46    pub fn storage(&self) -> &PartialStorage {
47        self.partial_account.storage()
48    }
49
50    /// Returns a reference to the partial vault representation of the account.
51    pub fn vault(&self) -> &PartialVault {
52        self.partial_account.vault()
53    }
54
55    /// Returns a reference to the account's witness.
56    pub fn witness(&self) -> &AccountWitness {
57        &self.witness
58    }
59
60    /// Decomposes the `AccountInputs` into its constituent parts.
61    pub fn into_parts(self) -> (PartialAccount, AccountWitness) {
62        (self.partial_account, self.witness)
63    }
64
65    /// Computes the account root based on the account witness.
66    /// This root should be equal to the account root in the reference block header.
67    pub fn compute_account_root(&self) -> Result<Word, SmtProofError> {
68        let smt_merkle_path = self.witness.path().clone();
69        let smt_leaf = self.witness.leaf();
70        let root = SmtProof::new(smt_merkle_path, smt_leaf)?.compute_root();
71
72        Ok(root)
73    }
74}
75
76impl Serializable for AccountInputs {
77    fn write_into<W: ByteWriter>(&self, target: &mut W) {
78        target.write(&self.partial_account);
79        target.write(&self.witness);
80    }
81}
82
83impl Deserializable for AccountInputs {
84    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
85        let partial_account = source.read()?;
86        let witness = source.read()?;
87
88        Ok(AccountInputs { partial_account, witness })
89    }
90}
91
92// TESTS
93// ================================================================================================
94
95#[cfg(test)]
96mod tests {
97    use alloc::vec::Vec;
98
99    use miden_core::Felt;
100    use miden_core::utils::{Deserializable, Serializable};
101    use miden_crypto::merkle::MerklePath;
102    use miden_processor::SMT_DEPTH;
103
104    use crate::account::{Account, AccountCode, AccountId, AccountStorage};
105    use crate::asset::AssetVault;
106    use crate::block::AccountWitness;
107    use crate::testing::account_id::ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE;
108    use crate::transaction::AccountInputs;
109
110    #[test]
111    fn serde_roundtrip() {
112        let id = AccountId::try_from(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_IMMUTABLE_CODE).unwrap();
113        let code = AccountCode::mock();
114        let vault = AssetVault::new(&[]).unwrap();
115        let storage = AccountStorage::new(vec![]).unwrap();
116        let account = Account::from_parts(id, vault, storage, code, Felt::new(10));
117
118        let commitment = account.commitment();
119
120        let mut merkle_nodes = Vec::with_capacity(SMT_DEPTH as usize);
121        for _ in 0..(SMT_DEPTH as usize) {
122            merkle_nodes.push(commitment);
123        }
124        let merkle_path = MerklePath::new(merkle_nodes);
125
126        let fpi_inputs = AccountInputs::new(
127            account.into(),
128            AccountWitness::new(id, commitment, merkle_path).unwrap(),
129        );
130
131        let serialized = fpi_inputs.to_bytes();
132        let deserialized = AccountInputs::read_from_bytes(&serialized).unwrap();
133        assert_eq!(deserialized, fpi_inputs);
134    }
135}