miden_client/store/
account.rs

1// ACCOUNT RECORD
2// ================================================================================================
3use alloc::vec::Vec;
4use core::fmt::Display;
5
6use miden_objects::{
7    Digest, Word,
8    account::{Account, AccountId},
9};
10
11/// Represents a stored account state along with its status.
12///
13/// The account should be stored in the database with its parts normalized. Meaning that the
14/// account header, vault, storage and code are stored separately. This is done to avoid data
15/// duplication as the header can reference the same elements if they have equal roots.
16#[derive(Debug)]
17pub struct AccountRecord {
18    /// Full account object.
19    account: Account,
20    /// Status of the tracked account.
21    status: AccountStatus,
22}
23
24impl AccountRecord {
25    pub fn new(account: Account, status: AccountStatus) -> Self {
26        Self { account, status }
27    }
28
29    pub fn account(&self) -> &Account {
30        &self.account
31    }
32
33    pub fn status(&self) -> &AccountStatus {
34        &self.status
35    }
36
37    pub fn is_locked(&self) -> bool {
38        self.status.is_locked()
39    }
40
41    pub fn seed(&self) -> Option<&Word> {
42        self.status.seed()
43    }
44}
45
46impl From<AccountRecord> for Account {
47    fn from(record: AccountRecord) -> Self {
48        record.account
49    }
50}
51
52// ACCOUNT STATUS
53// ================================================================================================
54
55/// Represents the status of an account tracked by the client.
56///
57/// The status of an account may change by local or external factors.
58#[derive(Debug)]
59pub enum AccountStatus {
60    /// The account is new and hasn't been used yet. The seed used to create the account is
61    /// stored in this state.
62    New { seed: Word },
63    /// The account is tracked by the node and was used at least once.
64    Tracked,
65    /// The local account state doesn't match the node's state, rendering it unusable. Only used
66    /// for private accounts.
67    Locked,
68}
69
70impl AccountStatus {
71    pub fn is_locked(&self) -> bool {
72        matches!(self, AccountStatus::Locked)
73    }
74
75    pub fn seed(&self) -> Option<&Word> {
76        match self {
77            AccountStatus::New { seed } => Some(seed),
78            _ => None,
79        }
80    }
81}
82
83impl Display for AccountStatus {
84    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
85        match self {
86            AccountStatus::New { .. } => write!(f, "New"),
87            AccountStatus::Tracked => write!(f, "Tracked"),
88            AccountStatus::Locked => write!(f, "Locked"),
89        }
90    }
91}
92
93// ACCOUNT UPDATES
94// ================================================================================================
95
96/// Contains account changes to apply to the store.
97pub struct AccountUpdates {
98    /// Updated public accounts.
99    updated_public_accounts: Vec<Account>,
100    /// Network account commitments that don't match the current tracked state for private
101    /// accounts.
102    mismatched_private_accounts: Vec<(AccountId, Digest)>,
103}
104
105impl AccountUpdates {
106    /// Creates a new instance of `AccountUpdates`.
107    pub fn new(
108        updated_public_accounts: Vec<Account>,
109        mismatched_private_accounts: Vec<(AccountId, Digest)>,
110    ) -> Self {
111        Self {
112            updated_public_accounts,
113            mismatched_private_accounts,
114        }
115    }
116
117    /// Returns the updated public accounts.
118    pub fn updated_public_accounts(&self) -> &[Account] {
119        &self.updated_public_accounts
120    }
121
122    /// Returns the mismatched private accounts.
123    pub fn mismatched_private_accounts(&self) -> &[(AccountId, Digest)] {
124        &self.mismatched_private_accounts
125    }
126}