miden_node_proto/domain/
account.rs1use std::fmt::{Debug, Display, Formatter};
2
3use miden_node_utils::formatting::format_opt;
4use miden_objects::{
5 account::{Account, AccountHeader, AccountId},
6 block::BlockNumber,
7 crypto::{hash::rpo::RpoDigest, merkle::MerklePath},
8 utils::{Deserializable, Serializable},
9 Digest,
10};
11
12use super::try_convert;
13use crate::{
14 errors::{ConversionError, MissingFieldHelper},
15 generated as proto,
16};
17
18impl Display for proto::account::AccountId {
22 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
23 write!(f, "0x")?;
24 for byte in &self.id {
25 write!(f, "{byte:02x}")?;
26 }
27 Ok(())
28 }
29}
30
31impl Debug for proto::account::AccountId {
32 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
33 Display::fmt(self, f)
34 }
35}
36
37impl From<&AccountId> for proto::account::AccountId {
41 fn from(account_id: &AccountId) -> Self {
42 (*account_id).into()
43 }
44}
45
46impl From<AccountId> for proto::account::AccountId {
47 fn from(account_id: AccountId) -> Self {
48 Self { id: account_id.to_bytes() }
49 }
50}
51
52impl TryFrom<proto::account::AccountId> for AccountId {
56 type Error = ConversionError;
57
58 fn try_from(account_id: proto::account::AccountId) -> Result<Self, Self::Error> {
59 AccountId::read_from_bytes(&account_id.id).map_err(|_| ConversionError::NotAValidFelt)
60 }
61}
62
63#[derive(Debug, PartialEq)]
67pub struct AccountSummary {
68 pub account_id: AccountId,
69 pub account_hash: RpoDigest,
70 pub block_num: BlockNumber,
71}
72
73impl From<&AccountSummary> for proto::account::AccountSummary {
74 fn from(update: &AccountSummary) -> Self {
75 Self {
76 account_id: Some(update.account_id.into()),
77 account_hash: Some(update.account_hash.into()),
78 block_num: update.block_num.as_u32(),
79 }
80 }
81}
82
83#[derive(Debug, PartialEq)]
84pub struct AccountInfo {
85 pub summary: AccountSummary,
86 pub details: Option<Account>,
87}
88
89impl From<&AccountInfo> for proto::account::AccountInfo {
90 fn from(AccountInfo { summary, details }: &AccountInfo) -> Self {
91 Self {
92 summary: Some(summary.into()),
93 details: details.as_ref().map(miden_objects::utils::Serializable::to_bytes),
94 }
95 }
96}
97
98pub struct AccountProofRequest {
103 pub account_id: AccountId,
104 pub storage_requests: Vec<StorageMapKeysProof>,
105}
106
107impl TryInto<AccountProofRequest> for proto::requests::get_account_proofs_request::AccountRequest {
108 type Error = ConversionError;
109
110 fn try_into(self) -> Result<AccountProofRequest, Self::Error> {
111 let proto::requests::get_account_proofs_request::AccountRequest {
112 account_id,
113 storage_requests,
114 } = self;
115
116 Ok(AccountProofRequest {
117 account_id: account_id
118 .clone()
119 .ok_or(proto::requests::get_account_proofs_request::AccountRequest::missing_field(
120 stringify!(account_id),
121 ))?
122 .try_into()?,
123 storage_requests: try_convert(storage_requests)?,
124 })
125 }
126}
127
128pub struct StorageMapKeysProof {
130 pub storage_index: u8,
132 pub storage_keys: Vec<Digest>,
134}
135
136impl TryInto<StorageMapKeysProof> for proto::requests::get_account_proofs_request::StorageRequest {
137 type Error = ConversionError;
138
139 fn try_into(self) -> Result<StorageMapKeysProof, Self::Error> {
140 let proto::requests::get_account_proofs_request::StorageRequest {
141 storage_slot_index,
142 map_keys,
143 } = self;
144
145 Ok(StorageMapKeysProof {
146 storage_index: storage_slot_index.try_into()?,
147 storage_keys: try_convert(map_keys)?,
148 })
149 }
150}
151
152#[derive(Clone, Debug)]
156pub struct AccountInputRecord {
157 pub account_id: AccountId,
158 pub account_hash: Digest,
159 pub proof: MerklePath,
160}
161
162impl From<AccountInputRecord> for proto::responses::AccountBlockInputRecord {
163 fn from(from: AccountInputRecord) -> Self {
164 Self {
165 account_id: Some(from.account_id.into()),
166 account_hash: Some(from.account_hash.into()),
167 proof: Some(Into::into(&from.proof)),
168 }
169 }
170}
171
172impl TryFrom<proto::responses::AccountBlockInputRecord> for AccountInputRecord {
173 type Error = ConversionError;
174
175 fn try_from(
176 account_input_record: proto::responses::AccountBlockInputRecord,
177 ) -> Result<Self, Self::Error> {
178 Ok(Self {
179 account_id: account_input_record
180 .account_id
181 .ok_or(proto::responses::AccountBlockInputRecord::missing_field(stringify!(
182 account_id
183 )))?
184 .try_into()?,
185 account_hash: account_input_record
186 .account_hash
187 .ok_or(proto::responses::AccountBlockInputRecord::missing_field(stringify!(
188 account_hash
189 )))?
190 .try_into()?,
191 proof: account_input_record
192 .proof
193 .as_ref()
194 .ok_or(proto::responses::AccountBlockInputRecord::missing_field(stringify!(proof)))?
195 .try_into()?,
196 })
197 }
198}
199
200#[derive(Debug)]
205pub struct AccountState {
206 pub account_id: AccountId,
208 pub account_hash: Option<Digest>,
210}
211
212impl Display for AccountState {
213 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
214 f.write_fmt(format_args!(
215 "{{ account_id: {}, account_hash: {} }}",
216 self.account_id,
217 format_opt(self.account_hash.as_ref()),
218 ))
219 }
220}
221
222impl From<AccountState> for proto::responses::AccountTransactionInputRecord {
223 fn from(from: AccountState) -> Self {
224 Self {
225 account_id: Some(from.account_id.into()),
226 account_hash: from.account_hash.map(Into::into),
227 }
228 }
229}
230
231impl From<AccountHeader> for proto::account::AccountHeader {
232 fn from(from: AccountHeader) -> Self {
233 Self {
234 vault_root: Some(from.vault_root().into()),
235 storage_commitment: Some(from.storage_commitment().into()),
236 code_commitment: Some(from.code_commitment().into()),
237 nonce: from.nonce().into(),
238 }
239 }
240}
241
242impl TryFrom<proto::responses::AccountTransactionInputRecord> for AccountState {
243 type Error = ConversionError;
244
245 fn try_from(
246 from: proto::responses::AccountTransactionInputRecord,
247 ) -> Result<Self, Self::Error> {
248 let account_id = from
249 .account_id
250 .ok_or(proto::responses::AccountTransactionInputRecord::missing_field(stringify!(
251 account_id
252 )))?
253 .try_into()?;
254
255 let account_hash = from
256 .account_hash
257 .ok_or(proto::responses::AccountTransactionInputRecord::missing_field(stringify!(
258 account_hash
259 )))?
260 .try_into()?;
261
262 let account_hash = if account_hash == Digest::default() {
265 None
266 } else {
267 Some(account_hash)
268 };
269
270 Ok(Self { account_id, account_hash })
271 }
272}