miden_testing/
mock_host.rs1use alloc::boxed::Box;
2use alloc::collections::BTreeSet;
3use alloc::rc::Rc;
4use alloc::sync::Arc;
5use alloc::vec::Vec;
6
7use miden_lib::transaction::{TransactionEvent, TransactionEventError};
8use miden_objects::account::{AccountHeader, AccountVaultDelta};
9use miden_objects::assembly::debuginfo::SourceManagerSync;
10use miden_objects::assembly::{DefaultSourceManager, SourceManager};
11use miden_objects::{Felt, Word};
12use miden_processor::{
13 AdviceInputs,
14 AdviceMutation,
15 BaseHost,
16 ContextId,
17 EventError,
18 MastForest,
19 MastForestStore,
20 ProcessState,
21 SyncHost,
22};
23use miden_tx::{AccountProcedureIndexMap, LinkMap, TransactionMastStore};
24
25pub struct MockHost {
33 acct_procedure_index_map: AccountProcedureIndexMap,
34 mast_store: Rc<TransactionMastStore>,
35 source_manager: Arc<dyn SourceManagerSync>,
36}
37
38impl MockHost {
39 pub fn new(
41 account: AccountHeader,
42 advice_inputs: &AdviceInputs,
43 mast_store: Rc<TransactionMastStore>,
44 mut foreign_code_commitments: BTreeSet<Word>,
45 ) -> Self {
46 foreign_code_commitments.insert(account.code_commitment());
47 let account_procedure_index_map =
48 AccountProcedureIndexMap::new(foreign_code_commitments, advice_inputs)
49 .expect("account procedure index map should be valid");
50
51 Self {
52 acct_procedure_index_map: account_procedure_index_map,
53 mast_store,
54 source_manager: Arc::new(DefaultSourceManager::default()),
55 }
56 }
57
58 pub fn with_source_manager(mut self, source_manager: Arc<dyn SourceManagerSync>) -> Self {
60 self.source_manager = source_manager;
61 self
62 }
63
64 pub fn into_parts(self) -> AccountVaultDelta {
66 AccountVaultDelta::default()
67 }
68
69 fn on_push_account_procedure_index(
73 &mut self,
74 process: &ProcessState,
75 ) -> Result<Vec<AdviceMutation>, EventError> {
76 let proc_idx = self.acct_procedure_index_map.get_proc_index(process).map_err(Box::new)?;
77 Ok(vec![AdviceMutation::extend_stack([Felt::from(proc_idx)])])
78 }
79}
80
81impl BaseHost for MockHost {
82 fn get_mast_forest(&self, node_digest: &Word) -> Option<Arc<MastForest>> {
83 self.mast_store.get(node_digest)
84 }
85
86 fn get_label_and_source_file(
87 &self,
88 location: &miden_objects::assembly::debuginfo::Location,
89 ) -> (
90 miden_objects::assembly::debuginfo::SourceSpan,
91 Option<Arc<miden_objects::assembly::SourceFile>>,
92 ) {
93 let maybe_file = self.source_manager.get_by_uri(location.uri());
94 let span = self.source_manager.location_to_span(location.clone()).unwrap_or_default();
95 (span, maybe_file)
96 }
97}
98
99impl SyncHost for MockHost {
100 fn on_event(
101 &mut self,
102 process: &ProcessState,
103 event_id: u32,
104 ) -> Result<Vec<AdviceMutation>, EventError> {
105 let event = TransactionEvent::try_from(event_id).map_err(Box::new)?;
106
107 if process.ctx() != ContextId::root() {
108 return Err(Box::new(TransactionEventError::NotRootContext(event_id)));
109 }
110
111 let advice_mutations = match event {
112 TransactionEvent::AccountPushProcedureIndex => {
113 self.on_push_account_procedure_index(process)
114 },
115 TransactionEvent::LinkMapSetEvent => LinkMap::handle_set_event(process),
116 TransactionEvent::LinkMapGetEvent => LinkMap::handle_get_event(process),
117 _ => Ok(Vec::new()),
118 }?;
119
120 Ok(advice_mutations)
121 }
122}