1use alloc::{collections::BTreeMap, vec::Vec};
2
3use vm_core::{
4 crypto::merkle::{MerkleStore, NodeIndex, StoreNode},
5 mast::MastNodeExt,
6};
7
8use super::{
9 AdviceInputs, AdviceProvider, AdviceSource, ExecutionError, Felt, MerklePath, RpoDigest, Word,
10};
11use crate::{
12 ErrorContext, ProcessState,
13 utils::collections::{KvMap, RecordingMap},
14};
15
16type SimpleMerkleMap = BTreeMap<RpoDigest, StoreNode>;
20type RecordingMerkleMap = RecordingMap<RpoDigest, StoreNode>;
21
22type SimpleAdviceMap = BTreeMap<RpoDigest, Vec<Felt>>;
23type RecordingAdviceMap = RecordingMap<RpoDigest, Vec<Felt>>;
24
25#[derive(Debug, Clone, Default)]
31pub struct BaseAdviceProvider<M, S>
32where
33 M: KvMap<RpoDigest, Vec<Felt>>,
34 S: KvMap<RpoDigest, StoreNode>,
35{
36 stack: Vec<Felt>,
37 map: M,
38 store: MerkleStore<S>,
39}
40
41impl<M, S> From<AdviceInputs> for BaseAdviceProvider<M, S>
42where
43 M: KvMap<RpoDigest, Vec<Felt>>,
44 S: KvMap<RpoDigest, StoreNode>,
45{
46 fn from(inputs: AdviceInputs) -> Self {
47 let (mut stack, map, store) = inputs.into_parts();
48 stack.reverse();
49 Self {
50 stack,
51 map: map.into_iter().collect(),
52 store: store.inner_nodes().collect(),
53 }
54 }
55}
56
57impl<M, S> AdviceProvider for BaseAdviceProvider<M, S>
58where
59 M: KvMap<RpoDigest, Vec<Felt>>,
60 S: KvMap<RpoDigest, StoreNode>,
61{
62 fn pop_stack(
66 &mut self,
67 process: ProcessState,
68 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
69 ) -> Result<Felt, ExecutionError> {
70 self.stack
71 .pop()
72 .ok_or(ExecutionError::advice_stack_read_failed(process.clk(), err_ctx))
73 }
74
75 fn pop_stack_word(
76 &mut self,
77 process: ProcessState,
78 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
79 ) -> Result<Word, ExecutionError> {
80 if self.stack.len() < 4 {
81 return Err(ExecutionError::advice_stack_read_failed(process.clk(), err_ctx));
82 }
83
84 let idx = self.stack.len() - 4;
85 let result =
86 [self.stack[idx + 3], self.stack[idx + 2], self.stack[idx + 1], self.stack[idx]];
87
88 self.stack.truncate(idx);
89
90 Ok(result)
91 }
92
93 fn pop_stack_dword(
94 &mut self,
95 process: ProcessState,
96 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
97 ) -> Result<[Word; 2], ExecutionError> {
98 let word0 = self.pop_stack_word(process, err_ctx)?;
99 let word1 = self.pop_stack_word(process, err_ctx)?;
100
101 Ok([word0, word1])
102 }
103
104 fn push_stack(
105 &mut self,
106 source: AdviceSource,
107 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
108 ) -> Result<(), ExecutionError> {
109 match source {
110 AdviceSource::Value(value) => {
111 self.stack.push(value);
112 },
113 AdviceSource::Word(word) => {
114 self.stack.extend(word.iter().rev());
115 },
116 AdviceSource::Map { key, include_len } => {
117 let values = self
118 .map
119 .get(&key.into())
120 .ok_or(ExecutionError::advice_map_key_not_found(key, err_ctx))?;
121
122 self.stack.extend(values.iter().rev());
123 if include_len {
124 self.stack
125 .push(Felt::try_from(values.len() as u64).expect("value length too big"));
126 }
127 },
128 }
129
130 Ok(())
131 }
132
133 fn peek_stack(&self, length: usize) -> &[Felt] {
134 if length == 0 {
135 &self.stack
136 } else {
137 &self.stack[0..length]
138 }
139 }
140
141 fn get_mapped_values(&self, key: &RpoDigest) -> Option<&[Felt]> {
145 self.map.get(key).map(|v| v.as_slice())
146 }
147
148 fn insert_into_map(&mut self, key: Word, values: Vec<Felt>) {
149 self.map.insert(key.into(), values);
150 }
151
152 fn get_tree_node(
156 &self,
157 root: Word,
158 depth: &Felt,
159 index: &Felt,
160 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
161 ) -> Result<Word, ExecutionError> {
162 let index = NodeIndex::from_elements(depth, index)
163 .map_err(|_| ExecutionError::invalid_merkle_tree_node_index(*depth, *index, err_ctx))?;
164 self.store
165 .get_node(root.into(), index)
166 .map(|v| v.into())
167 .map_err(|err| ExecutionError::merkle_store_lookup_failed(err, err_ctx))
168 }
169
170 fn get_merkle_path(
171 &self,
172 root: Word,
173 depth: &Felt,
174 index: &Felt,
175 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
176 ) -> Result<MerklePath, ExecutionError> {
177 let index = NodeIndex::from_elements(depth, index)
178 .map_err(|_| ExecutionError::invalid_merkle_tree_node_index(*depth, *index, err_ctx))?;
179 self.store
180 .get_path(root.into(), index)
181 .map(|value| value.path)
182 .map_err(|err| ExecutionError::merkle_store_lookup_failed(err, err_ctx))
183 }
184
185 fn get_leaf_depth(
186 &self,
187 root: Word,
188 tree_depth: &Felt,
189 index: &Felt,
190 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
191 ) -> Result<u8, ExecutionError> {
192 let tree_depth = u8::try_from(tree_depth.as_int())
193 .map_err(|_| ExecutionError::invalid_merkle_tree_depth(*tree_depth, err_ctx))?;
194 self.store
195 .get_leaf_depth(root.into(), tree_depth, index.as_int())
196 .map_err(|err| ExecutionError::merkle_store_lookup_failed(err, err_ctx))
197 }
198
199 fn update_merkle_node(
200 &mut self,
201 root: Word,
202 depth: &Felt,
203 index: &Felt,
204 value: Word,
205 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
206 ) -> Result<(MerklePath, Word), ExecutionError> {
207 let node_index = NodeIndex::from_elements(depth, index)
208 .map_err(|_| ExecutionError::invalid_merkle_tree_node_index(*depth, *index, err_ctx))?;
209 self.store
210 .set_node(root.into(), node_index, value.into())
211 .map(|root| (root.path, root.root.into()))
212 .map_err(|err| ExecutionError::merkle_store_update_failed(err, err_ctx))
213 }
214
215 fn merge_roots(
216 &mut self,
217 lhs: Word,
218 rhs: Word,
219 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
220 ) -> Result<Word, ExecutionError> {
221 self.store
222 .merge_roots(lhs.into(), rhs.into())
223 .map(|v| v.into())
224 .map_err(|err| ExecutionError::merkle_store_merge_failed(err, err_ctx))
225 }
226}
227
228#[derive(Debug, Clone, Default)]
233pub struct MemAdviceProvider {
234 provider: BaseAdviceProvider<SimpleAdviceMap, SimpleMerkleMap>,
235}
236
237impl From<AdviceInputs> for MemAdviceProvider {
238 fn from(inputs: AdviceInputs) -> Self {
239 let provider = inputs.into();
240 Self { provider }
241 }
242}
243
244#[cfg(any(test, feature = "testing"))]
246impl MemAdviceProvider {
247 pub fn stack(&self) -> &[Felt] {
249 &self.provider.stack
250 }
251
252 pub fn map(&self) -> &SimpleAdviceMap {
254 &self.provider.map
255 }
256
257 pub fn store(&self) -> &MerkleStore<SimpleMerkleMap> {
259 &self.provider.store
260 }
261
262 pub fn has_merkle_root(&self, root: crate::crypto::RpoDigest) -> bool {
264 self.provider.store.get_node(root, NodeIndex::root()).is_ok()
265 }
266}
267
268#[rustfmt::skip]
272impl AdviceProvider for MemAdviceProvider {
273 fn pop_stack(&mut self, process: ProcessState,
274 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
275 )-> Result<Felt, ExecutionError> {
276 self.provider.pop_stack(process, err_ctx)
277 }
278
279 fn pop_stack_word(&mut self, process: ProcessState,
280 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
281 ) -> Result<Word, ExecutionError> {
282 self.provider.pop_stack_word(process, err_ctx)
283 }
284
285 fn pop_stack_dword(&mut self, process: ProcessState,
286 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
287 ) -> Result<[Word; 2], ExecutionError> {
288 self.provider.pop_stack_dword(process, err_ctx)
289 }
290
291 fn push_stack(&mut self, source: AdviceSource, err_ctx: &ErrorContext<impl MastNodeExt>) -> Result<(), ExecutionError> {
292 self.provider.push_stack(source, err_ctx)
293 }
294
295 fn peek_stack(&self, length: usize,
296 )-> &[Felt] {
297 self.provider.peek_stack(length)
298 }
299
300 fn insert_into_map(&mut self, key: Word, values: Vec<Felt>) {
301 self.provider.insert_into_map(key, values)
302 }
303
304 fn get_mapped_values(&self, key: &RpoDigest) -> Option<&[Felt]> {
305 self.provider.get_mapped_values(key)
306 }
307
308 fn get_tree_node(&self, root: Word, depth: &Felt, index: &Felt,
309 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
310 ) -> Result<Word, ExecutionError> {
311 self.provider.get_tree_node(root, depth, index, err_ctx)
312 }
313
314 fn get_merkle_path(&self, root: Word, depth: &Felt, index: &Felt,
315 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
316 ) -> Result<MerklePath, ExecutionError> {
317 self.provider.get_merkle_path(root, depth, index, err_ctx)
318 }
319
320 fn get_leaf_depth(&self, root: Word, tree_depth: &Felt, index: &Felt,
321 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
322 ) -> Result<u8, ExecutionError> {
323 self.provider.get_leaf_depth(root, tree_depth, index, err_ctx)
324 }
325
326 fn update_merkle_node(&mut self, root: Word, depth: &Felt, index: &Felt, value: Word,
327 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
328 ) -> Result<(MerklePath, Word), ExecutionError> {
329 self.provider.update_merkle_node(root, depth, index, value, err_ctx)
330 }
331
332 fn merge_roots(&mut self, lhs: Word, rhs: Word,
333 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
334 ) -> Result<Word, ExecutionError> {
335 self.provider.merge_roots(lhs, rhs, err_ctx)
336 }
337}
338
339impl MemAdviceProvider {
340 pub fn into_parts(self) -> (Vec<Felt>, SimpleAdviceMap, MerkleStore) {
345 let BaseAdviceProvider { stack, map, store } = self.provider;
346 (stack, map, store)
347 }
348}
349
350#[derive(Debug, Clone, Default)]
358pub struct RecAdviceProvider {
359 provider: BaseAdviceProvider<RecordingAdviceMap, RecordingMerkleMap>,
360 init_stack: Vec<Felt>,
361}
362
363impl From<AdviceInputs> for RecAdviceProvider {
364 fn from(inputs: AdviceInputs) -> Self {
365 let init_stack = inputs.stack().to_vec();
366 let provider = inputs.into();
367 Self { provider, init_stack }
368 }
369}
370
371#[cfg(any(test, feature = "testing"))]
373impl RecAdviceProvider {
374 pub fn stack(&self) -> &[Felt] {
376 &self.provider.stack
377 }
378
379 pub fn map(&self) -> &RecordingAdviceMap {
381 &self.provider.map
382 }
383
384 pub fn store(&self) -> &MerkleStore<RecordingMerkleMap> {
386 &self.provider.store
387 }
388
389 pub fn has_merkle_root(&self, root: crate::crypto::RpoDigest) -> bool {
391 self.provider.store.get_node(root, NodeIndex::root()).is_ok()
392 }
393}
394
395#[rustfmt::skip]
399impl AdviceProvider for RecAdviceProvider {
400 fn pop_stack(&mut self, process: ProcessState,
401 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
402 ) -> Result<Felt, ExecutionError> {
403 self.provider.pop_stack(process,err_ctx)
404 }
405
406 fn pop_stack_word(&mut self, process: ProcessState,
407 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
408 ) -> Result<Word, ExecutionError> {
409 self.provider.pop_stack_word(process,err_ctx)
410 }
411
412 fn pop_stack_dword(&mut self, process: ProcessState,
413 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
414 ) -> Result<[Word; 2], ExecutionError> {
415 self.provider.pop_stack_dword(process, err_ctx)
416 }
417
418 fn push_stack(&mut self, source: AdviceSource, err_ctx: &ErrorContext<impl MastNodeExt>) -> Result<(), ExecutionError> {
419 self.provider.push_stack(source, err_ctx)
420 }
421
422 fn peek_stack(&self, length: usize) -> &[Felt] {
423 self.provider.peek_stack(length)
424 }
425
426 fn insert_into_map(&mut self, key: Word, values: Vec<Felt>) {
427 self.provider.insert_into_map(key, values)
428 }
429
430 fn get_mapped_values(&self, key: &RpoDigest) -> Option<&[Felt]> {
431 self.provider.get_mapped_values(key)
432 }
433
434 fn get_tree_node(&self, root: Word, depth: &Felt, index: &Felt,
435 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
436 ) -> Result<Word, ExecutionError> {
437 self.provider.get_tree_node(root, depth, index, err_ctx)
438 }
439
440 fn get_merkle_path(&self, root: Word, depth: &Felt, index: &Felt,
441 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
442 ) -> Result<MerklePath, ExecutionError> {
443 self.provider.get_merkle_path(root, depth, index, err_ctx)
444 }
445
446 fn get_leaf_depth(&self, root: Word, tree_depth: &Felt, index: &Felt,
447 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
448 ) -> Result<u8, ExecutionError> {
449 self.provider.get_leaf_depth(root, tree_depth, index, err_ctx)
450 }
451
452 fn update_merkle_node(&mut self, root: Word, depth: &Felt, index: &Felt, value: Word,
453 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
454 ) -> Result<(MerklePath, Word), ExecutionError> {
455 self.provider.update_merkle_node(root, depth, index, value, err_ctx)
456 }
457
458 fn merge_roots(&mut self, lhs: Word, rhs: Word,
459 err_ctx: &ErrorContext<'_, impl MastNodeExt>,
460 ) -> Result<Word, ExecutionError> {
461 self.provider.merge_roots(lhs, rhs, err_ctx)
462 }
463}
464
465impl RecAdviceProvider {
466 pub fn finalize(self) -> (AdviceInputs, Vec<Felt>, SimpleAdviceMap, MerkleStore) {
479 let Self { provider, init_stack } = self;
480 let BaseAdviceProvider { stack, map, store } = provider;
481
482 let (map, map_proof) = map.finalize();
483 let (store, store_proof) = store.into_inner().finalize();
484
485 let proof = AdviceInputs::default()
486 .with_stack(init_stack)
487 .with_map(map_proof)
488 .with_merkle_store(store_proof.into());
489
490 (proof, stack, map, store.into())
491 }
492}