ssz/decode/
impls.rs

1use super::*;
2use core::num::NonZeroUsize;
3use ethereum_types::{H256, U128, U256};
4use smallvec::SmallVec;
5use std::sync::Arc;
6
7macro_rules! impl_decodable_for_uint {
8    ($type: ident, $bit_size: expr) => {
9        impl Decode for $type {
10            fn is_ssz_fixed_len() -> bool {
11                true
12            }
13
14            fn ssz_fixed_len() -> usize {
15                $bit_size / 8
16            }
17
18            fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
19                let len = bytes.len();
20                let expected = <Self as Decode>::ssz_fixed_len();
21
22                if len != expected {
23                    Err(DecodeError::InvalidByteLength { len, expected })
24                } else {
25                    let mut array: [u8; $bit_size / 8] = std::default::Default::default();
26                    array.clone_from_slice(bytes);
27
28                    Ok(Self::from_le_bytes(array))
29                }
30            }
31        }
32    };
33}
34
35impl_decodable_for_uint!(u8, 8);
36impl_decodable_for_uint!(u16, 16);
37impl_decodable_for_uint!(u32, 32);
38impl_decodable_for_uint!(u64, 64);
39
40#[cfg(target_pointer_width = "32")]
41impl_decodable_for_uint!(usize, 32);
42
43#[cfg(target_pointer_width = "64")]
44impl_decodable_for_uint!(usize, 64);
45
46macro_rules! impl_decode_for_tuples {
47    ($(
48        $Tuple:ident {
49            $(($idx:tt) -> $T:ident)+
50        }
51    )+) => {
52        $(
53            impl<$($T: Decode),+> Decode for ($($T,)+) {
54                fn is_ssz_fixed_len() -> bool {
55                    $(
56                        <$T as Decode>::is_ssz_fixed_len() &&
57                    )*
58                        true
59                }
60
61                fn ssz_fixed_len() -> usize {
62                    if <Self as Decode>::is_ssz_fixed_len() {
63                        $(
64                            <$T as Decode>::ssz_fixed_len() +
65                        )*
66                            0
67                    } else {
68                        BYTES_PER_LENGTH_OFFSET
69                    }
70                }
71
72                fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
73                    let mut builder = SszDecoderBuilder::new(bytes);
74
75                    $(
76                        builder.register_type::<$T>()?;
77                    )*
78
79                    let mut decoder = builder.build()?;
80
81                    Ok(($(
82                            decoder.decode_next::<$T>()?,
83                        )*
84                    ))
85                }
86            }
87        )+
88    }
89}
90
91impl_decode_for_tuples! {
92    Tuple2 {
93        (0) -> A
94        (1) -> B
95    }
96    Tuple3 {
97        (0) -> A
98        (1) -> B
99        (2) -> C
100    }
101    Tuple4 {
102        (0) -> A
103        (1) -> B
104        (2) -> C
105        (3) -> D
106    }
107    Tuple5 {
108        (0) -> A
109        (1) -> B
110        (2) -> C
111        (3) -> D
112        (4) -> E
113    }
114    Tuple6 {
115        (0) -> A
116        (1) -> B
117        (2) -> C
118        (3) -> D
119        (4) -> E
120        (5) -> F
121    }
122    Tuple7 {
123        (0) -> A
124        (1) -> B
125        (2) -> C
126        (3) -> D
127        (4) -> E
128        (5) -> F
129        (6) -> G
130    }
131    Tuple8 {
132        (0) -> A
133        (1) -> B
134        (2) -> C
135        (3) -> D
136        (4) -> E
137        (5) -> F
138        (6) -> G
139        (7) -> H
140    }
141    Tuple9 {
142        (0) -> A
143        (1) -> B
144        (2) -> C
145        (3) -> D
146        (4) -> E
147        (5) -> F
148        (6) -> G
149        (7) -> H
150        (8) -> I
151    }
152    Tuple10 {
153        (0) -> A
154        (1) -> B
155        (2) -> C
156        (3) -> D
157        (4) -> E
158        (5) -> F
159        (6) -> G
160        (7) -> H
161        (8) -> I
162        (9) -> J
163    }
164    Tuple11 {
165        (0) -> A
166        (1) -> B
167        (2) -> C
168        (3) -> D
169        (4) -> E
170        (5) -> F
171        (6) -> G
172        (7) -> H
173        (8) -> I
174        (9) -> J
175        (10) -> K
176    }
177    Tuple12 {
178        (0) -> A
179        (1) -> B
180        (2) -> C
181        (3) -> D
182        (4) -> E
183        (5) -> F
184        (6) -> G
185        (7) -> H
186        (8) -> I
187        (9) -> J
188        (10) -> K
189        (11) -> L
190    }
191}
192
193impl Decode for bool {
194    fn is_ssz_fixed_len() -> bool {
195        true
196    }
197
198    fn ssz_fixed_len() -> usize {
199        1
200    }
201
202    fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
203        let len = bytes.len();
204        let expected = <Self as Decode>::ssz_fixed_len();
205
206        if len != expected {
207            Err(DecodeError::InvalidByteLength { len, expected })
208        } else {
209            match bytes[0] {
210                0b0000_0000 => Ok(false),
211                0b0000_0001 => Ok(true),
212                _ => Err(DecodeError::BytesInvalid(format!(
213                    "Out-of-range for boolean: {}",
214                    bytes[0]
215                ))),
216            }
217        }
218    }
219}
220
221impl Decode for NonZeroUsize {
222    fn is_ssz_fixed_len() -> bool {
223        <usize as Decode>::is_ssz_fixed_len()
224    }
225
226    fn ssz_fixed_len() -> usize {
227        <usize as Decode>::ssz_fixed_len()
228    }
229
230    fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
231        let x = usize::from_ssz_bytes(bytes)?;
232
233        if x == 0 {
234            Err(DecodeError::BytesInvalid(
235                "NonZeroUsize cannot be zero.".to_string(),
236            ))
237        } else {
238            // `unwrap` is safe here as `NonZeroUsize::new()` succeeds if `x > 0` and this path
239            // never executes when `x == 0`.
240            Ok(NonZeroUsize::new(x).unwrap())
241        }
242    }
243}
244
245impl<T: Decode> Decode for Arc<T> {
246    fn is_ssz_fixed_len() -> bool {
247        T::is_ssz_fixed_len()
248    }
249
250    fn ssz_fixed_len() -> usize {
251        T::ssz_fixed_len()
252    }
253
254    fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
255        T::from_ssz_bytes(bytes).map(Arc::new)
256    }
257}
258
259impl Decode for H256 {
260    fn is_ssz_fixed_len() -> bool {
261        true
262    }
263
264    fn ssz_fixed_len() -> usize {
265        32
266    }
267
268    fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
269        let len = bytes.len();
270        let expected = <Self as Decode>::ssz_fixed_len();
271
272        if len != expected {
273            Err(DecodeError::InvalidByteLength { len, expected })
274        } else {
275            Ok(H256::from_slice(bytes))
276        }
277    }
278}
279
280impl Decode for U256 {
281    fn is_ssz_fixed_len() -> bool {
282        true
283    }
284
285    fn ssz_fixed_len() -> usize {
286        32
287    }
288
289    fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
290        let len = bytes.len();
291        let expected = <Self as Decode>::ssz_fixed_len();
292
293        if len != expected {
294            Err(DecodeError::InvalidByteLength { len, expected })
295        } else {
296            Ok(U256::from_little_endian(bytes))
297        }
298    }
299}
300
301impl Decode for U128 {
302    fn is_ssz_fixed_len() -> bool {
303        true
304    }
305
306    fn ssz_fixed_len() -> usize {
307        16
308    }
309
310    fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
311        let len = bytes.len();
312        let expected = <Self as Decode>::ssz_fixed_len();
313
314        if len != expected {
315            Err(DecodeError::InvalidByteLength { len, expected })
316        } else {
317            Ok(U128::from_little_endian(bytes))
318        }
319    }
320}
321
322macro_rules! impl_decodable_for_u8_array {
323    ($len: expr) => {
324        impl Decode for [u8; $len] {
325            fn is_ssz_fixed_len() -> bool {
326                true
327            }
328
329            fn ssz_fixed_len() -> usize {
330                $len
331            }
332
333            fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
334                let len = bytes.len();
335                let expected = <Self as Decode>::ssz_fixed_len();
336
337                if len != expected {
338                    Err(DecodeError::InvalidByteLength { len, expected })
339                } else {
340                    let mut array: [u8; $len] = [0; $len];
341                    array.copy_from_slice(bytes);
342
343                    Ok(array)
344                }
345            }
346        }
347    };
348}
349
350impl_decodable_for_u8_array!(4);
351impl_decodable_for_u8_array!(32);
352
353macro_rules! impl_for_vec {
354    ($type: ty, $max_len: expr) => {
355        impl<T: Decode> Decode for $type {
356            fn is_ssz_fixed_len() -> bool {
357                false
358            }
359
360            fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
361                if bytes.is_empty() {
362                    Ok(vec![].into())
363                } else if T::is_ssz_fixed_len() {
364                    bytes
365                        .chunks(T::ssz_fixed_len())
366                        .map(|chunk| T::from_ssz_bytes(chunk))
367                        .collect()
368                } else {
369                    decode_list_of_variable_length_items(bytes, $max_len).map(|vec| vec.into())
370                }
371            }
372        }
373    };
374}
375
376impl_for_vec!(Vec<T>, None);
377impl_for_vec!(SmallVec<[T; 1]>, Some(1));
378impl_for_vec!(SmallVec<[T; 2]>, Some(2));
379impl_for_vec!(SmallVec<[T; 3]>, Some(3));
380impl_for_vec!(SmallVec<[T; 4]>, Some(4));
381impl_for_vec!(SmallVec<[T; 5]>, Some(5));
382impl_for_vec!(SmallVec<[T; 6]>, Some(6));
383impl_for_vec!(SmallVec<[T; 7]>, Some(7));
384impl_for_vec!(SmallVec<[T; 8]>, Some(8));
385
386/// Decodes `bytes` as if it were a list of variable-length items.
387///
388/// The `ssz::SszDecoder` can also perform this functionality, however it it significantly faster
389/// as it is optimized to read same-typed items whilst `ssz::SszDecoder` supports reading items of
390/// differing types.
391pub fn decode_list_of_variable_length_items<T: Decode>(
392    bytes: &[u8],
393    max_len: Option<usize>,
394) -> Result<Vec<T>, DecodeError> {
395    if bytes.is_empty() {
396        return Ok(vec![]);
397    }
398
399    let first_offset = read_offset(bytes)?;
400    sanitize_offset(first_offset, None, bytes.len(), Some(first_offset))?;
401
402    if first_offset % BYTES_PER_LENGTH_OFFSET != 0 || first_offset < BYTES_PER_LENGTH_OFFSET {
403        return Err(DecodeError::InvalidListFixedBytesLen(first_offset));
404    }
405
406    let num_items = first_offset / BYTES_PER_LENGTH_OFFSET;
407
408    if max_len.map_or(false, |max| num_items > max) {
409        return Err(DecodeError::BytesInvalid(format!(
410            "Variable length list of {} items exceeds maximum of {:?}",
411            num_items, max_len
412        )));
413    }
414
415    // Only initialize the vec with a capacity if a maximum length is provided.
416    //
417    // We assume that if a max length is provided then the application is able to handle an
418    // allocation of this size.
419    let mut values = if max_len.is_some() {
420        Vec::with_capacity(num_items)
421    } else {
422        vec![]
423    };
424
425    let mut offset = first_offset;
426    for i in 1..=num_items {
427        let slice_option = if i == num_items {
428            bytes.get(offset..)
429        } else {
430            let start = offset;
431
432            let next_offset = read_offset(&bytes[(i * BYTES_PER_LENGTH_OFFSET)..])?;
433            offset = sanitize_offset(next_offset, Some(offset), bytes.len(), Some(first_offset))?;
434
435            bytes.get(start..offset)
436        };
437
438        let slice = slice_option.ok_or(DecodeError::OutOfBoundsByte { i: offset })?;
439
440        values.push(T::from_ssz_bytes(slice)?);
441    }
442
443    Ok(values)
444}
445
446#[cfg(test)]
447mod tests {
448    use super::*;
449
450    // Note: decoding of valid bytes is generally tested "indirectly" in the `/tests` dir, by
451    // encoding then decoding the element.
452
453    #[test]
454    fn invalid_u8_array_4() {
455        assert_eq!(
456            <[u8; 4]>::from_ssz_bytes(&[0; 3]),
457            Err(DecodeError::InvalidByteLength {
458                len: 3,
459                expected: 4
460            })
461        );
462
463        assert_eq!(
464            <[u8; 4]>::from_ssz_bytes(&[0; 5]),
465            Err(DecodeError::InvalidByteLength {
466                len: 5,
467                expected: 4
468            })
469        );
470    }
471
472    #[test]
473    fn invalid_bool() {
474        assert_eq!(
475            bool::from_ssz_bytes(&[0; 2]),
476            Err(DecodeError::InvalidByteLength {
477                len: 2,
478                expected: 1
479            })
480        );
481
482        assert_eq!(
483            bool::from_ssz_bytes(&[]),
484            Err(DecodeError::InvalidByteLength {
485                len: 0,
486                expected: 1
487            })
488        );
489
490        if let Err(DecodeError::BytesInvalid(_)) = bool::from_ssz_bytes(&[2]) {
491            // Success.
492        } else {
493            panic!("Did not return error on invalid bool val")
494        }
495    }
496
497    #[test]
498    fn invalid_h256() {
499        assert_eq!(
500            H256::from_ssz_bytes(&[0; 33]),
501            Err(DecodeError::InvalidByteLength {
502                len: 33,
503                expected: 32
504            })
505        );
506
507        assert_eq!(
508            H256::from_ssz_bytes(&[0; 31]),
509            Err(DecodeError::InvalidByteLength {
510                len: 31,
511                expected: 32
512            })
513        );
514    }
515
516    #[test]
517    fn empty_list() {
518        let vec: Vec<Vec<u16>> = vec![];
519        let bytes = vec.as_ssz_bytes();
520        assert!(bytes.is_empty());
521        assert_eq!(Vec::from_ssz_bytes(&bytes), Ok(vec),);
522    }
523
524    #[test]
525    fn first_length_points_backwards() {
526        assert_eq!(
527            <Vec<Vec<u16>>>::from_ssz_bytes(&[0, 0, 0, 0]),
528            Err(DecodeError::InvalidListFixedBytesLen(0))
529        );
530
531        assert_eq!(
532            <Vec<Vec<u16>>>::from_ssz_bytes(&[1, 0, 0, 0]),
533            Err(DecodeError::InvalidListFixedBytesLen(1))
534        );
535
536        assert_eq!(
537            <Vec<Vec<u16>>>::from_ssz_bytes(&[2, 0, 0, 0]),
538            Err(DecodeError::InvalidListFixedBytesLen(2))
539        );
540
541        assert_eq!(
542            <Vec<Vec<u16>>>::from_ssz_bytes(&[3, 0, 0, 0]),
543            Err(DecodeError::InvalidListFixedBytesLen(3))
544        );
545    }
546
547    #[test]
548    fn lengths_are_decreasing() {
549        assert_eq!(
550            <Vec<Vec<u16>>>::from_ssz_bytes(&[12, 0, 0, 0, 14, 0, 0, 0, 12, 0, 0, 0, 1, 0, 1, 0]),
551            Err(DecodeError::OffsetsAreDecreasing(12))
552        );
553    }
554
555    #[test]
556    fn awkward_fixed_length_portion() {
557        assert_eq!(
558            <Vec<Vec<u16>>>::from_ssz_bytes(&[10, 0, 0, 0, 10, 0, 0, 0, 0, 0]),
559            Err(DecodeError::InvalidListFixedBytesLen(10))
560        );
561    }
562
563    #[test]
564    fn length_out_of_bounds() {
565        assert_eq!(
566            <Vec<Vec<u16>>>::from_ssz_bytes(&[5, 0, 0, 0]),
567            Err(DecodeError::OffsetOutOfBounds(5))
568        );
569        assert_eq!(
570            <Vec<Vec<u16>>>::from_ssz_bytes(&[8, 0, 0, 0, 9, 0, 0, 0]),
571            Err(DecodeError::OffsetOutOfBounds(9))
572        );
573        assert_eq!(
574            <Vec<Vec<u16>>>::from_ssz_bytes(&[8, 0, 0, 0, 16, 0, 0, 0]),
575            Err(DecodeError::OffsetOutOfBounds(16))
576        );
577    }
578
579    #[test]
580    fn vec_of_vec_of_u16() {
581        assert_eq!(
582            <Vec<Vec<u16>>>::from_ssz_bytes(&[4, 0, 0, 0]),
583            Ok(vec![vec![]])
584        );
585
586        assert_eq!(
587            <Vec<u16>>::from_ssz_bytes(&[0, 0, 1, 0, 2, 0, 3, 0]),
588            Ok(vec![0, 1, 2, 3])
589        );
590        assert_eq!(<u16>::from_ssz_bytes(&[16, 0]), Ok(16));
591        assert_eq!(<u16>::from_ssz_bytes(&[0, 1]), Ok(256));
592        assert_eq!(<u16>::from_ssz_bytes(&[255, 255]), Ok(65535));
593
594        assert_eq!(
595            <u16>::from_ssz_bytes(&[255]),
596            Err(DecodeError::InvalidByteLength {
597                len: 1,
598                expected: 2
599            })
600        );
601
602        assert_eq!(
603            <u16>::from_ssz_bytes(&[]),
604            Err(DecodeError::InvalidByteLength {
605                len: 0,
606                expected: 2
607            })
608        );
609
610        assert_eq!(
611            <u16>::from_ssz_bytes(&[0, 1, 2]),
612            Err(DecodeError::InvalidByteLength {
613                len: 3,
614                expected: 2
615            })
616        );
617    }
618
619    #[test]
620    fn vec_of_u16() {
621        assert_eq!(<Vec<u16>>::from_ssz_bytes(&[0, 0, 0, 0]), Ok(vec![0, 0]));
622        assert_eq!(
623            <Vec<u16>>::from_ssz_bytes(&[0, 0, 1, 0, 2, 0, 3, 0]),
624            Ok(vec![0, 1, 2, 3])
625        );
626        assert_eq!(<u16>::from_ssz_bytes(&[16, 0]), Ok(16));
627        assert_eq!(<u16>::from_ssz_bytes(&[0, 1]), Ok(256));
628        assert_eq!(<u16>::from_ssz_bytes(&[255, 255]), Ok(65535));
629
630        assert_eq!(
631            <u16>::from_ssz_bytes(&[255]),
632            Err(DecodeError::InvalidByteLength {
633                len: 1,
634                expected: 2
635            })
636        );
637
638        assert_eq!(
639            <u16>::from_ssz_bytes(&[]),
640            Err(DecodeError::InvalidByteLength {
641                len: 0,
642                expected: 2
643            })
644        );
645
646        assert_eq!(
647            <u16>::from_ssz_bytes(&[0, 1, 2]),
648            Err(DecodeError::InvalidByteLength {
649                len: 3,
650                expected: 2
651            })
652        );
653    }
654
655    #[test]
656    fn u16() {
657        assert_eq!(<u16>::from_ssz_bytes(&[0, 0]), Ok(0));
658        assert_eq!(<u16>::from_ssz_bytes(&[16, 0]), Ok(16));
659        assert_eq!(<u16>::from_ssz_bytes(&[0, 1]), Ok(256));
660        assert_eq!(<u16>::from_ssz_bytes(&[255, 255]), Ok(65535));
661
662        assert_eq!(
663            <u16>::from_ssz_bytes(&[255]),
664            Err(DecodeError::InvalidByteLength {
665                len: 1,
666                expected: 2
667            })
668        );
669
670        assert_eq!(
671            <u16>::from_ssz_bytes(&[]),
672            Err(DecodeError::InvalidByteLength {
673                len: 0,
674                expected: 2
675            })
676        );
677
678        assert_eq!(
679            <u16>::from_ssz_bytes(&[0, 1, 2]),
680            Err(DecodeError::InvalidByteLength {
681                len: 3,
682                expected: 2
683            })
684        );
685    }
686
687    #[test]
688    fn tuple() {
689        assert_eq!(<(u16, u16)>::from_ssz_bytes(&[0, 0, 0, 0]), Ok((0, 0)));
690        assert_eq!(<(u16, u16)>::from_ssz_bytes(&[16, 0, 17, 0]), Ok((16, 17)));
691        assert_eq!(<(u16, u16)>::from_ssz_bytes(&[0, 1, 2, 0]), Ok((256, 2)));
692        assert_eq!(
693            <(u16, u16)>::from_ssz_bytes(&[255, 255, 0, 0]),
694            Ok((65535, 0))
695        );
696    }
697}