1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
use alloc::vec::Vec;
use vm_core::crypto::hash::RpoDigest;
use super::{AdviceMap, Felt, InnerNodeInfo, InputError, MerkleStore};
// ADVICE INPUTS
// ================================================================================================
/// Inputs container to initialize advice provider for the execution of Miden VM programs.
///
/// The program may request nondeterministic advice inputs from the prover. These inputs are secret
/// inputs. This means that the prover does not need to share them with the verifier.
///
/// There are three types of advice inputs:
///
/// 1. Single advice stack which can contain any number of elements.
/// 2. Key-mapped element lists which can be pushed onto the advice stack.
/// 3. Merkle store, which is used to provide nondeterministic inputs for instructions that operates
///    with Merkle trees.
#[cfg(not(feature = "testing"))]
#[derive(Clone, Debug, Default)]
pub struct AdviceInputs {
    stack: Vec<Felt>,
    map: AdviceMap,
    store: MerkleStore,
}
impl AdviceInputs {
    // CONSTRUCTORS
    // --------------------------------------------------------------------------------------------
    /// Attempts to extend the stack values with the given sequence of integers, returning an error
    /// if any of the numbers fails while converting to an element `[Felt]`.
    pub fn with_stack_values<I>(mut self, iter: I) -> Result<Self, InputError>
    where
        I: IntoIterator<Item = u64>,
    {
        let stack = iter
            .into_iter()
            .map(|v| Felt::try_from(v).map_err(|e| InputError::NotFieldElement(v, e)))
            .collect::<Result<Vec<_>, _>>()?;
        self.stack.extend(stack.iter());
        Ok(self)
    }
    /// Extends the stack with the given elements.
    pub fn with_stack<I>(mut self, iter: I) -> Self
    where
        I: IntoIterator<Item = Felt>,
    {
        self.stack.extend(iter);
        self
    }
    /// Extends the map of values with the given argument, replacing previously inserted items.
    pub fn with_map<I>(mut self, iter: I) -> Self
    where
        I: IntoIterator<Item = (RpoDigest, Vec<Felt>)>,
    {
        self.map.extend(iter);
        self
    }
    /// Replaces the [MerkleStore] with the provided argument.
    pub fn with_merkle_store(mut self, store: MerkleStore) -> Self {
        self.store = store;
        self
    }
    // PUBLIC MUTATORS
    // --------------------------------------------------------------------------------------------
    /// Extends the stack with the given elements.
    pub fn extend_stack<I>(&mut self, iter: I)
    where
        I: IntoIterator<Item = Felt>,
    {
        self.stack.extend(iter);
    }
    /// Extends the map of values with the given argument, replacing previously inserted items.
    pub fn extend_map<I>(&mut self, iter: I)
    where
        I: IntoIterator<Item = (RpoDigest, Vec<Felt>)>,
    {
        self.map.extend(iter);
    }
    /// Extends the [MerkleStore] with the given nodes.
    pub fn extend_merkle_store<I>(&mut self, iter: I)
    where
        I: Iterator<Item = InnerNodeInfo>,
    {
        self.store.extend(iter);
    }
    /// Extends the contents of this instance with the contents of the other instance.
    pub fn extend(&mut self, other: Self) {
        self.stack.extend(other.stack);
        self.map.extend(other.map);
        self.store.extend(other.store.inner_nodes());
    }
    // PUBLIC ACCESSORS
    // --------------------------------------------------------------------------------------------
    /// Returns a reference to the advice stack.
    pub fn stack(&self) -> &[Felt] {
        &self.stack
    }
    /// Fetch a values set mapped by the given key.
    pub fn mapped_values(&self, key: &RpoDigest) -> Option<&[Felt]> {
        self.map.get(key)
    }
    /// Returns the underlying [MerkleStore].
    pub const fn merkle_store(&self) -> &MerkleStore {
        &self.store
    }
    // DESTRUCTORS
    // --------------------------------------------------------------------------------------------
    /// Decomposes these `[Self]` into their raw components.
    #[allow(clippy::type_complexity)]
    pub(crate) fn into_parts(self) -> (Vec<Felt>, AdviceMap, MerkleStore) {
        let Self { stack, map, store } = self;
        (stack, map, store)
    }
}
// TESTING
// ================================================================================================
#[cfg(feature = "testing")]
#[derive(Clone, Debug, Default)]
pub struct AdviceInputs {
    pub stack: Vec<Felt>,
    pub map: AdviceMap,
    pub store: MerkleStore,
}