Skip to main content

miden_processor/host/
mast_forest_store.rs

1use alloc::{collections::BTreeMap, sync::Arc};
2
3use miden_core::{Word, mast::MastForest};
4use miden_mast_package::{PackageDebugInfoError, debug_info::PackageDebugInfo};
5
6/// Executable MAST loaded by the host, together with the package debug info that belongs to the
7/// same forest.
8#[derive(Debug, Clone)]
9pub struct LoadedMastForest {
10    mast_forest: Arc<MastForest>,
11    debug_info: Result<Option<Arc<PackageDebugInfo>>, Arc<PackageDebugInfoError>>,
12}
13
14impl LoadedMastForest {
15    /// Creates a loaded MAST forest without package-owned debug info.
16    pub fn new(mast_forest: Arc<MastForest>) -> Self {
17        Self { mast_forest, debug_info: Ok(None) }
18    }
19
20    /// Creates a loaded MAST forest with package debug info already decoded from the owning
21    /// package.
22    pub fn with_package_debug_info(
23        mast_forest: Arc<MastForest>,
24        debug_info: Result<Option<PackageDebugInfo>, PackageDebugInfoError>,
25    ) -> Self {
26        Self {
27            mast_forest,
28            debug_info: debug_info.map(|debug_info| debug_info.map(Arc::new)).map_err(Arc::new),
29        }
30    }
31
32    /// Returns the executable MAST forest.
33    pub fn mast_forest(&self) -> &Arc<MastForest> {
34        &self.mast_forest
35    }
36
37    /// Returns the package debug info associated with this forest, if any.
38    pub fn package_debug_info(
39        &self,
40    ) -> Result<Option<Arc<PackageDebugInfo>>, Arc<PackageDebugInfoError>> {
41        self.debug_info.clone()
42    }
43}
44
45/// A set of [`MastForest`]s available to the prover that programs may refer to (by means of an
46/// [`miden_core::mast::ExternalNode`]).
47///
48/// For example, a program's kernel and core library would most likely not be compiled directly
49/// with the program, and instead be provided separately to the prover. This has the benefit of
50/// reducing program binary size. The store could also be much more complex, such as accessing a
51/// centralized registry of [`MastForest`]s when it doesn't find one locally.
52pub trait MastForestStore {
53    /// Returns a [`MastForest`] which is guaranteed to contain a procedure with the provided
54    /// procedure hash as one of its procedure, if any.
55    fn get(&self, procedure_hash: &Word) -> Option<LoadedMastForest>;
56}
57
58/// A simple [`MastForestStore`] where all known [`MastForest`]s are held in memory.
59#[derive(Debug, Default, Clone)]
60pub struct MemMastForestStore {
61    mast_forests: BTreeMap<Word, LoadedMastForest>,
62}
63
64impl MemMastForestStore {
65    /// Inserts all the procedures of the provided MAST forest in the store.
66    pub fn insert(&mut self, mast_forest: Arc<MastForest>) {
67        self.insert_loaded(LoadedMastForest::new(mast_forest));
68    }
69
70    /// Inserts all the procedures of the provided loaded MAST forest in the store.
71    pub fn insert_loaded(&mut self, loaded_mast_forest: LoadedMastForest) {
72        // only register the procedures which are local to this forest
73        for proc_digest in loaded_mast_forest.mast_forest.local_procedure_digests() {
74            self.mast_forests.insert(proc_digest, loaded_mast_forest.clone());
75        }
76    }
77}
78
79impl MastForestStore for MemMastForestStore {
80    fn get(&self, procedure_hash: &Word) -> Option<LoadedMastForest> {
81        self.mast_forests.get(procedure_hash).cloned()
82    }
83}