miden_protocol/block/
block_account_update.rs1use alloc::string::ToString;
2
3use crate::Word;
4use crate::account::{AccountId, AccountUpdateDetails, validate_new_public_account};
5use crate::errors::BlockAccountUpdateError;
6use crate::utils::serde::{
7 ByteReader,
8 ByteWriter,
9 Deserializable,
10 DeserializationError,
11 Serializable,
12};
13
14#[derive(Debug, Clone, PartialEq, Eq)]
20pub struct BlockAccountUpdate {
21 account_id: AccountId,
23
24 final_state_commitment: Word,
26
27 details: AccountUpdateDetails,
31}
32
33impl BlockAccountUpdate {
34 pub fn new(
36 account_id: AccountId,
37 final_state_commitment: Word,
38 details: AccountUpdateDetails,
39 ) -> Result<Self, BlockAccountUpdateError> {
40 let update = Self::new_unchecked(account_id, final_state_commitment, details);
41 update.validate()?;
42 Ok(update)
43 }
44
45 pub(crate) const fn new_unchecked(
49 account_id: AccountId,
50 final_state_commitment: Word,
51 details: AccountUpdateDetails,
52 ) -> Self {
53 Self {
54 account_id,
55 final_state_commitment,
56 details,
57 }
58 }
59
60 pub(crate) fn validate(&self) -> Result<(), BlockAccountUpdateError> {
62 self.details.validate_for_account(self.account_id)?;
63 Ok(())
64 }
65
66 pub(super) fn validate_new_account_patch(&self) -> Result<(), BlockAccountUpdateError> {
72 if let AccountUpdateDetails::Public(patch) = &self.details {
73 validate_new_public_account(patch, self.final_state_commitment)?;
74 }
75
76 Ok(())
77 }
78
79 pub fn account_id(&self) -> AccountId {
81 self.account_id
82 }
83
84 pub fn final_state_commitment(&self) -> Word {
86 self.final_state_commitment
87 }
88
89 pub fn details(&self) -> &AccountUpdateDetails {
93 &self.details
94 }
95
96 pub fn is_private(&self) -> bool {
98 self.details.is_private()
99 }
100}
101
102impl Serializable for BlockAccountUpdate {
103 fn write_into<W: ByteWriter>(&self, target: &mut W) {
104 self.account_id.write_into(target);
105 self.final_state_commitment.write_into(target);
106 self.details.write_into(target);
107 }
108}
109
110impl Deserializable for BlockAccountUpdate {
111 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
112 Self::new(
113 AccountId::read_from(source)?,
114 Word::read_from(source)?,
115 AccountUpdateDetails::read_from(source)?,
116 )
117 .map_err(|error| DeserializationError::InvalidValue(error.to_string()))
118 }
119}
120
121#[cfg(test)]
125mod tests {
126 use super::BlockAccountUpdate;
127 use crate::Word;
128 use crate::account::{AccountId, AccountPatch, AccountUpdateDetails};
129 use crate::testing::account_id::ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE;
130
131 #[test]
132 fn accepts_partial_public_account_patch() -> anyhow::Result<()> {
133 let account_id = AccountId::try_from(ACCOUNT_ID_REGULAR_PUBLIC_ACCOUNT_UPDATABLE_CODE)?;
134
135 BlockAccountUpdate::new(
136 account_id,
137 Word::empty(),
138 AccountUpdateDetails::Public(AccountPatch::empty(account_id)),
139 )?;
140
141 Ok(())
142 }
143}