Skip to main content

miden_protocol/account/code/
procedure.rs

1use alloc::string::String;
2use alloc::sync::Arc;
3
4use miden_core::mast::MastForest;
5use miden_core::prettier::PrettyPrint;
6use miden_processor::{MastNode, MastNodeExt, MastNodeId};
7use miden_protocol_macros::WordWrapper;
8
9use super::Felt;
10use crate::Word;
11use crate::utils::serde::{
12    ByteReader,
13    ByteWriter,
14    Deserializable,
15    DeserializationError,
16    Serializable,
17};
18
19// ACCOUNT PROCEDURE ROOT
20// ================================================================================================
21
22/// The MAST root of a public procedure in an account's interface.
23#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, WordWrapper)]
24pub struct AccountProcedureRoot(Word);
25
26impl AccountProcedureRoot {
27    /// The number of field elements that represent an [`AccountProcedureRoot`] in kernel memory.
28    pub const NUM_ELEMENTS: usize = 4;
29
30    // PUBLIC ACCESSORS
31    // --------------------------------------------------------------------------------------------
32
33    /// Returns a reference to the procedure's mast root.
34    pub fn mast_root(&self) -> &Word {
35        &self.0
36    }
37}
38
39impl From<AccountProcedureRoot> for Word {
40    fn from(root: AccountProcedureRoot) -> Self {
41        *root.mast_root()
42    }
43}
44
45impl Serializable for AccountProcedureRoot {
46    fn write_into<W: ByteWriter>(&self, target: &mut W) {
47        target.write(self.0);
48    }
49
50    fn get_size_hint(&self) -> usize {
51        self.0.get_size_hint()
52    }
53}
54
55impl Deserializable for AccountProcedureRoot {
56    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
57        let mast_root: Word = source.read()?;
58        Ok(Self::from_raw(mast_root))
59    }
60}
61
62// PRINTABLE PROCEDURE
63// ================================================================================================
64
65/// A printable representation of a single account procedure.
66#[derive(Debug, Clone)]
67pub struct PrintableProcedure {
68    mast: Arc<MastForest>,
69    procedure_root: AccountProcedureRoot,
70    entrypoint: MastNodeId,
71}
72
73impl PrintableProcedure {
74    /// Creates a new PrintableProcedure instance from its components.
75    pub(crate) fn new(
76        mast: Arc<MastForest>,
77        procedure_root: AccountProcedureRoot,
78        entrypoint: MastNodeId,
79    ) -> Self {
80        Self { mast, procedure_root, entrypoint }
81    }
82
83    fn entrypoint(&self) -> &MastNode {
84        &self.mast[self.entrypoint]
85    }
86
87    pub(crate) fn mast_root(&self) -> &Word {
88        self.procedure_root.mast_root()
89    }
90}
91
92impl PrettyPrint for PrintableProcedure {
93    fn render(&self) -> miden_core::prettier::Document {
94        use miden_core::prettier::*;
95
96        indent(
97            4,
98            const_text("begin") + nl() + self.entrypoint().to_pretty_print(&self.mast).render(),
99        ) + nl()
100            + const_text("end")
101    }
102}
103
104// TESTS
105// ================================================================================================
106
107#[cfg(test)]
108mod tests {
109
110    use miden_crypto::utils::{Deserializable, Serializable};
111
112    use crate::account::{AccountCode, AccountProcedureRoot};
113
114    #[test]
115    fn test_serde_account_procedure() {
116        let account_code = AccountCode::mock();
117
118        let serialized = account_code.procedures()[0].to_bytes();
119        let deserialized = AccountProcedureRoot::read_from_bytes(&serialized).unwrap();
120
121        assert_eq!(account_code.procedures()[0], deserialized);
122    }
123}