Skip to main content

miden_protocol/account/patch/
code.rs

1use alloc::vec::Vec;
2
3use crate::Felt;
4use crate::account::AccountCode;
5use crate::utils::serde::{
6    ByteReader,
7    ByteWriter,
8    Deserializable,
9    DeserializationError,
10    Serializable,
11};
12
13/// Describes the update to the [`AccountCode`] of an account.
14///
15/// It carries the code of a new or upgraded account and is empty if the code did not change.
16#[derive(Debug, Clone, Default, PartialEq, Eq)]
17pub struct AccountCodePatch {
18    patch: Option<AccountCode>,
19}
20
21impl AccountCodePatch {
22    /// The domain of the code section in the patch and delta commitments.
23    const DOMAIN: Felt = Felt::from_u8(4);
24
25    /// Returns a new [`AccountCodePatch`] that updates the account code to `code`, or an empty one
26    /// if `code` is `None`.
27    pub fn new(code: Option<AccountCode>) -> Self {
28        Self { patch: code }
29    }
30
31    /// Returns `true` if this patch does not update the account code.
32    pub fn is_empty(&self) -> bool {
33        self.patch.is_none()
34    }
35
36    /// Returns a reference to the new account code, if present.
37    pub fn as_code(&self) -> Option<&AccountCode> {
38        self.patch.as_ref()
39    }
40
41    /// Consumes self and returns the new account code, if present.
42    pub fn into_code(self) -> Option<AccountCode> {
43        self.patch
44    }
45
46    /// Merges `other` into this patch. The code of `other`, if present, replaces the code of
47    /// `self`, since `other` describes the later state. Hence, the merge is not commutative.
48    pub fn merge(&mut self, other: Self) {
49        if other.patch.is_some() {
50            self.patch = other.patch;
51        }
52    }
53
54    /// Appends the code section of the patch and delta commitments to `elements`, if the code is
55    /// present.
56    pub(in crate::account) fn append_patch_elements(&self, elements: &mut Vec<Felt>) {
57        if let Some(code) = &self.patch {
58            elements.extend_from_slice(&[Self::DOMAIN, Felt::ZERO, Felt::ZERO, Felt::ZERO]);
59            elements.extend_from_slice(code.commitment().as_elements());
60        }
61    }
62}
63
64impl Serializable for AccountCodePatch {
65    fn write_into<W: ByteWriter>(&self, target: &mut W) {
66        self.patch.write_into(target);
67    }
68
69    fn get_size_hint(&self) -> usize {
70        self.patch.get_size_hint()
71    }
72}
73
74impl Deserializable for AccountCodePatch {
75    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
76        <Option<AccountCode>>::read_from(source).map(Self::new)
77    }
78}