miden_processor/host/
mod.rs

1use alloc::{sync::Arc, vec::Vec};
2use core::future::Future;
3
4use miden_core::{
5    AdviceMap, DebugOptions, Felt, Word, crypto::merkle::InnerNodeInfo, mast::MastForest,
6};
7use miden_debug_types::{Location, SourceFile, SourceSpan};
8
9use crate::{EventError, ExecutionError, ProcessState};
10
11pub(super) mod advice;
12
13#[cfg(feature = "std")]
14mod debug;
15
16pub mod default;
17use default::DefaultDebugHandler;
18
19pub mod handlers;
20use handlers::DebugHandler;
21
22mod mast_forest_store;
23pub use mast_forest_store::{MastForestStore, MemMastForestStore};
24
25// ADVICE MAP MUTATIONS
26// ================================================================================================
27
28/// Any possible way an event can modify the advice map
29#[derive(Debug, PartialEq, Eq)]
30pub enum AdviceMutation {
31    ExtendStack { values: Vec<Felt> },
32    ExtendMap { other: AdviceMap },
33    ExtendMerkleStore { infos: Vec<InnerNodeInfo> },
34}
35
36impl AdviceMutation {
37    pub fn extend_stack(iter: impl IntoIterator<Item = Felt>) -> Self {
38        Self::ExtendStack { values: Vec::from_iter(iter) }
39    }
40
41    pub fn extend_map(other: AdviceMap) -> Self {
42        Self::ExtendMap { other }
43    }
44
45    pub fn extend_merkle_store(infos: impl IntoIterator<Item = InnerNodeInfo>) -> Self {
46        Self::ExtendMerkleStore { infos: Vec::from_iter(infos) }
47    }
48}
49// HOST TRAIT
50// ================================================================================================
51
52/// Defines the common interface between [SyncHost] and [AsyncHost], by which the VM can interact
53/// with the host.
54///
55/// There are three main categories of interactions between the VM and the host:
56/// 1. getting a library's MAST forest,
57/// 2. handling VM events (which can mutate the process' advice provider), and
58/// 3. handling debug and trace events.
59pub trait BaseHost {
60    // REQUIRED METHODS
61    // --------------------------------------------------------------------------------------------
62
63    /// Returns MAST forest corresponding to the specified digest, or None if the MAST forest for
64    /// this digest could not be found in this host.
65    fn get_mast_forest(&self, node_digest: &Word) -> Option<Arc<MastForest>>;
66
67    /// Returns the [`SourceSpan`] and optional [`SourceFile`] for the provided location.
68    fn get_label_and_source_file(
69        &self,
70        location: &Location,
71    ) -> (SourceSpan, Option<Arc<SourceFile>>);
72
73    /// Handles the debug request from the VM.
74    fn on_debug(
75        &mut self,
76        process: &mut ProcessState,
77        options: &DebugOptions,
78    ) -> Result<(), ExecutionError> {
79        DefaultDebugHandler.on_debug(process, options)
80    }
81
82    /// Handles the trace emitted from the VM.
83    fn on_trace(
84        &mut self,
85        process: &mut ProcessState,
86        trace_id: u32,
87    ) -> Result<(), ExecutionError> {
88        DefaultDebugHandler.on_trace(process, trace_id)
89    }
90
91    /// Handles the failure of the assertion instruction.
92    fn on_assert_failed(&mut self, _process: &ProcessState, _err_code: Felt) {}
93}
94
95/// Defines an interface by which the VM can interact with the host.
96///
97/// There are four main categories of interactions between the VM and the host:
98/// 1. accessing the advice provider,
99/// 2. getting a library's MAST forest,
100/// 3. handling VM events (which can mutate the process' advice provider), and
101/// 4. handling debug and trace events.
102pub trait SyncHost: BaseHost {
103    // REQUIRED METHODS
104    // --------------------------------------------------------------------------------------------
105
106    /// Handles the event emitted from the VM.
107    fn on_event(
108        &mut self,
109        process: &ProcessState,
110        event_id: u32,
111    ) -> Result<Vec<AdviceMutation>, EventError>;
112}
113
114// ASYNC HOST trait
115// ================================================================================================
116
117/// Analogous to the [SyncHost] trait, but designed for asynchronous execution contexts.
118pub trait AsyncHost: BaseHost {
119    // REQUIRED METHODS
120    // --------------------------------------------------------------------------------------------
121
122    // Note: we don't use the `async` keyword in this method, since we need to specify the `+ Send`
123    // bound to the returned Future, and `async` doesn't allow us to do that.
124
125    /// Handles the event emitted from the VM and provides advice mutations to be applied to
126    /// the advice provider.
127    fn on_event(
128        &mut self,
129        process: &ProcessState<'_>,
130        event_id: u32,
131    ) -> impl FutureMaybeSend<Result<Vec<AdviceMutation>, EventError>>;
132}
133
134/// Alias for a `Future`
135///
136/// Unless the compilation target family is `wasm`, we add `Send` to the required bounds. For
137/// `wasm` compilation targets there is no `Send` bound.
138///
139/// We also provide a blank implementation of this trait for all features.
140#[cfg(target_family = "wasm")]
141pub trait FutureMaybeSend<O>: Future<Output = O> {}
142
143#[cfg(target_family = "wasm")]
144impl<T, O> FutureMaybeSend<O> for T where T: Future<Output = O> {}
145
146/// Alias for a `Future`
147///
148/// Unless the compilation target family is `wasm`, we add `Send` to the required bounds. For
149/// `wasm` compilation targets there is no `Send` bound.
150///
151/// We also provide a blank implementation of this trait for all features.
152#[cfg(not(target_family = "wasm"))]
153pub trait FutureMaybeSend<O>: Future<Output = O> + Send {}
154
155#[cfg(not(target_family = "wasm"))]
156impl<T, O> FutureMaybeSend<O> for T where T: Future<Output = O> + Send {}