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
use super::{BTreeMap, Felt, InnerNodeInfo, InputError, MerkleStore, Vec};
// 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.
#[derive(Clone, Debug, Default)]
pub struct AdviceInputs {
stack: Vec<Felt>,
map: BTreeMap<[u8; 32], Vec<Felt>>,
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(|_| {
InputError::NotFieldElement(v, "the provided value isn't a valid field element")
})
})
.collect::<Result<Vec<_>, _>>()?;
self.stack.extend(stack);
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 = ([u8; 32], 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 = ([u8; 32], 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);
}
// 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: &[u8; 32]) -> Option<&[Felt]> {
self.map.get(key).map(Vec::as_slice)
}
/// 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>, BTreeMap<[u8; 32], Vec<Felt>>, MerkleStore) {
let Self { stack, map, store } = self;
(stack, map, store)
}
}