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 the [`SourceSpan`] and optional [`SourceFile`] for the provided location.
64    fn get_label_and_source_file(
65        &self,
66        location: &Location,
67    ) -> (SourceSpan, Option<Arc<SourceFile>>);
68
69    /// Handles the debug request from the VM.
70    fn on_debug(
71        &mut self,
72        process: &mut ProcessState,
73        options: &DebugOptions,
74    ) -> Result<(), ExecutionError> {
75        DefaultDebugHandler.on_debug(process, options)
76    }
77
78    /// Handles the trace emitted from the VM.
79    fn on_trace(
80        &mut self,
81        process: &mut ProcessState,
82        trace_id: u32,
83    ) -> Result<(), ExecutionError> {
84        DefaultDebugHandler.on_trace(process, trace_id)
85    }
86
87    /// Handles the failure of the assertion instruction.
88    fn on_assert_failed(&mut self, _process: &ProcessState, _err_code: Felt) {}
89}
90
91/// Defines an interface by which the VM can interact with the host.
92///
93/// There are four main categories of interactions between the VM and the host:
94/// 1. accessing the advice provider,
95/// 2. getting a library's MAST forest,
96/// 3. handling VM events (which can mutate the process' advice provider), and
97/// 4. handling debug and trace events.
98pub trait SyncHost: BaseHost {
99    // REQUIRED METHODS
100    // --------------------------------------------------------------------------------------------
101
102    /// Returns MAST forest corresponding to the specified digest, or None if the MAST forest for
103    /// this digest could not be found in this host.
104    fn get_mast_forest(&self, node_digest: &Word) -> Option<Arc<MastForest>>;
105
106    /// Invoked when the VM encounters an `EMIT` operation.
107    ///
108    /// The event ID is available at the top of the stack (position 0) when this handler is called.
109    /// This allows the handler to access both the event ID and any additional context data that
110    /// may have been pushed onto the stack prior to the emit operation.
111    fn on_event(&mut self, process: &ProcessState) -> 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    /// Returns MAST forest corresponding to the specified digest, or None if the MAST forest for
126    /// this digest could not be found in this host.
127    fn get_mast_forest(&self, node_digest: &Word) -> impl FutureMaybeSend<Option<Arc<MastForest>>>;
128
129    /// Handles the event emitted from the VM and provides advice mutations to be applied to
130    /// the advice provider.
131    ///
132    /// The event ID is available at the top of the stack (position 0) when this handler is called.
133    /// This allows the handler to access both the event ID and any additional context data that
134    /// may have been pushed onto the stack prior to the emit operation.
135    fn on_event(
136        &mut self,
137        process: &ProcessState<'_>,
138    ) -> impl FutureMaybeSend<Result<Vec<AdviceMutation>, EventError>>;
139}
140
141/// Alias for a `Future`
142///
143/// Unless the compilation target family is `wasm`, we add `Send` to the required bounds. For
144/// `wasm` compilation targets there is no `Send` bound.
145///
146/// We also provide a blank implementation of this trait for all features.
147#[cfg(target_family = "wasm")]
148pub trait FutureMaybeSend<O>: Future<Output = O> {}
149
150#[cfg(target_family = "wasm")]
151impl<T, O> FutureMaybeSend<O> for T where T: Future<Output = O> {}
152
153/// Alias for a `Future`
154///
155/// Unless the compilation target family is `wasm`, we add `Send` to the required bounds. For
156/// `wasm` compilation targets there is no `Send` bound.
157///
158/// We also provide a blank implementation of this trait for all features.
159#[cfg(not(target_family = "wasm"))]
160pub trait FutureMaybeSend<O>: Future<Output = O> + Send {}
161
162#[cfg(not(target_family = "wasm"))]
163impl<T, O> FutureMaybeSend<O> for T where T: Future<Output = O> + Send {}