miden_protocol/account/patch/
update_details.rs1use crate::account::AccountPatch;
2use crate::errors::AccountPatchError;
3use crate::utils::serde::{
4 ByteReader,
5 ByteWriter,
6 Deserializable,
7 DeserializationError,
8 Serializable,
9};
10
11#[derive(Clone, Debug, PartialEq, Eq)]
24pub enum AccountUpdateDetails {
25 Private,
27
28 Public(AccountPatch),
31}
32
33impl AccountUpdateDetails {
34 const PRIVATE_TAG: u8 = 0;
35 const PUBLIC_TAG: u8 = 1;
36
37 pub fn is_private(&self) -> bool {
39 matches!(self, Self::Private)
40 }
41
42 pub fn is_public(&self) -> bool {
44 matches!(self, Self::Public(_))
45 }
46
47 pub fn merge(self, other: AccountUpdateDetails) -> Result<Self, AccountPatchError> {
52 let merged_update = match (self, other) {
53 (AccountUpdateDetails::Private, AccountUpdateDetails::Private) => {
54 AccountUpdateDetails::Private
55 },
56 (AccountUpdateDetails::Public(mut patch), AccountUpdateDetails::Public(new_patch)) => {
57 patch.merge(new_patch)?;
58 AccountUpdateDetails::Public(patch)
59 },
60 (left, right) => {
61 return Err(AccountPatchError::IncompatibleAccountUpdates {
62 left_update_type: left.as_tag_str(),
63 right_update_type: right.as_tag_str(),
64 });
65 },
66 };
67
68 Ok(merged_update)
69 }
70
71 pub(crate) const fn as_tag_str(&self) -> &'static str {
73 match self {
74 AccountUpdateDetails::Private => "private",
75 AccountUpdateDetails::Public(_) => "public",
76 }
77 }
78}
79
80impl Serializable for AccountUpdateDetails {
84 fn write_into<W: ByteWriter>(&self, target: &mut W) {
85 match self {
86 AccountUpdateDetails::Private => {
87 Self::PRIVATE_TAG.write_into(target);
88 },
89 AccountUpdateDetails::Public(public) => {
90 Self::PUBLIC_TAG.write_into(target);
91 public.write_into(target);
92 },
93 }
94 }
95
96 fn get_size_hint(&self) -> usize {
97 let u8_size = 0u8.get_size_hint();
99
100 match self {
101 AccountUpdateDetails::Private => u8_size,
102 AccountUpdateDetails::Public(public) => u8_size + public.get_size_hint(),
103 }
104 }
105}
106
107impl Deserializable for AccountUpdateDetails {
108 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
109 match u8::read_from(source)? {
110 Self::PRIVATE_TAG => Ok(Self::Private),
111 Self::PUBLIC_TAG => Ok(Self::Public(AccountPatch::read_from(source)?)),
112 variant => Err(DeserializationError::InvalidValue(format!(
113 "Unknown variant {variant} for AccountUpdateDetails"
114 ))),
115 }
116 }
117}
118
119#[cfg(test)]
123mod tests {
124 use super::AccountUpdateDetails;
125 use crate::account::{
126 AccountCode,
127 AccountId,
128 AccountPatch,
129 AccountStoragePatch,
130 AccountVaultPatch,
131 StorageMapKey,
132 StorageSlotName,
133 };
134 use crate::asset::{Asset, FungibleAsset, NonFungibleAsset};
135 use crate::testing::account_id::ACCOUNT_ID_PRIVATE_SENDER;
136 use crate::utils::serde::Serializable;
137 use crate::{ONE, Word};
138
139 #[test]
140 fn account_update_details_size_hint() -> anyhow::Result<()> {
141 let account_id = AccountId::try_from(ACCOUNT_ID_PRIVATE_SENDER)?;
142
143 let storage_patch = AccountStoragePatch::builder()
145 .create_value(StorageSlotName::mock(2), Word::from([1, 1, 1, 1u32]))
146 .create_value(StorageSlotName::mock(3), Word::from([1, 1, 0, 1u32]))
147 .create_map(
148 StorageSlotName::mock(4),
149 [(StorageMapKey::from_array([1, 1, 1, 1]), Word::from([1, 1, 1, 1u32]))],
150 )
151 .build();
152
153 let non_fungible: Asset = NonFungibleAsset::mock(&[6]);
154 let fungible: Asset = FungibleAsset::mock(42);
155 let vault_patch = AccountVaultPatch::with_assets([non_fungible, fungible]);
156
157 let account_patch = AccountPatch::new(
158 account_id,
159 storage_patch,
160 vault_patch,
161 Some(AccountCode::mock()),
162 Some(ONE),
163 )?;
164
165 let update_details_private = AccountUpdateDetails::Private;
166 assert_eq!(update_details_private.to_bytes().len(), update_details_private.get_size_hint());
167
168 let update_details_patch = AccountUpdateDetails::Public(account_patch);
169 assert_eq!(update_details_patch.to_bytes().len(), update_details_patch.get_size_hint());
170
171 assert!(update_details_patch.get_size_hint() > update_details_private.get_size_hint());
174
175 Ok(())
176 }
177}