1use alloc::{collections::BTreeMap, vec::Vec};
2
3use vm_core::crypto::merkle::{MerkleStore, NodeIndex, StoreNode};
4
5use super::{
6 AdviceInputs, AdviceProvider, AdviceSource, ExecutionError, Felt, MerklePath, RpoDigest, Word,
7};
8use crate::{
9 ProcessState,
10 utils::collections::{KvMap, RecordingMap},
11};
12
13type SimpleMerkleMap = BTreeMap<RpoDigest, StoreNode>;
17type RecordingMerkleMap = RecordingMap<RpoDigest, StoreNode>;
18
19type SimpleAdviceMap = BTreeMap<RpoDigest, Vec<Felt>>;
20type RecordingAdviceMap = RecordingMap<RpoDigest, Vec<Felt>>;
21
22#[derive(Debug, Clone, Default)]
28pub struct BaseAdviceProvider<M, S>
29where
30 M: KvMap<RpoDigest, Vec<Felt>>,
31 S: KvMap<RpoDigest, StoreNode>,
32{
33 stack: Vec<Felt>,
34 map: M,
35 store: MerkleStore<S>,
36}
37
38impl<M, S> From<AdviceInputs> for BaseAdviceProvider<M, S>
39where
40 M: KvMap<RpoDigest, Vec<Felt>>,
41 S: KvMap<RpoDigest, StoreNode>,
42{
43 fn from(inputs: AdviceInputs) -> Self {
44 let (mut stack, map, store) = inputs.into_parts();
45 stack.reverse();
46 Self {
47 stack,
48 map: map.into_iter().collect(),
49 store: store.inner_nodes().collect(),
50 }
51 }
52}
53
54impl<M, S> AdviceProvider for BaseAdviceProvider<M, S>
55where
56 M: KvMap<RpoDigest, Vec<Felt>>,
57 S: KvMap<RpoDigest, StoreNode>,
58{
59 fn pop_stack(&mut self, process: ProcessState) -> Result<Felt, ExecutionError> {
63 self.stack.pop().ok_or(ExecutionError::AdviceStackReadFailed(process.clk()))
64 }
65
66 fn pop_stack_word(&mut self, process: ProcessState) -> Result<Word, ExecutionError> {
67 if self.stack.len() < 4 {
68 return Err(ExecutionError::AdviceStackReadFailed(process.clk()));
69 }
70
71 let idx = self.stack.len() - 4;
72 let result =
73 [self.stack[idx + 3], self.stack[idx + 2], self.stack[idx + 1], self.stack[idx]];
74
75 self.stack.truncate(idx);
76
77 Ok(result)
78 }
79
80 fn pop_stack_dword(&mut self, process: ProcessState) -> Result<[Word; 2], ExecutionError> {
81 let word0 = self.pop_stack_word(process)?;
82 let word1 = self.pop_stack_word(process)?;
83
84 Ok([word0, word1])
85 }
86
87 fn push_stack(&mut self, source: AdviceSource) -> Result<(), ExecutionError> {
88 match source {
89 AdviceSource::Value(value) => {
90 self.stack.push(value);
91 },
92 AdviceSource::Word(word) => {
93 self.stack.extend(word.iter().rev());
94 },
95 AdviceSource::Map { key, include_len } => {
96 let values =
97 self.map.get(&key.into()).ok_or(ExecutionError::AdviceMapKeyNotFound(key))?;
98
99 self.stack.extend(values.iter().rev());
100 if include_len {
101 self.stack
102 .push(Felt::try_from(values.len() as u64).expect("value length too big"));
103 }
104 },
105 }
106
107 Ok(())
108 }
109
110 fn get_mapped_values(&self, key: &RpoDigest) -> Option<&[Felt]> {
114 self.map.get(key).map(|v| v.as_slice())
115 }
116
117 fn insert_into_map(&mut self, key: Word, values: Vec<Felt>) {
118 self.map.insert(key.into(), values);
119 }
120
121 fn get_tree_node(
125 &self,
126 root: Word,
127 depth: &Felt,
128 index: &Felt,
129 ) -> Result<Word, ExecutionError> {
130 let index = NodeIndex::from_elements(depth, index).map_err(|_| {
131 ExecutionError::InvalidMerkleTreeNodeIndex { depth: *depth, value: *index }
132 })?;
133 self.store
134 .get_node(root.into(), index)
135 .map(|v| v.into())
136 .map_err(ExecutionError::MerkleStoreLookupFailed)
137 }
138
139 fn get_merkle_path(
140 &self,
141 root: Word,
142 depth: &Felt,
143 index: &Felt,
144 ) -> Result<MerklePath, ExecutionError> {
145 let index = NodeIndex::from_elements(depth, index).map_err(|_| {
146 ExecutionError::InvalidMerkleTreeNodeIndex { depth: *depth, value: *index }
147 })?;
148 self.store
149 .get_path(root.into(), index)
150 .map(|value| value.path)
151 .map_err(ExecutionError::MerkleStoreLookupFailed)
152 }
153
154 fn get_leaf_depth(
155 &self,
156 root: Word,
157 tree_depth: &Felt,
158 index: &Felt,
159 ) -> Result<u8, ExecutionError> {
160 let tree_depth = u8::try_from(tree_depth.as_int())
161 .map_err(|_| ExecutionError::InvalidMerkleTreeDepth { depth: *tree_depth })?;
162 self.store
163 .get_leaf_depth(root.into(), tree_depth, index.as_int())
164 .map_err(ExecutionError::MerkleStoreLookupFailed)
165 }
166
167 fn update_merkle_node(
168 &mut self,
169 root: Word,
170 depth: &Felt,
171 index: &Felt,
172 value: Word,
173 ) -> Result<(MerklePath, Word), ExecutionError> {
174 let node_index = NodeIndex::from_elements(depth, index).map_err(|_| {
175 ExecutionError::InvalidMerkleTreeNodeIndex { depth: *depth, value: *index }
176 })?;
177 self.store
178 .set_node(root.into(), node_index, value.into())
179 .map(|root| (root.path, root.root.into()))
180 .map_err(ExecutionError::MerkleStoreUpdateFailed)
181 }
182
183 fn merge_roots(&mut self, lhs: Word, rhs: Word) -> Result<Word, ExecutionError> {
184 self.store
185 .merge_roots(lhs.into(), rhs.into())
186 .map(|v| v.into())
187 .map_err(ExecutionError::MerkleStoreMergeFailed)
188 }
189}
190
191#[derive(Debug, Clone, Default)]
196pub struct MemAdviceProvider {
197 provider: BaseAdviceProvider<SimpleAdviceMap, SimpleMerkleMap>,
198}
199
200impl From<AdviceInputs> for MemAdviceProvider {
201 fn from(inputs: AdviceInputs) -> Self {
202 let provider = inputs.into();
203 Self { provider }
204 }
205}
206
207#[cfg(any(test, feature = "testing"))]
209impl MemAdviceProvider {
210 pub fn stack(&self) -> &[Felt] {
212 &self.provider.stack
213 }
214
215 pub fn map(&self) -> &SimpleAdviceMap {
217 &self.provider.map
218 }
219
220 pub fn store(&self) -> &MerkleStore<SimpleMerkleMap> {
222 &self.provider.store
223 }
224
225 pub fn has_merkle_root(&self, root: crate::crypto::RpoDigest) -> bool {
227 self.provider.store.get_node(root, NodeIndex::root()).is_ok()
228 }
229}
230
231#[rustfmt::skip]
235impl AdviceProvider for MemAdviceProvider {
236 fn pop_stack(&mut self, process: ProcessState)-> Result<Felt, ExecutionError> {
237 self.provider.pop_stack(process)
238 }
239
240 fn pop_stack_word(&mut self, process: ProcessState) -> Result<Word, ExecutionError> {
241 self.provider.pop_stack_word(process)
242 }
243
244 fn pop_stack_dword(&mut self, process: ProcessState) -> Result<[Word; 2], ExecutionError> {
245 self.provider.pop_stack_dword(process)
246 }
247
248 fn push_stack(&mut self, source: AdviceSource) -> Result<(), ExecutionError> {
249 self.provider.push_stack(source)
250 }
251
252 fn insert_into_map(&mut self, key: Word, values: Vec<Felt>) {
253 self.provider.insert_into_map(key, values)
254 }
255
256 fn get_mapped_values(&self, key: &RpoDigest) -> Option<&[Felt]> {
257 self.provider.get_mapped_values(key)
258 }
259
260 fn get_tree_node(&self, root: Word, depth: &Felt, index: &Felt) -> Result<Word, ExecutionError> {
261 self.provider.get_tree_node(root, depth, index)
262 }
263
264 fn get_merkle_path(&self, root: Word, depth: &Felt, index: &Felt) -> Result<MerklePath, ExecutionError> {
265 self.provider.get_merkle_path(root, depth, index)
266 }
267
268 fn get_leaf_depth(&self, root: Word, tree_depth: &Felt, index: &Felt) -> Result<u8, ExecutionError> {
269 self.provider.get_leaf_depth(root, tree_depth, index)
270 }
271
272 fn update_merkle_node(&mut self, root: Word, depth: &Felt, index: &Felt, value: Word) -> Result<(MerklePath, Word), ExecutionError> {
273 self.provider.update_merkle_node(root, depth, index, value)
274 }
275
276 fn merge_roots(&mut self, lhs: Word, rhs: Word) -> Result<Word, ExecutionError> {
277 self.provider.merge_roots(lhs, rhs)
278 }
279}
280
281impl MemAdviceProvider {
282 pub fn into_parts(self) -> (Vec<Felt>, SimpleAdviceMap, MerkleStore) {
287 let BaseAdviceProvider { stack, map, store } = self.provider;
288 (stack, map, store)
289 }
290}
291
292#[derive(Debug, Clone, Default)]
300pub struct RecAdviceProvider {
301 provider: BaseAdviceProvider<RecordingAdviceMap, RecordingMerkleMap>,
302 init_stack: Vec<Felt>,
303}
304
305impl From<AdviceInputs> for RecAdviceProvider {
306 fn from(inputs: AdviceInputs) -> Self {
307 let init_stack = inputs.stack().to_vec();
308 let provider = inputs.into();
309 Self { provider, init_stack }
310 }
311}
312
313#[cfg(any(test, feature = "testing"))]
315impl RecAdviceProvider {
316 pub fn stack(&self) -> &[Felt] {
318 &self.provider.stack
319 }
320
321 pub fn map(&self) -> &RecordingAdviceMap {
323 &self.provider.map
324 }
325
326 pub fn store(&self) -> &MerkleStore<RecordingMerkleMap> {
328 &self.provider.store
329 }
330
331 pub fn has_merkle_root(&self, root: crate::crypto::RpoDigest) -> bool {
333 self.provider.store.get_node(root, NodeIndex::root()).is_ok()
334 }
335}
336
337#[rustfmt::skip]
341impl AdviceProvider for RecAdviceProvider {
342 fn pop_stack(&mut self, process: ProcessState) -> Result<Felt, ExecutionError> {
343 self.provider.pop_stack(process)
344 }
345
346 fn pop_stack_word(&mut self, process: ProcessState) -> Result<Word, ExecutionError> {
347 self.provider.pop_stack_word(process)
348 }
349
350 fn pop_stack_dword(&mut self, process: ProcessState) -> Result<[Word; 2], ExecutionError> {
351 self.provider.pop_stack_dword(process)
352 }
353
354 fn push_stack(&mut self, source: AdviceSource) -> Result<(), ExecutionError> {
355 self.provider.push_stack(source)
356 }
357
358 fn insert_into_map(&mut self, key: Word, values: Vec<Felt>) {
359 self.provider.insert_into_map(key, values)
360 }
361
362 fn get_mapped_values(&self, key: &RpoDigest) -> Option<&[Felt]> {
363 self.provider.get_mapped_values(key)
364 }
365
366 fn get_tree_node(&self, root: Word, depth: &Felt, index: &Felt) -> Result<Word, ExecutionError> {
367 self.provider.get_tree_node(root, depth, index)
368 }
369
370 fn get_merkle_path(&self, root: Word, depth: &Felt, index: &Felt) -> Result<MerklePath, ExecutionError> {
371 self.provider.get_merkle_path(root, depth, index)
372 }
373
374 fn get_leaf_depth(&self, root: Word, tree_depth: &Felt, index: &Felt) -> Result<u8, ExecutionError> {
375 self.provider.get_leaf_depth(root, tree_depth, index)
376 }
377
378 fn update_merkle_node(&mut self, root: Word, depth: &Felt, index: &Felt, value: Word) -> Result<(MerklePath, Word), ExecutionError> {
379 self.provider.update_merkle_node(root, depth, index, value)
380 }
381
382 fn merge_roots(&mut self, lhs: Word, rhs: Word) -> Result<Word, ExecutionError> {
383 self.provider.merge_roots(lhs, rhs)
384 }
385}
386
387impl RecAdviceProvider {
388 pub fn finalize(self) -> (AdviceInputs, Vec<Felt>, SimpleAdviceMap, MerkleStore) {
401 let Self { provider, init_stack } = self;
402 let BaseAdviceProvider { stack, map, store } = provider;
403
404 let (map, map_proof) = map.finalize();
405 let (store, store_proof) = store.into_inner().finalize();
406
407 let proof = AdviceInputs::default()
408 .with_stack(init_stack)
409 .with_map(map_proof)
410 .with_merkle_store(store_proof.into());
411
412 (proof, stack, map, store.into())
413 }
414}