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::DecodedPrivateAccountUpdate as PrivateAccountUpdate;
42
43impl Verify for PrivateAccountUpdate {
44 type Verified = miden_protocol::account::AccountUpdateDetails;
45 type Error = core::convert::Infallible;
46 fn verify(self) -> Result<Self::Verified, Self::Error> {
47 Ok(Self::Verified::Private)
48 }
49}
50
51pub use proto::account::DecodedStorageMapPatchEntries as StorageMapPatchEntries;
52
53impl Verify for StorageMapPatchEntries {
54 type Verified = miden_protocol::account::StorageMapPatchEntries;
55 type Error = StorageMapPatchError;
56 fn verify(self) -> Result<Self::Verified, Self::Error> {
57 let mut entries = alloc::collections::BTreeMap::new();
58 for entry in self.entries.into_inner() {
59 let (key, value) = unwrap_infallible(entry.verify());
60 if entries.insert(key, value).is_some() {
61 return Err(StorageMapPatchError::DuplicateKey(key));
62 }
63 }
64 Ok(Self::Verified::from_raw(entries))
65 }
66}
67
68pub use proto::account::DecodedStorageMapPatch as StorageMapPatch;
69
70impl Verify for StorageMapPatch {
71 type Verified = miden_protocol::account::StorageMapPatch;
72 type Error = StorageMapPatchError;
73 fn verify(self) -> Result<Self::Verified, Self::Error> {
74 use proto::account::storage_map_patch::DecodedOperation;
75 match self.operation {
76 DecodedOperation::Create(entries) => {
77 Ok(Self::Verified::Create { entries: entries.verify()? })
78 },
79 DecodedOperation::Update(entries) => {
80 let entries = entries.verify()?;
81 if entries.is_empty() {
82 return Err(StorageMapPatchError::EmptyUpdate);
83 }
84 Ok(Self::Verified::Update { entries })
85 },
86 DecodedOperation::Remove(()) => Ok(Self::Verified::Remove),
87 }
88 }
89}
90
91#[derive(Debug, thiserror::Error)]
92pub enum StorageMapPatchError {
93 #[error("entries must be non-empty for an update operation")]
94 EmptyUpdate,
95 #[error("duplicate storage map key {0:?}")]
96 DuplicateKey(miden_protocol::account::StorageMapKey),
97}
98
99pub use proto::account::DecodedStorageValuePatch as StorageValuePatch;
100
101impl Verify for StorageValuePatch {
102 type Verified = miden_protocol::account::StorageValuePatch;
103 type Error = core::convert::Infallible;
104 fn verify(self) -> Result<Self::Verified, Self::Error> {
105 use proto::account::storage_value_patch::DecodedOperation;
106 Ok(match self.operation {
107 DecodedOperation::Create(value) => Self::Verified::Create { value },
108 DecodedOperation::Update(value) => Self::Verified::Update { value },
109 DecodedOperation::Remove(()) => Self::Verified::Remove,
110 })
111 }
112}
113
114pub use proto::account::DecodedStorageSlotPatch as StorageSlotPatch;
115
116impl Verify for StorageSlotPatch {
117 type Verified = (
118 miden_protocol::account::StorageSlotName,
119 miden_protocol::account::StorageSlotPatch,
120 );
121 type Error = VerificationError;
122 fn verify(self) -> Result<Self::Verified, Self::Error> {
123 use miden_protocol::account::{StorageSlotName, StorageSlotPatch};
124 use proto::account::storage_slot_patch::DecodedPatch;
125 let name = StorageSlotName::new(self.slot_name)?;
126 let patch = match self.patch {
127 DecodedPatch::Value(value) => {
128 StorageSlotPatch::Value(unwrap_infallible(value.verify()))
129 },
130 DecodedPatch::Map(map) => StorageSlotPatch::Map(map.verify()?),
131 };
132 Ok((name, patch))
133 }
134}
135
136pub use proto::account::DecodedAccountStoragePatch as AccountStoragePatch;
137
138impl Verify for AccountStoragePatch {
139 type Verified = miden_protocol::account::AccountStoragePatch;
140 type Error = VerificationError;
141 fn verify(self) -> Result<Self::Verified, Self::Error> {
142 let slots = self.slots.verify()?;
143 Ok(Self::Verified::from_entries(slots)?)
144 }
145}
146
147pub use proto::account::DecodedAccountPatch as AccountPatch;
148
149impl Verify for AccountPatch {
150 type Verified = miden_protocol::account::AccountPatch;
151 type Error = VerificationError;
152 fn verify(self) -> Result<Self::Verified, Self::Error> {
153 if self.version != proto::account::AccountPatchVersion::V1 {
154 return Err(AccountPatchError::UnspecifiedVersion.into());
155 }
156 Ok(Self::Verified::new(
157 self.account_id.verify()?,
158 self.storage.verify()?,
159 self.vault.verify()?,
160 self.code.verify()?,
161 self.final_nonce.into_inner(),
162 )?)
163 }
164}
165
166#[derive(Debug, thiserror::Error)]
167pub enum AccountPatchError {
168 #[error("account patch version is unspecified")]
169 UnspecifiedVersion,
170}
171
172pub use proto::account::DecodedAccountUpdateDetails as AccountUpdateDetails;
173
174impl Verify for AccountUpdateDetails {
175 type Verified = miden_protocol::account::AccountUpdateDetails;
176 type Error = VerificationError;
177 fn verify(self) -> Result<Self::Verified, Self::Error> {
178 use proto::account::account_update_details::DecodedUpdate;
179 match self.update {
180 DecodedUpdate::Private(value) => Ok(unwrap_infallible(value.verify())),
181 DecodedUpdate::Public(patch) => Ok(Self::Verified::Public(patch.verify()?)),
182 }
183 }
184}