miden_processor/host/
mod.rs1use alloc::sync::Arc;
2
3use vm_core::{DebugOptions, crypto::hash::RpoDigest, mast::MastForest};
4
5use super::{ExecutionError, ProcessState};
6use crate::{KvMap, MemAdviceProvider};
7
8pub(super) mod advice;
9use advice::AdviceProvider;
10
11#[cfg(feature = "std")]
12mod debug;
13
14mod mast_forest_store;
15pub use mast_forest_store::{MastForestStore, MemMastForestStore};
16
17pub trait Host {
28 type AdviceProvider: AdviceProvider;
29
30 fn advice_provider(&self) -> &Self::AdviceProvider;
35
36 fn advice_provider_mut(&mut self) -> &mut Self::AdviceProvider;
38
39 fn get_mast_forest(&self, node_digest: &RpoDigest) -> Option<Arc<MastForest>>;
42
43 fn on_event(&mut self, _process: ProcessState, _event_id: u32) -> Result<(), ExecutionError> {
48 #[cfg(feature = "std")]
49 std::println!(
50 "Event with id {} emitted at step {} in context {}",
51 _event_id,
52 _process.clk(),
53 _process.ctx()
54 );
55 Ok(())
56 }
57
58 fn on_debug(
60 &mut self,
61 _process: ProcessState,
62 _options: &DebugOptions,
63 ) -> Result<(), ExecutionError> {
64 #[cfg(feature = "std")]
65 debug::print_debug_info(_process, _options);
66 Ok(())
67 }
68
69 fn on_trace(&mut self, _process: ProcessState, _trace_id: u32) -> Result<(), ExecutionError> {
71 #[cfg(feature = "std")]
72 std::println!(
73 "Trace with id {} emitted at step {} in context {}",
74 _trace_id,
75 _process.clk(),
76 _process.ctx()
77 );
78 Ok(())
79 }
80
81 fn on_assert_failed(&mut self, process: ProcessState, err_code: u32) -> ExecutionError {
83 ExecutionError::FailedAssertion {
84 clk: process.clk(),
85 err_code,
86 err_msg: None,
87 }
88 }
89}
90
91impl<H> Host for &mut H
92where
93 H: Host,
94{
95 type AdviceProvider = H::AdviceProvider;
96
97 fn advice_provider(&self) -> &Self::AdviceProvider {
98 H::advice_provider(self)
99 }
100
101 fn advice_provider_mut(&mut self) -> &mut Self::AdviceProvider {
102 H::advice_provider_mut(self)
103 }
104
105 fn get_mast_forest(&self, node_digest: &RpoDigest) -> Option<Arc<MastForest>> {
106 H::get_mast_forest(self, node_digest)
107 }
108
109 fn on_debug(
110 &mut self,
111 process: ProcessState,
112 options: &DebugOptions,
113 ) -> Result<(), ExecutionError> {
114 H::on_debug(self, process, options)
115 }
116
117 fn on_event(&mut self, process: ProcessState, event_id: u32) -> Result<(), ExecutionError> {
118 H::on_event(self, process, event_id)
119 }
120
121 fn on_trace(&mut self, process: ProcessState, trace_id: u32) -> Result<(), ExecutionError> {
122 H::on_trace(self, process, trace_id)
123 }
124
125 fn on_assert_failed(&mut self, process: ProcessState, err_code: u32) -> ExecutionError {
126 H::on_assert_failed(self, process, err_code)
127 }
128}
129
130pub struct DefaultHost<A> {
135 adv_provider: A,
136 store: MemMastForestStore,
137}
138
139impl<A: Clone> Clone for DefaultHost<A> {
140 fn clone(&self) -> Self {
141 Self {
142 adv_provider: self.adv_provider.clone(),
143 store: self.store.clone(),
144 }
145 }
146}
147
148impl Default for DefaultHost<MemAdviceProvider> {
149 fn default() -> Self {
150 Self {
151 adv_provider: MemAdviceProvider::default(),
152 store: MemMastForestStore::default(),
153 }
154 }
155}
156
157impl<A: AdviceProvider> DefaultHost<A> {
158 pub fn new(adv_provider: A) -> Self {
159 Self {
160 adv_provider,
161 store: MemMastForestStore::default(),
162 }
163 }
164
165 pub fn load_mast_forest(&mut self, mast_forest: Arc<MastForest>) -> Result<(), ExecutionError> {
166 for (digest, values) in mast_forest.advice_map().iter() {
169 if let Some(stored_values) = self.advice_provider().get_mapped_values(digest) {
170 if stored_values != values {
171 return Err(ExecutionError::AdviceMapKeyAlreadyPresent(digest.into()));
172 }
173 } else {
174 self.advice_provider_mut().insert_into_map(digest.into(), values.clone());
175 }
176 }
177
178 self.store.insert(mast_forest);
179 Ok(())
180 }
181
182 #[cfg(any(test, feature = "testing"))]
183 pub fn advice_provider(&self) -> &A {
184 &self.adv_provider
185 }
186
187 #[cfg(any(test, feature = "testing"))]
188 pub fn advice_provider_mut(&mut self) -> &mut A {
189 &mut self.adv_provider
190 }
191
192 pub fn into_inner(self) -> A {
193 self.adv_provider
194 }
195}
196
197impl<A: AdviceProvider> Host for DefaultHost<A> {
198 type AdviceProvider = A;
199
200 fn advice_provider(&self) -> &Self::AdviceProvider {
201 &self.adv_provider
202 }
203
204 fn advice_provider_mut(&mut self) -> &mut Self::AdviceProvider {
205 &mut self.adv_provider
206 }
207
208 fn get_mast_forest(&self, node_digest: &RpoDigest) -> Option<Arc<MastForest>> {
209 self.store.get(node_digest)
210 }
211
212 fn on_event(&mut self, _process: ProcessState, _event_id: u32) -> Result<(), ExecutionError> {
213 #[cfg(feature = "std")]
214 std::println!(
215 "Event with id {} emitted at step {} in context {}",
216 _event_id,
217 _process.clk(),
218 _process.ctx()
219 );
220 Ok(())
221 }
222}