miden_protocol/account/component/
code.rs1use miden_assembly::Library;
2use miden_assembly::library::ProcedureExport;
3use miden_processor::mast::{MastForest, MastNodeExt};
4
5use crate::account::AccountProcedureRoot;
6use crate::vm::AdviceMap;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct AccountComponentCode(Library);
14
15impl AccountComponentCode {
16 pub fn as_library(&self) -> &Library {
18 &self.0
19 }
20
21 pub fn mast_forest(&self) -> &MastForest {
23 self.0.mast_forest().as_ref()
24 }
25
26 pub fn into_library(self) -> Library {
28 self.0
29 }
30
31 pub fn procedure_roots(&self) -> impl Iterator<Item = AccountProcedureRoot> + '_ {
34 self.0.exports().filter_map(|export| {
35 export.as_procedure().map(|proc_export| {
36 let digest = self.0.mast_forest()[proc_export.node].digest();
37 AccountProcedureRoot::from_raw(digest)
38 })
39 })
40 }
41
42 pub fn exports(&self) -> impl Iterator<Item = &ProcedureExport> + '_ {
44 self.0.exports().filter_map(|export| export.as_procedure())
45 }
46
47 pub fn with_advice_map(self, advice_map: AdviceMap) -> Self {
53 if advice_map.is_empty() {
54 return self;
55 }
56
57 Self(self.0.with_advice_map(advice_map))
58 }
59}
60
61impl AsRef<Library> for AccountComponentCode {
62 fn as_ref(&self) -> &Library {
63 self.as_library()
64 }
65}
66
67impl From<Library> for AccountComponentCode {
71 fn from(value: Library) -> Self {
72 Self(value)
73 }
74}
75
76impl From<AccountComponentCode> for Library {
77 fn from(value: AccountComponentCode) -> Self {
78 value.into_library()
79 }
80}
81
82#[cfg(test)]
86mod tests {
87 use alloc::sync::Arc;
88
89 use miden_core::{Felt, Word};
90
91 use super::*;
92 use crate::assembly::Assembler;
93
94 #[test]
95 fn test_account_component_code_with_advice_map() {
96 let assembler = Assembler::default();
97 let library = Arc::unwrap_or_clone(
98 assembler
99 .assemble_library(["pub proc test nop end"])
100 .expect("failed to assemble library"),
101 );
102 let component_code = AccountComponentCode::from(library);
103
104 assert!(component_code.mast_forest().advice_map().is_empty());
105
106 let cloned = component_code.clone();
108 let original_digest = cloned.as_library().digest();
109 let component_code = component_code.with_advice_map(AdviceMap::default());
110 assert_eq!(original_digest, component_code.as_library().digest());
111
112 let key = Word::from([10u32, 20, 30, 40]);
114 let value = vec![Felt::new(200)];
115 let mut advice_map = AdviceMap::default();
116 advice_map.insert(key, value.clone());
117
118 let component_code = component_code.with_advice_map(advice_map);
119
120 let mast = component_code.mast_forest();
121 let stored = mast.advice_map().get(&key).expect("entry should be present");
122 assert_eq!(stored.as_ref(), value.as_slice());
123 }
124}