1use alloc::vec::Vec;
2
3use crate::{
4 Felt, Word,
5 crypto::merkle::MerkleStore,
6 field::QuotientMap,
7 program::InputError,
8 serde::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
9};
10
11mod map;
12pub use map::AdviceMap;
13
14mod stack;
15pub use stack::AdviceStackBuilder;
16
17#[derive(Clone, Debug, Default, PartialEq, Eq)]
32pub struct AdviceInputs {
33 pub stack: Vec<Felt>,
34 pub map: AdviceMap,
35 pub store: MerkleStore,
36}
37
38impl AdviceInputs {
39 pub fn with_stack_values<I>(mut self, iter: I) -> Result<Self, InputError>
45 where
46 I: IntoIterator<Item = u64>,
47 {
48 let stack = iter
49 .into_iter()
50 .map(|v| Felt::from_canonical_checked(v).ok_or(InputError::InvalidStackElement(v)))
51 .collect::<Result<Vec<_>, _>>()?;
52
53 self.stack.extend(stack.iter());
54 Ok(self)
55 }
56
57 pub fn with_stack<I>(mut self, iter: I) -> Self
59 where
60 I: IntoIterator<Item = Felt>,
61 {
62 self.stack.extend(iter);
63 self
64 }
65
66 pub fn with_map<I>(mut self, iter: I) -> Self
68 where
69 I: IntoIterator<Item = (Word, Vec<Felt>)>,
70 {
71 self.map.extend(iter);
72 self
73 }
74
75 pub fn with_merkle_store(mut self, store: MerkleStore) -> Self {
77 self.store = store;
78 self
79 }
80
81 pub fn extend(&mut self, other: Self) {
86 self.stack.extend(other.stack);
87 self.map.extend(other.map);
88 self.store.extend(other.store.inner_nodes());
89 }
90}
91
92impl Serializable for AdviceInputs {
93 fn write_into<W: ByteWriter>(&self, target: &mut W) {
94 let Self { stack, map, store } = self;
95 stack.write_into(target);
96 map.write_into(target);
97 store.write_into(target);
98 }
99}
100
101impl Deserializable for AdviceInputs {
102 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
103 let stack = Vec::<Felt>::read_from(source)?;
104 let map = AdviceMap::read_from(source)?;
105 let store = MerkleStore::read_from(source)?;
106 Ok(Self { stack, map, store })
107 }
108}
109
110#[cfg(test)]
114mod tests {
115 use alloc::vec::Vec;
116
117 use super::{AdviceInputs, AdviceStackBuilder};
118 use crate::{
119 Felt, Word,
120 serde::{Deserializable, Serializable},
121 };
122
123 #[test]
124 fn test_advice_inputs_eq() {
125 let advice1 = AdviceInputs::default();
126 let advice2 = AdviceInputs::default();
127
128 assert_eq!(advice1, advice2);
129
130 let advice1 = AdviceInputs::default().with_stack_values([1, 2, 3].iter().copied()).unwrap();
131 let advice2 = AdviceInputs::default().with_stack_values([1, 2, 3].iter().copied()).unwrap();
132
133 assert_eq!(advice1, advice2);
134 }
135
136 #[test]
137 fn test_advice_inputs_serialization() {
138 let advice1 = AdviceInputs::default().with_stack_values([1, 2, 3].iter().copied()).unwrap();
139 let bytes = advice1.to_bytes();
140 let advice2 = AdviceInputs::read_from_bytes(&bytes).unwrap();
141
142 assert_eq!(advice1, advice2);
143 }
144
145 #[test]
149 fn test_builder_push_for_adv_push() {
150 let a = Felt::new_unchecked(1);
153 let b = Felt::new_unchecked(2);
154 let c = Felt::new_unchecked(3);
155
156 let mut builder = AdviceStackBuilder::new();
157 builder.push_for_adv_push(&[a, b, c]);
158 let advice = builder.build();
159
160 assert_eq!(advice.stack, vec![c, b, a]);
163 }
164
165 #[test]
166 fn test_builder_push_word() {
167 let word: Word = [
168 Felt::new_unchecked(1),
169 Felt::new_unchecked(2),
170 Felt::new_unchecked(3),
171 Felt::new_unchecked(4),
172 ]
173 .into();
174
175 let mut builder = AdviceStackBuilder::new();
176 builder.push_word(word);
177 let advice = builder.build();
178
179 assert_eq!(
181 advice.stack,
182 vec![
183 Felt::new_unchecked(1),
184 Felt::new_unchecked(2),
185 Felt::new_unchecked(3),
186 Felt::new_unchecked(4)
187 ]
188 );
189 }
190
191 #[test]
192 fn test_builder_push_for_adv_pipe() {
193 let slice: Vec<Felt> = (1..=8).map(Felt::new_unchecked).collect();
194
195 let mut builder = AdviceStackBuilder::new();
196 builder.push_for_adv_pipe(&slice);
197 let advice = builder.build();
198
199 assert_eq!(advice.stack, slice);
200 }
201
202 #[test]
203 #[should_panic(expected = "push_for_adv_pipe requires slice length to be a multiple of 8")]
204 fn test_builder_push_for_adv_pipe_panics_on_misalignment() {
205 let slice: Vec<Felt> = (1..=7).map(Felt::new_unchecked).collect();
206
207 let mut builder = AdviceStackBuilder::new();
208 builder.push_for_adv_pipe(&slice);
209 builder.build();
210 }
211
212 #[test]
213 fn test_builder_push_u64_slice() {
214 let mut builder = AdviceStackBuilder::new();
216 builder.push_u64_slice(&[1, 2, 3, 4]);
217 let advice = builder.build();
218
219 assert_eq!(
220 advice.stack,
221 vec![
222 Felt::new_unchecked(1),
223 Felt::new_unchecked(2),
224 Felt::new_unchecked(3),
225 Felt::new_unchecked(4)
226 ]
227 );
228 }
229
230 #[test]
231 fn test_builder_chaining_top_first() {
232 let a = Felt::new_unchecked(1);
235 let b = Felt::new_unchecked(2);
236 let c = Felt::new_unchecked(3);
237 let word: Word = [
238 Felt::new_unchecked(10),
239 Felt::new_unchecked(20),
240 Felt::new_unchecked(30),
241 Felt::new_unchecked(40),
242 ]
243 .into();
244
245 let mut builder = AdviceStackBuilder::new();
246 builder.push_for_adv_push(&[a, b, c]); builder.push_word(word); let advice = builder.build();
249
250 assert_eq!(
253 advice.stack,
254 vec![
255 c,
256 b,
257 a,
258 Felt::new_unchecked(10),
259 Felt::new_unchecked(20),
260 Felt::new_unchecked(30),
261 Felt::new_unchecked(40)
262 ]
263 );
264 }
265
266 #[test]
267 fn test_builder_multiple_push_for_adv_push() {
268 let first = [Felt::new_unchecked(1), Felt::new_unchecked(2)];
270 let second = [Felt::new_unchecked(3), Felt::new_unchecked(4)];
271
272 let mut builder = AdviceStackBuilder::new();
273 builder.push_for_adv_push(&first); builder.push_for_adv_push(&second); let advice = builder.build();
276
277 assert_eq!(
283 advice.stack,
284 vec![
285 Felt::new_unchecked(2),
286 Felt::new_unchecked(1),
287 Felt::new_unchecked(4),
288 Felt::new_unchecked(3)
289 ]
290 );
291 }
292}