miden_objects/decoded/account/
patch.rs1use miden_protobuf::unwrap_infallible;
2pub use proto::account::DecodedAccountVaultPatchEntry as AccountVaultPatchEntry;
3
4use crate::decoded::VerificationError;
5use crate::{Verify, proto};
6
7#[cfg(test)]
8mod tests;
9
10impl Verify for AccountVaultPatchEntry {
11 type Verified = (miden_protocol::asset::AssetId, miden_protocol::Word);
12 type Error = miden_protocol::errors::AssetError;
13 fn verify(self) -> Result<Self::Verified, Self::Error> {
14 Ok((self.asset_id.try_into()?, self.value))
15 }
16}
17
18pub use proto::account::DecodedAccountVaultPatch as AccountVaultPatch;
19
20impl Verify for AccountVaultPatch {
21 type Verified = miden_protocol::account::AccountVaultPatch;
22 type Error = VerificationError;
23 fn verify(self) -> Result<Self::Verified, Self::Error> {
24 let mut entries = alloc::collections::BTreeMap::new();
25 for entry in self.entries.into_inner() {
26 let (id, value) = entry.verify()?;
27 if entries.insert(id, value).is_some() {
28 return Err(VaultPatchError::DuplicateAssetId(id).into());
29 }
30 }
31 Ok(Self::Verified::new(entries)?)
32 }
33}
34
35#[derive(Debug, thiserror::Error)]
36pub enum VaultPatchError {
37 #[error("duplicate vault asset ID {0}")]
38 DuplicateAssetId(miden_protocol::asset::AssetId),
39}
40
41pub use proto::account::DecodedAccountCodePatch as AccountCodePatch;
42
43impl Verify for AccountCodePatch {
44 type Verified = miden_protocol::account::AccountCodePatch;
45 type Error = VerificationError;
46 fn verify(self) -> Result<Self::Verified, Self::Error> {
47 Ok(Self::Verified::new(self.code.verify()?))
48 }
49}
50
51pub use proto::account::DecodedPrivateAccountUpdate as PrivateAccountUpdate;
52
53impl Verify for PrivateAccountUpdate {
54 type Verified = miden_protocol::account::AccountUpdateDetails;
55 type Error = core::convert::Infallible;
56 fn verify(self) -> Result<Self::Verified, Self::Error> {
57 Ok(Self::Verified::Private)
58 }
59}
60
61pub use proto::account::DecodedStorageMapPatchEntries as StorageMapPatchEntries;
62
63impl Verify for StorageMapPatchEntries {
64 type Verified = miden_protocol::account::StorageMapPatchEntries;
65 type Error = StorageMapPatchError;
66 fn verify(self) -> Result<Self::Verified, Self::Error> {
67 let mut entries = alloc::collections::BTreeMap::new();
68 for entry in self.entries.into_inner() {
69 let (key, value) = unwrap_infallible(entry.verify());
70 if entries.insert(key, value).is_some() {
71 return Err(StorageMapPatchError::DuplicateKey(key));
72 }
73 }
74 Ok(Self::Verified::from_raw(entries))
75 }
76}
77
78pub use proto::account::DecodedStorageMapPatch as StorageMapPatch;
79
80impl Verify for StorageMapPatch {
81 type Verified = miden_protocol::account::StorageMapPatch;
82 type Error = StorageMapPatchError;
83 fn verify(self) -> Result<Self::Verified, Self::Error> {
84 use proto::account::storage_map_patch::DecodedOperation;
85 match self.operation {
86 DecodedOperation::Create(entries) => {
87 Ok(Self::Verified::Create { entries: entries.verify()? })
88 },
89 DecodedOperation::Update(entries) => {
90 let entries = entries.verify()?;
91 if entries.is_empty() {
92 return Err(StorageMapPatchError::EmptyUpdate);
93 }
94 Ok(Self::Verified::Update { entries })
95 },
96 DecodedOperation::Remove(()) => Ok(Self::Verified::Remove),
97 }
98 }
99}
100
101#[derive(Debug, thiserror::Error)]
102pub enum StorageMapPatchError {
103 #[error("entries must be non-empty for an update operation")]
104 EmptyUpdate,
105 #[error("duplicate storage map key {0:?}")]
106 DuplicateKey(miden_protocol::account::StorageMapKey),
107}
108
109pub use proto::account::DecodedStorageValuePatch as StorageValuePatch;
110
111impl Verify for StorageValuePatch {
112 type Verified = miden_protocol::account::StorageValuePatch;
113 type Error = core::convert::Infallible;
114 fn verify(self) -> Result<Self::Verified, Self::Error> {
115 use proto::account::storage_value_patch::DecodedOperation;
116 Ok(match self.operation {
117 DecodedOperation::Create(value) => Self::Verified::Create { value },
118 DecodedOperation::Update(value) => Self::Verified::Update { value },
119 DecodedOperation::Remove(()) => Self::Verified::Remove,
120 })
121 }
122}
123
124pub use proto::account::DecodedStorageSlotPatch as StorageSlotPatch;
125
126impl Verify for StorageSlotPatch {
127 type Verified = (
128 miden_protocol::account::StorageSlotName,
129 miden_protocol::account::StorageSlotPatch,
130 );
131 type Error = VerificationError;
132 fn verify(self) -> Result<Self::Verified, Self::Error> {
133 use miden_protocol::account::{StorageSlotName, StorageSlotPatch};
134 use proto::account::storage_slot_patch::DecodedPatch;
135 let name = StorageSlotName::new(self.slot_name)?;
136 let patch = match self.patch {
137 DecodedPatch::Value(value) => {
138 StorageSlotPatch::Value(unwrap_infallible(value.verify()))
139 },
140 DecodedPatch::Map(map) => StorageSlotPatch::Map(map.verify()?),
141 };
142 Ok((name, patch))
143 }
144}
145
146pub use proto::account::DecodedAccountStoragePatch as AccountStoragePatch;
147
148impl Verify for AccountStoragePatch {
149 type Verified = miden_protocol::account::AccountStoragePatch;
150 type Error = VerificationError;
151 fn verify(self) -> Result<Self::Verified, Self::Error> {
152 let slots = self.slots.verify()?;
153 Ok(Self::Verified::from_entries(slots)?)
154 }
155}
156
157pub use proto::account::DecodedAccountPatch as AccountPatch;
158
159impl Verify for AccountPatch {
160 type Verified = miden_protocol::account::AccountPatch;
161 type Error = VerificationError;
162 fn verify(self) -> Result<Self::Verified, Self::Error> {
163 if self.version != proto::account::AccountPatchVersion::V1 {
164 return Err(AccountPatchError::UnspecifiedVersion.into());
165 }
166 Ok(Self::Verified::new(
167 self.account_id.verify()?,
168 self.storage.verify()?,
169 self.vault.verify()?,
170 self.code.verify()?,
171 self.final_nonce.into_inner(),
172 )?)
173 }
174}
175
176#[derive(Debug, thiserror::Error)]
177pub enum AccountPatchError {
178 #[error("account patch version is unspecified")]
179 UnspecifiedVersion,
180}
181
182pub use proto::account::DecodedAccountUpdateDetails as AccountUpdateDetails;
183
184impl Verify for AccountUpdateDetails {
185 type Verified = miden_protocol::account::AccountUpdateDetails;
186 type Error = VerificationError;
187 fn verify(self) -> Result<Self::Verified, Self::Error> {
188 use proto::account::account_update_details::DecodedUpdate;
189 match self.update {
190 DecodedUpdate::Private(value) => Ok(unwrap_infallible(value.verify())),
191 DecodedUpdate::Public(patch) => Ok(Self::Verified::Public(patch.verify()?)),
192 }
193 }
194}