snarkvm_utilities/serialize/
impls.rs

1// Copyright 2024 Aleo Network Foundation
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16pub use crate::{
17    FromBytes,
18    ToBytes,
19    Vec,
20    io::{Read, Write},
21};
22use crate::{SerializationError, serialize::traits::*};
23
24use bincode::Options;
25
26use std::{borrow::Cow, collections::BTreeMap, marker::PhantomData, rc::Rc, sync::Arc};
27
28impl Valid for bool {
29    fn check(&self) -> Result<(), SerializationError> {
30        Ok(())
31    }
32}
33
34impl CanonicalSerialize for bool {
35    #[inline]
36    fn serialize_with_mode<W: Write>(&self, mut writer: W, _compress: Compress) -> Result<(), SerializationError> {
37        Ok(self.write_le(&mut writer)?)
38    }
39
40    #[inline]
41    fn serialized_size(&self, _compress: Compress) -> usize {
42        1
43    }
44}
45
46impl CanonicalDeserialize for bool {
47    #[inline]
48    fn deserialize_with_mode<R: Read>(
49        reader: R,
50        _compress: Compress,
51        _validate: Validate,
52    ) -> Result<Self, SerializationError> {
53        Ok(bool::read_le(reader)?)
54    }
55}
56
57impl CanonicalSerialize for String {
58    #[inline]
59    fn serialize_with_mode<W: Write>(&self, mut writer: W, _compress: Compress) -> Result<(), SerializationError> {
60        Ok(bincode::serialize_into(&mut writer, self)?)
61    }
62
63    #[inline]
64    fn serialized_size(&self, _compress: Compress) -> usize {
65        self.len() + 8
66    }
67}
68
69impl Valid for String {
70    #[inline]
71    fn check(&self) -> Result<(), SerializationError> {
72        Ok(())
73    }
74
75    #[inline]
76    fn batch_check<'a>(_batch: impl Iterator<Item = &'a Self>) -> Result<(), SerializationError>
77    where
78        Self: 'a,
79    {
80        Ok(())
81    }
82}
83
84impl CanonicalDeserialize for String {
85    #[inline]
86    fn deserialize_with_mode<R: Read>(
87        reader: R,
88        _compress: Compress,
89        _validate: Validate,
90    ) -> Result<Self, SerializationError> {
91        Ok(bincode::DefaultOptions::new()
92            .with_fixint_encoding() // this option is for compatibility with the defaults
93            .allow_trailing_bytes() // so is this
94            .with_limit(10 * 1024)  // a limit to guard against OOMs
95            .deserialize_from(reader)?)
96    }
97}
98
99macro_rules! impl_canonical_serialization_uint {
100    ($type:ty) => {
101        impl CanonicalSerialize for $type {
102            #[inline]
103            fn serialize_with_mode<W: Write>(
104                &self,
105                mut writer: W,
106                _compress: Compress,
107            ) -> Result<(), SerializationError> {
108                Ok(writer.write_all(&self.to_le_bytes())?)
109            }
110
111            #[inline]
112            fn serialized_size(&self, _compress: Compress) -> usize {
113                std::mem::size_of::<$type>()
114            }
115        }
116        impl Valid for $type {
117            #[inline]
118            fn check(&self) -> Result<(), SerializationError> {
119                Ok(())
120            }
121
122            #[inline]
123            fn batch_check<'a>(_batch: impl Iterator<Item = &'a Self>) -> Result<(), SerializationError>
124            where
125                Self: 'a,
126            {
127                Ok(())
128            }
129        }
130
131        impl CanonicalDeserialize for $type {
132            #[inline]
133            fn deserialize_with_mode<R: Read>(
134                mut reader: R,
135                _compress: Compress,
136                _validate: Validate,
137            ) -> Result<Self, SerializationError> {
138                let mut bytes = [0u8; std::mem::size_of::<$type>()];
139                reader.read_exact(&mut bytes)?;
140                Ok(<$type>::from_le_bytes(bytes))
141            }
142        }
143    };
144}
145
146impl_canonical_serialization_uint!(u8);
147impl_canonical_serialization_uint!(u16);
148impl_canonical_serialization_uint!(u32);
149impl_canonical_serialization_uint!(u64);
150
151impl CanonicalSerialize for usize {
152    #[inline]
153    fn serialize_with_mode<W: Write>(&self, mut writer: W, _compress: Compress) -> Result<(), SerializationError> {
154        let u64_value = u64::try_from(*self).map_err(|_| SerializationError::IncompatibleTarget)?;
155        Ok(writer.write_all(&u64_value.to_le_bytes())?)
156    }
157
158    #[inline]
159    fn serialized_size(&self, _compress: Compress) -> usize {
160        8
161    }
162}
163
164impl Valid for usize {
165    #[inline]
166    fn check(&self) -> Result<(), SerializationError> {
167        Ok(())
168    }
169
170    #[inline]
171    fn batch_check<'a>(_batch: impl Iterator<Item = &'a Self>) -> Result<(), SerializationError>
172    where
173        Self: 'a,
174    {
175        Ok(())
176    }
177}
178
179impl CanonicalDeserialize for usize {
180    #[inline]
181    fn deserialize_with_mode<R: Read>(
182        mut reader: R,
183        _compress: Compress,
184        _validate: Validate,
185    ) -> Result<Self, SerializationError> {
186        let u64_value = u64::deserialize_compressed(&mut reader)?;
187        usize::try_from(u64_value).map_err(|_| SerializationError::IncompatibleTarget)
188    }
189}
190
191impl<T: CanonicalSerialize> CanonicalSerialize for Option<T> {
192    #[inline]
193    fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> {
194        self.is_some().serialize_with_mode(&mut writer, compress)?;
195        if let Some(item) = self {
196            item.serialize_with_mode(&mut writer, compress)?;
197        }
198
199        Ok(())
200    }
201
202    #[inline]
203    fn serialized_size(&self, compress: Compress) -> usize {
204        8 + self.as_ref().map(|s| s.serialized_size(compress)).unwrap_or(0)
205    }
206}
207
208impl<T: Valid> Valid for Option<T> {
209    #[inline]
210    fn check(&self) -> Result<(), SerializationError> {
211        match self {
212            Some(v) => v.check(),
213            None => Ok(()),
214        }
215    }
216
217    #[inline]
218    fn batch_check<'a>(batch: impl Iterator<Item = &'a Self> + Send) -> Result<(), SerializationError>
219    where
220        Self: 'a,
221    {
222        T::batch_check(batch.map(Option::as_ref).filter(Option::is_some).flatten())
223    }
224}
225
226impl<T: CanonicalDeserialize> CanonicalDeserialize for Option<T> {
227    #[inline]
228    fn deserialize_with_mode<R: Read>(
229        mut reader: R,
230        compress: Compress,
231        validate: Validate,
232    ) -> Result<Self, SerializationError> {
233        let is_some = bool::deserialize_with_mode(&mut reader, compress, validate)?;
234        let data = if is_some { Some(T::deserialize_with_mode(&mut reader, compress, validate)?) } else { None };
235
236        Ok(data)
237    }
238}
239
240// No-op
241impl<T> CanonicalSerialize for std::marker::PhantomData<T> {
242    #[inline]
243    fn serialize_with_mode<W: Write>(&self, _writer: W, _compress: Compress) -> Result<(), SerializationError> {
244        Ok(())
245    }
246
247    #[inline]
248    fn serialized_size(&self, _compress: Compress) -> usize {
249        0
250    }
251}
252
253impl<T: Sync> Valid for PhantomData<T> {
254    #[inline]
255    fn check(&self) -> Result<(), SerializationError> {
256        Ok(())
257    }
258}
259
260impl<T: Send + Sync> CanonicalDeserialize for std::marker::PhantomData<T> {
261    #[inline]
262    fn deserialize_with_mode<R: Read>(
263        _reader: R,
264        _compress: Compress,
265        _validate: Validate,
266    ) -> Result<Self, SerializationError> {
267        Ok(std::marker::PhantomData)
268    }
269}
270
271impl<T: CanonicalSerialize + ToOwned> CanonicalSerialize for Rc<T> {
272    #[inline]
273    fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> {
274        self.as_ref().serialize_with_mode(&mut writer, compress)
275    }
276
277    #[inline]
278    fn serialized_size(&self, compress: Compress) -> usize {
279        self.as_ref().serialized_size(compress)
280    }
281}
282
283// impl<T: Valid> Valid for Rc<T> {
284//     #[inline]
285//     fn check(&self) -> Result<(), SerializationError> {
286//         self.as_ref().check()
287//     }
288
289//     #[inline]
290
291//     fn batch_check<'a>(batch: impl Iterator<Item = &'a Self>) -> Result<(), SerializationError>
292//     where
293//         Self: 'a,
294//     {
295//         T::batch_check(batch.map(|v| v.as_ref()))
296//     }
297// }
298
299// impl<T: CanonicalDeserialize + ToOwned> CanonicalDeserialize for Rc<T> {
300//     #[inline]
301//     fn deserialize_with_mode<R: Read>(
302//         reader: R,
303//         compress: Compress,
304//         validate: Validate,
305//     ) -> Result<Self, SerializationError> {
306//         Ok(Rc::new(T::deserialize_with_mode(reader, compress, validate)?))
307//     }
308// }
309
310impl<T: CanonicalSerialize> CanonicalSerialize for Arc<T> {
311    #[inline]
312    fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> {
313        self.as_ref().serialize_with_mode(&mut writer, compress)
314    }
315
316    #[inline]
317    fn serialized_size(&self, compress: Compress) -> usize {
318        self.as_ref().serialized_size(compress)
319    }
320}
321
322impl<T: Valid + Sync + Send> Valid for Arc<T> {
323    #[inline]
324    fn check(&self) -> Result<(), SerializationError> {
325        self.as_ref().check()
326    }
327
328    #[inline]
329    fn batch_check<'a>(batch: impl Iterator<Item = &'a Self> + Send) -> Result<(), SerializationError>
330    where
331        Self: 'a,
332    {
333        T::batch_check(batch.map(|v| v.as_ref()))
334    }
335}
336
337impl<T: CanonicalDeserialize + Sync + Send> CanonicalDeserialize for Arc<T> {
338    #[inline]
339    fn deserialize_with_mode<R: Read>(
340        reader: R,
341        compress: Compress,
342        validate: Validate,
343    ) -> Result<Self, SerializationError> {
344        Ok(Arc::new(T::deserialize_with_mode(reader, compress, validate)?))
345    }
346}
347
348impl<T: CanonicalSerialize + ToOwned> CanonicalSerialize for Cow<'_, T> {
349    #[inline]
350    fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> {
351        self.as_ref().serialize_with_mode(&mut writer, compress)
352    }
353
354    #[inline]
355    fn serialized_size(&self, compress: Compress) -> usize {
356        self.as_ref().serialized_size(compress)
357    }
358}
359
360// impl<'b, T> Valid for Cow<'b, T>
361// where
362//     T: ToOwned + Sync + Valid + Send,
363//     <T as ToOwned>::Owned: CanonicalDeserialize + Send + Valid,
364// {
365//     #[inline]
366//     fn check(&self) -> Result<(), SerializationError> {
367//         <<T as ToOwned>::Owned>::check(self.as_ref().borrow())
368//     }
369
370//     #[inline]
371
372//     fn batch_check<'a>(batch: impl Iterator<Item = &'a Self>) -> Result<(), SerializationError>
373//     where
374//         Self: 'a
375//     {
376//         <<T as ToOwned>::Owned>::batch_check(batch.map(|v| v.as_ref()))
377//     }
378// }
379
380// impl<'a, T> CanonicalDeserialize for Cow<'a, T>
381// where
382//     T: ToOwned + Valid + Valid + Sync + Send,
383//     <T as ToOwned>::Owned: CanonicalDeserialize + Valid + Send,
384// {
385//     #[inline]
386//     fn deserialize_with_mode<R: Read>(reader: R, compress: Compress, validate: Validate) -> Result<Self, SerializationError> {
387//         Ok(Cow::Owned(<T as ToOwned>::Owned::deserialize_with_mode(reader, compress, validate)?))
388//     }
389// }
390
391impl<T: CanonicalSerialize> CanonicalSerialize for Vec<T> {
392    #[inline]
393    fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> {
394        self.as_slice().serialize_with_mode(&mut writer, compress)
395    }
396
397    #[inline]
398    fn serialized_size(&self, compress: Compress) -> usize {
399        self.as_slice().serialized_size(compress)
400    }
401}
402
403impl<T: Valid> Valid for Vec<T> {
404    #[inline]
405    fn check(&self) -> Result<(), SerializationError> {
406        T::batch_check(self.iter())
407    }
408
409    #[inline]
410    fn batch_check<'a>(batch: impl Iterator<Item = &'a Self> + Send) -> Result<(), SerializationError>
411    where
412        Self: 'a,
413    {
414        T::batch_check(batch.flatten())
415    }
416}
417
418impl<T: CanonicalDeserialize> CanonicalDeserialize for Vec<T> {
419    #[inline]
420    fn deserialize_with_mode<R: Read>(
421        mut reader: R,
422        compress: Compress,
423        validate: Validate,
424    ) -> Result<Self, SerializationError> {
425        let len = u64::deserialize_with_mode(&mut reader, compress, validate)?;
426        let mut values = Vec::new();
427        let _ = values.try_reserve(len as usize);
428        for _ in 0..len {
429            values.push(T::deserialize_with_mode(&mut reader, compress, Validate::No)?);
430        }
431
432        if let Validate::Yes = validate {
433            T::batch_check(values.iter())?
434        }
435        Ok(values)
436    }
437}
438
439impl<T: CanonicalDeserialize + std::fmt::Debug> CanonicalDeserialize for [T; 32] {
440    #[inline]
441    fn deserialize_with_mode<R: Read>(
442        mut reader: R,
443        compress: Compress,
444        validate: Validate,
445    ) -> Result<Self, SerializationError> {
446        let values = [(); 32].map(|_| T::deserialize_with_mode(&mut reader, compress, Validate::No));
447
448        // check that each value is error free
449        if values.iter().any(|value| value.is_err()) {
450            return Err(SerializationError::InvalidData);
451        }
452
453        let values = values.map(|r| r.unwrap());
454
455        if let Validate::Yes = validate {
456            T::batch_check(values.iter())?
457        }
458
459        Ok(values)
460    }
461}
462
463impl<T: Valid> Valid for [T; 32] {
464    #[inline]
465    fn check(&self) -> Result<(), SerializationError> {
466        T::batch_check(self.iter())
467    }
468
469    #[inline]
470    fn batch_check<'a>(batch: impl Iterator<Item = &'a Self> + Send) -> Result<(), SerializationError>
471    where
472        Self: 'a,
473    {
474        T::batch_check(batch.flatten())
475    }
476}
477
478impl<T: CanonicalSerialize> CanonicalSerialize for [T] {
479    #[inline]
480    fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> {
481        let len = self.len() as u64;
482        len.serialize_with_mode(&mut writer, compress)?;
483        for item in self.iter() {
484            item.serialize_with_mode(&mut writer, compress)?;
485        }
486        Ok(())
487    }
488
489    #[inline]
490    fn serialized_size(&self, compress: Compress) -> usize {
491        8 + self.iter().map(|item| item.serialized_size(compress)).sum::<usize>()
492    }
493}
494
495impl<T: CanonicalSerialize> CanonicalSerialize for [T; 32] {
496    #[inline]
497    fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> {
498        for item in self.iter() {
499            item.serialize_with_mode(&mut writer, compress)?;
500        }
501        Ok(())
502    }
503
504    #[inline]
505    fn serialized_size(&self, compress: Compress) -> usize {
506        8 + self.iter().map(|item| item.serialized_size(compress)).sum::<usize>()
507    }
508}
509
510impl<T: CanonicalSerialize> CanonicalSerialize for &'_ [T] {
511    #[inline]
512    fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> {
513        (*self).serialize_with_mode(&mut writer, compress)
514    }
515
516    #[inline]
517    fn serialized_size(&self, compress: Compress) -> usize {
518        (*self).serialized_size(compress)
519    }
520}
521
522// Implement Serialization for tuples
523macro_rules! impl_tuple {
524    ($( $ty: ident : $no: tt, )+) => {
525        impl<$($ty, )+> Valid for ($($ty,)+) where
526            $($ty: Valid,)+
527        {
528            #[inline]
529            fn check(&self) -> Result<(), SerializationError> {
530                $(self.$no.check()?;)*
531                Ok(())
532            }
533        }
534
535        impl<$($ty, )+> CanonicalSerialize for ($($ty,)+) where
536            $($ty: CanonicalSerialize,)+
537        {
538            #[inline]
539            fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> {
540                $(self.$no.serialize_with_mode(&mut writer, compress)?;)*
541                Ok(())
542            }
543
544            #[inline]
545            fn serialized_size(&self, compress: Compress) -> usize {
546                [$(
547                    self.$no.serialized_size(compress),
548                )*].iter().sum()
549            }
550        }
551
552        impl<$($ty, )+> CanonicalDeserialize for ($($ty,)+) where
553            $($ty: CanonicalDeserialize,)+
554        {
555            #[inline]
556            fn deserialize_with_mode<R: Read>(mut reader: R, compress: Compress, validate: Validate) -> Result<Self, SerializationError> {
557                Ok(($(
558                    $ty::deserialize_with_mode(&mut reader, compress, validate)?,
559                )+))
560            }
561        }
562    }
563}
564
565impl_tuple!(A:0, B:1,);
566impl_tuple!(A:0, B:1, C:2,);
567impl_tuple!(A:0, B:1, C:2, D:3,);
568
569impl<K, V> CanonicalSerialize for BTreeMap<K, V>
570where
571    K: CanonicalSerialize,
572    V: CanonicalSerialize,
573{
574    /// Serializes a `BTreeMap` as `len(map) || key 1 || value 1 || ... || key n || value n`.
575    fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> {
576        let len = self.len() as u64;
577        len.serialize_with_mode(&mut writer, compress)?;
578        for (k, v) in self.iter() {
579            k.serialize_with_mode(&mut writer, compress)?;
580            v.serialize_with_mode(&mut writer, compress)?;
581        }
582        Ok(())
583    }
584
585    fn serialized_size(&self, compress: Compress) -> usize {
586        8 + self.iter().map(|(k, v)| k.serialized_size(compress) + v.serialized_size(compress)).sum::<usize>()
587    }
588}
589
590impl<K: Valid, V: Valid> Valid for BTreeMap<K, V> {
591    #[inline]
592    fn check(&self) -> Result<(), SerializationError> {
593        K::batch_check(self.keys())?;
594        V::batch_check(self.values())
595    }
596
597    #[inline]
598    fn batch_check<'a>(batch: impl Iterator<Item = &'a Self>) -> Result<(), SerializationError>
599    where
600        Self: 'a,
601    {
602        let (keys, values): (Vec<_>, Vec<_>) = batch.map(|b| (b.keys(), b.values())).unzip();
603        K::batch_check(keys.into_iter().flatten())?;
604        V::batch_check(values.into_iter().flatten())
605    }
606}
607
608impl<K, V> CanonicalDeserialize for BTreeMap<K, V>
609where
610    K: Ord + CanonicalDeserialize,
611    V: CanonicalDeserialize,
612{
613    /// Deserializes a `BTreeMap` from `len(map) || key 1 || value 1 || ... || key n || value n`.
614    fn deserialize_with_mode<R: Read>(
615        mut reader: R,
616        compress: Compress,
617        validate: Validate,
618    ) -> Result<Self, SerializationError> {
619        let len = u64::deserialize_with_mode(&mut reader, compress, validate)?;
620        let mut map = BTreeMap::new();
621        for _ in 0..len {
622            map.insert(
623                K::deserialize_with_mode(&mut reader, compress, validate)?,
624                V::deserialize_with_mode(&mut reader, compress, validate)?,
625            );
626        }
627        Ok(map)
628    }
629}
630
631#[cfg(test)]
632mod test {
633    use super::*;
634    use crate::{deserialize_vec_without_len, serialize_vec_without_len, serialized_vec_size_without_len};
635
636    fn test_serialize<T: PartialEq + std::fmt::Debug + CanonicalSerialize + CanonicalDeserialize>(data: T) {
637        let combinations = [
638            (Compress::No, Validate::No),
639            (Compress::Yes, Validate::No),
640            (Compress::No, Validate::Yes),
641            (Compress::Yes, Validate::Yes),
642        ];
643        for (compress, validate) in combinations {
644            let mut serialized = vec![0; data.serialized_size(compress)];
645            data.serialize_with_mode(&mut serialized[..], compress).unwrap();
646            let de = T::deserialize_with_mode(&serialized[..], compress, validate).unwrap();
647            assert_eq!(data, de);
648        }
649    }
650
651    fn test_serialize_without_len<T: PartialEq + std::fmt::Debug + CanonicalSerialize + CanonicalDeserialize>(
652        data: Vec<T>,
653    ) {
654        let combinations = [
655            (Compress::No, Validate::No),
656            (Compress::Yes, Validate::No),
657            (Compress::No, Validate::Yes),
658            (Compress::Yes, Validate::Yes),
659        ];
660        for (compress, validate) in combinations {
661            let len = serialized_vec_size_without_len(&data, compress);
662            let mut serialized = vec![0; len];
663            serialize_vec_without_len(data.iter(), serialized.as_mut_slice(), compress).unwrap();
664            let elements = if len > 0 { len / CanonicalSerialize::serialized_size(&data[0], compress) } else { 0 };
665            let de = deserialize_vec_without_len(serialized.as_slice(), compress, validate, elements).unwrap();
666            assert_eq!(data, de);
667        }
668    }
669
670    #[test]
671    fn test_bool() {
672        test_serialize(true);
673        test_serialize(false);
674    }
675
676    #[test]
677    fn test_uint() {
678        test_serialize(192830918usize);
679        test_serialize(192830918u64);
680        test_serialize(192830918u32);
681        test_serialize(22313u16);
682        test_serialize(123u8);
683    }
684
685    #[test]
686    fn test_string() {
687        test_serialize("asdf".to_owned());
688    }
689
690    #[test]
691    fn test_vec() {
692        test_serialize(vec![1u64, 2, 3, 4, 5]);
693        test_serialize(Vec::<u64>::new());
694    }
695
696    #[test]
697    fn test_vec_without_len() {
698        test_serialize_without_len(vec![1u64, 2, 3, 4, 5]);
699        test_serialize_without_len(Vec::<u64>::new());
700    }
701
702    #[test]
703    fn test_tuple() {
704        test_serialize((123u64, 234u32, 999u16));
705    }
706
707    #[test]
708    fn test_tuple_vec() {
709        test_serialize(vec![(123u64, 234u32, 999u16), (123u64, 234u32, 999u16), (123u64, 234u32, 999u16)]);
710    }
711
712    #[test]
713    fn test_option() {
714        test_serialize(Some(3u32));
715        test_serialize(None::<u32>);
716    }
717
718    #[test]
719    fn test_phantomdata() {
720        test_serialize(std::marker::PhantomData::<u64>);
721    }
722}