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