1use alloc::{boxed::Box, collections::BTreeSet, string::ToString, vec::Vec};
2
3use vm_core::{
4 utils::{ByteReader, ByteWriter, Deserializable, Serializable},
5 Felt, FieldElement, Word,
6};
7use vm_processor::{DeserializationError, Digest};
8
9use super::{placeholder::PlaceholderType, InitStorageData, MapEntry, StoragePlaceholder};
10use crate::account::{component::template::AccountComponentTemplateError, StorageMap};
11
12#[derive(Debug, Clone, PartialEq, Eq)]
17pub enum WordRepresentation {
18 Value([Felt; 4]),
20 Array([FeltRepresentation; 4]),
22 Template(StoragePlaceholder),
25}
26
27impl WordRepresentation {
28 pub fn all_placeholders_iter(
31 &self,
32 ) -> Box<dyn Iterator<Item = (&StoragePlaceholder, PlaceholderType)> + '_> {
33 match self {
34 WordRepresentation::Array(array) => {
35 Box::new(array.iter().flat_map(|felt| felt.all_placeholders_iter()))
36 },
37 WordRepresentation::Template(storage_placeholder) => {
38 Box::new(core::iter::once((storage_placeholder, PlaceholderType::Word)))
39 },
40 WordRepresentation::Value(_) => Box::new(core::iter::empty()),
41 }
42 }
43
44 pub fn try_build_word(
50 &self,
51 init_storage_data: &InitStorageData,
52 ) -> Result<Word, AccountComponentTemplateError> {
53 match self {
54 WordRepresentation::Value(word) => Ok(*word),
55 WordRepresentation::Array(array) => {
56 let mut result = [Felt::ZERO; 4];
57 for (index, felt_repr) in array.iter().enumerate() {
58 result[index] = felt_repr.clone().try_build_felt(init_storage_data)?;
59 }
60 Ok(result)
62 },
63 WordRepresentation::Template(storage_placeholder) => {
64 let user_value = init_storage_data
65 .get(storage_placeholder)
66 .ok_or_else(|| {
67 AccountComponentTemplateError::PlaceholderValueNotProvided(
68 storage_placeholder.clone(),
69 )
70 })?
71 .as_word()?;
72 Ok(*user_value)
73 },
74 }
75 }
76}
77
78impl From<Word> for WordRepresentation {
79 fn from(value: Word) -> Self {
80 WordRepresentation::Value(value)
81 }
82}
83
84impl Serializable for WordRepresentation {
85 fn write_into<W: ByteWriter>(&self, target: &mut W) {
86 match self {
87 WordRepresentation::Value(value) => {
88 target.write_u8(0);
89 target.write(value);
90 },
91 WordRepresentation::Array(value) => {
92 target.write_u8(1);
93 target.write(value);
94 },
95 WordRepresentation::Template(storage_placeholder) => {
96 target.write_u8(2);
97 target.write(storage_placeholder);
98 },
99 }
100 }
101}
102
103impl Deserializable for WordRepresentation {
104 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
105 let variant_tag = source.read_u8()?;
106
107 match variant_tag {
108 0 => {
109 let value = <[Felt; 4]>::read_from(source)?;
111 Ok(WordRepresentation::Value(value))
112 },
113 1 => {
114 let value = <[FeltRepresentation; 4]>::read_from(source)?;
116 Ok(WordRepresentation::Array(value))
117 },
118 2 => {
119 let storage_placeholder = StoragePlaceholder::read_from(source)?;
121 Ok(WordRepresentation::Template(storage_placeholder))
122 },
123 _ => Err(DeserializationError::InvalidValue(format!(
124 "unknown variant tag for WordRepresentation: {variant_tag}"
125 ))),
126 }
127 }
128}
129
130impl Default for WordRepresentation {
131 fn default() -> Self {
132 WordRepresentation::Value(Default::default())
133 }
134}
135
136impl core::fmt::Display for WordRepresentation {
137 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
138 match self {
139 WordRepresentation::Value(hex) => f.write_str(&Digest::from(hex).to_hex()),
140 WordRepresentation::Array(array) => {
141 f.write_str("[")?;
142 f.write_fmt(format_args!("{}, ", array[0]))?;
143 f.write_fmt(format_args!("{}, ", array[1]))?;
144 f.write_fmt(format_args!("{}, ", array[2]))?;
145 f.write_fmt(format_args!("{}, ", array[3]))?;
146
147 f.write_str("]")
148 },
149 WordRepresentation::Template(storage_placeholder) => {
150 f.write_fmt(format_args!("{}", storage_placeholder))
151 },
152 }
153 }
154}
155
156#[derive(Debug, Clone, PartialEq, Eq)]
161pub enum FeltRepresentation {
162 Hexadecimal(Felt),
164 Decimal(Felt),
166 Template(StoragePlaceholder),
168}
169
170impl FeltRepresentation {
171 pub fn all_placeholders_iter(
173 &self,
174 ) -> impl Iterator<Item = (&StoragePlaceholder, PlaceholderType)> {
175 let maybe_key = match self {
176 FeltRepresentation::Template(storage_placeholder) => {
177 Some((storage_placeholder, PlaceholderType::Felt))
178 },
179 _ => None,
180 };
181
182 maybe_key.into_iter()
183 }
184
185 pub fn try_build_felt(
190 self,
191 init_storage_data: &InitStorageData,
192 ) -> Result<Felt, AccountComponentTemplateError> {
193 match self {
194 FeltRepresentation::Hexadecimal(base_element) => Ok(base_element),
195 FeltRepresentation::Decimal(base_element) => Ok(base_element),
196 FeltRepresentation::Template(storage_placeholder) => init_storage_data
197 .get(&storage_placeholder)
198 .ok_or(AccountComponentTemplateError::PlaceholderValueNotProvided(
199 storage_placeholder,
200 ))?
201 .as_felt()
202 .copied(),
203 }
204 }
205}
206
207impl Default for FeltRepresentation {
208 fn default() -> Self {
209 FeltRepresentation::Hexadecimal(Felt::default())
210 }
211}
212
213impl Serializable for FeltRepresentation {
214 fn write_into<W: ByteWriter>(&self, target: &mut W) {
215 match self {
216 FeltRepresentation::Hexadecimal(felt) => {
217 target.write_u8(0);
218 target.write(felt);
219 },
220 FeltRepresentation::Decimal(felt) => {
221 target.write_u8(1);
222 target.write(felt);
223 },
224 FeltRepresentation::Template(storage_placeholder) => {
225 target.write_u8(2);
226 target.write(storage_placeholder);
227 },
228 }
229 }
230}
231
232impl Deserializable for FeltRepresentation {
233 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
234 let variant_tag = source.read_u8()?;
235
236 match variant_tag {
237 0 => {
238 let felt = Felt::read_from(source)?;
240 Ok(FeltRepresentation::Hexadecimal(felt))
241 },
242 1 => {
243 let felt = Felt::read_from(source)?;
245 Ok(FeltRepresentation::Decimal(felt))
246 },
247 2 => {
248 let storage_placeholder = StoragePlaceholder::read_from(source)?;
250 Ok(FeltRepresentation::Template(storage_placeholder))
251 },
252 _ => Err(DeserializationError::InvalidValue(format!(
253 "unknown variant tag for FeltRepresentation: {}",
254 variant_tag
255 ))),
256 }
257 }
258}
259
260impl core::fmt::Display for FeltRepresentation {
261 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
262 match self {
263 FeltRepresentation::Hexadecimal(base_element) => {
264 f.write_fmt(format_args!("{}", base_element))
265 },
266 FeltRepresentation::Decimal(base_element) => {
267 f.write_fmt(format_args!("{}", base_element))
268 },
269 FeltRepresentation::Template(storage_placeholder) => {
270 f.write_fmt(format_args!("{}", storage_placeholder))
271 },
272 }
273 }
274}
275
276#[derive(Debug, Clone, PartialEq, Eq)]
281#[cfg_attr(feature = "std", derive(::serde::Deserialize, ::serde::Serialize))]
282#[cfg_attr(feature = "std", serde(untagged))]
283pub enum MapRepresentation {
284 List(Vec<MapEntry>),
285 Template(StoragePlaceholder),
286}
287
288impl MapRepresentation {
289 pub fn all_placeholders_iter(
292 &self,
293 ) -> Box<dyn Iterator<Item = (&StoragePlaceholder, PlaceholderType)> + '_> {
294 match self {
295 MapRepresentation::Template(storage_placeholder) => {
296 Box::new(core::iter::once((storage_placeholder, PlaceholderType::Map)))
297 },
298 MapRepresentation::List(entries) => {
299 Box::new(entries.iter().flat_map(|entry| entry.all_placeholders_iter()))
300 },
301 }
302 }
303
304 pub fn len(&self) -> Option<usize> {
307 match self {
308 MapRepresentation::List(vec) => Some(vec.len()),
309 MapRepresentation::Template(_) => None,
310 }
311 }
312
313 pub fn is_empty(&self) -> bool {
316 match self {
317 MapRepresentation::List(vec) => vec.is_empty(),
318 MapRepresentation::Template(_) => false,
319 }
320 }
321
322 pub fn try_build_map(
328 &self,
329 init_storage_data: &InitStorageData,
330 ) -> Result<StorageMap, AccountComponentTemplateError> {
331 let map = match self {
332 MapRepresentation::List(vec) => {
333 let entries = vec
334 .iter()
335 .map(|map_entry| {
336 let key = map_entry.key().try_build_word(init_storage_data)?;
337 let value = map_entry.value().try_build_word(init_storage_data)?;
338 Ok((key.into(), value))
339 })
340 .collect::<Result<Vec<(Digest, Word)>, _>>()?;
341
342 let mut seen_keys = BTreeSet::new();
344 for (map_key, _map_value) in entries.iter() {
345 if !seen_keys.insert(map_key) {
346 return Err(AccountComponentTemplateError::StorageMapHasDuplicateKeys(
347 map_key.to_hex(),
348 ));
349 }
350 }
351
352 StorageMap::with_entries(entries)
353 },
354 MapRepresentation::Template(storage_placeholder) => init_storage_data
355 .get(storage_placeholder)
356 .ok_or_else(|| {
357 AccountComponentTemplateError::PlaceholderValueNotProvided(
358 storage_placeholder.clone(),
359 )
360 })?
361 .as_map()
362 .cloned()?,
363 };
364
365 Ok(map)
366 }
367
368 pub(crate) fn validate(&self) -> Result<(), AccountComponentTemplateError> {
373 match self {
374 MapRepresentation::List(entries) => {
375 let mut seen_keys = BTreeSet::new();
376 for entry in entries {
377 if !seen_keys.insert(entry.key().to_string()) {
378 return Err(AccountComponentTemplateError::StorageMapHasDuplicateKeys(
379 entry.key().to_string(),
380 ));
381 }
382 }
383 },
384 MapRepresentation::Template(_) => {},
385 }
386 Ok(())
387 }
388}
389
390impl Serializable for MapRepresentation {
391 fn write_into<W: ByteWriter>(&self, target: &mut W) {
392 match self {
393 MapRepresentation::List(entries) => {
394 target.write_u8(0);
395 entries.write_into(target);
396 },
397 MapRepresentation::Template(storage_placeholder) => {
398 target.write_u8(1);
399 storage_placeholder.write_into(target);
400 },
401 }
402 }
403}
404
405impl Deserializable for MapRepresentation {
406 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
407 match source.read_u8()? {
408 0 => Ok(MapRepresentation::List(Vec::<MapEntry>::read_from(source)?)),
409 1 => Ok(MapRepresentation::Template(StoragePlaceholder::read_from(source)?)),
410 other => Err(DeserializationError::InvalidValue(format!(
411 "Unknown variant tag for MapRepresentation: {}",
412 other
413 ))),
414 }
415 }
416}
417
418#[cfg(test)]
422mod tests {
423 use vm_core::{
424 utils::{Deserializable, Serializable},
425 Felt, Word,
426 };
427
428 use crate::account::component::template::{
429 storage::{FeltRepresentation, StorageValue, WordRepresentation},
430 InitStorageData, StoragePlaceholder,
431 };
432
433 #[test]
434 fn test_storage_placeholder_try_from_str() {
435 let invalid_strings = vec![
436 "{invalid}",
437 "no_braces",
438 "{{unclosed",
439 "unopened}}",
440 "{}",
441 "{{}}",
442 "{{.}}",
443 "{{foo..bar}}",
444 ];
445
446 for s in invalid_strings {
447 let result = StoragePlaceholder::try_from(s);
448 result.unwrap_err();
449 }
450
451 let s = "{{storage_placeholder}}";
452 let tk = StoragePlaceholder::try_from(s).unwrap();
453 assert_eq!(tk.inner(), "storage_placeholder");
454 }
455
456 #[test]
457 fn test_storage_placeholder_serialization_deserialization() {
458 let original = StoragePlaceholder::new("serialize_test").unwrap();
459 let serialized = original.to_bytes();
460 let deserialized = StoragePlaceholder::read_from_bytes(&serialized).unwrap();
461 assert_eq!(original, deserialized);
462 }
463
464 #[test]
465 fn test_felt_representation_serde() {
466 let felt = Felt::new(1234);
467 let original = FeltRepresentation::Hexadecimal(felt);
468 let serialized = original.to_bytes();
469 let deserialized = FeltRepresentation::read_from_bytes(&serialized).unwrap();
470 assert_eq!(original, deserialized);
471
472 let felt = Felt::new(45563);
473 let original = FeltRepresentation::Decimal(felt);
474 let serialized = original.to_bytes();
475 let deserialized = FeltRepresentation::read_from_bytes(&serialized).unwrap();
476 assert_eq!(original, deserialized);
477
478 let storage_placeholder = StoragePlaceholder::new("template_felt").unwrap();
479 let original = FeltRepresentation::Template(storage_placeholder.clone());
480 let serialized = original.to_bytes();
481 let deserialized = FeltRepresentation::read_from_bytes(&serialized).unwrap();
482 assert_eq!(original, deserialized);
483 }
484
485 #[test]
486 fn test_felt_representation_try_build_felt() {
487 let dyn_key = StoragePlaceholder::new("felt_key").unwrap();
488 let template = FeltRepresentation::Template(dyn_key.clone());
489 let init_storage_data = InitStorageData::new([(
490 StoragePlaceholder::new("felt_key").unwrap(),
491 StorageValue::Felt(Felt::new(300)),
492 )]);
493 let built = template.try_build_felt(&init_storage_data).unwrap();
494 assert_eq!(built, Felt::new(300));
495
496 let dyn_key = StoragePlaceholder::new("missing_key").unwrap();
497 let template = FeltRepresentation::Template(dyn_key.clone());
498 let result = template.try_build_felt(&init_storage_data);
499 result.unwrap_err();
500 }
501
502 #[test]
503 fn test_word_representation_serde() {
504 let word = Word::default();
505 let original = WordRepresentation::Value(word);
506 let serialized = original.to_bytes();
507 let deserialized = WordRepresentation::read_from_bytes(&serialized).unwrap();
508 assert_eq!(original, deserialized);
509
510 let array = [
511 FeltRepresentation::Hexadecimal(Felt::new(10)),
512 FeltRepresentation::Decimal(Felt::new(20)),
513 FeltRepresentation::Template(StoragePlaceholder::new("word_key1").unwrap()),
514 FeltRepresentation::Template(StoragePlaceholder::new("word_key2").unwrap()),
515 ];
516 let original = WordRepresentation::Array(array);
517 let serialized = original.to_bytes();
518 let deserialized = WordRepresentation::read_from_bytes(&serialized).unwrap();
519 assert_eq!(original, deserialized);
520 }
521
522 #[test]
523 fn test_word_representation_template_serde() {
524 let storage_placeholder = StoragePlaceholder::new("temlpate_word").unwrap();
525 let original = WordRepresentation::Template(storage_placeholder.clone());
526 let serialized = original.to_bytes();
527 let deserialized = WordRepresentation::read_from_bytes(&serialized).unwrap();
528 assert_eq!(original, deserialized);
529 }
530}