1use super::*;
2use crate::decode::try_from_iter::{TryCollect, TryFromIter};
3use alloy_primitives::{Address, Bloom, Bytes, FixedBytes, U128, U256};
4use core::num::NonZeroUsize;
5use itertools::process_results;
6use smallvec::SmallVec;
7use std::collections::{BTreeMap, BTreeSet};
8use std::iter::{self, FromIterator};
9use std::sync::Arc;
10
11macro_rules! impl_decodable_for_uint {
12 ($type: ident, $bit_size: expr) => {
13 impl Decode for $type {
14 #[inline(always)]
15 fn is_ssz_fixed_len() -> bool {
16 true
17 }
18
19 #[inline(always)]
20 fn ssz_fixed_len() -> usize {
21 $bit_size / 8
22 }
23
24 #[inline(always)]
25 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
26 let len = bytes.len();
27 let expected = <Self as Decode>::ssz_fixed_len();
28
29 if len != expected {
30 Err(DecodeError::InvalidByteLength { len, expected })
31 } else {
32 let mut array: [u8; $bit_size / 8] = std::default::Default::default();
33 array.clone_from_slice(bytes);
34
35 Ok(Self::from_le_bytes(array))
36 }
37 }
38 }
39 };
40}
41
42impl_decodable_for_uint!(u8, 8);
43impl_decodable_for_uint!(u16, 16);
44impl_decodable_for_uint!(u32, 32);
45impl_decodable_for_uint!(u64, 64);
46impl_decodable_for_uint!(u128, 128);
47
48#[cfg(target_pointer_width = "32")]
49impl_decodable_for_uint!(usize, 32);
50
51#[cfg(target_pointer_width = "64")]
52impl_decodable_for_uint!(usize, 64);
53
54macro_rules! impl_decode_for_tuples {
55 ($(
56 $Tuple:ident {
57 $(($idx:tt) -> $T:ident)+
58 }
59 )+) => {
60 $(
61 impl<$($T: Decode),+> Decode for ($($T,)+) {
62 fn is_ssz_fixed_len() -> bool {
63 $(
64 <$T as Decode>::is_ssz_fixed_len() &&
65 )*
66 true
67 }
68
69 fn ssz_fixed_len() -> usize {
70 if <Self as Decode>::is_ssz_fixed_len() {
71 $(
72 <$T as Decode>::ssz_fixed_len() +
73 )*
74 0
75 } else {
76 BYTES_PER_LENGTH_OFFSET
77 }
78 }
79
80 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
81 let mut builder = SszDecoderBuilder::new(bytes);
82
83 $(
84 builder.register_type::<$T>()?;
85 )*
86
87 let mut decoder = builder.build()?;
88
89 Ok(($(
90 decoder.decode_next::<$T>()?,
91 )*
92 ))
93 }
94 }
95 )+
96 }
97}
98
99impl_decode_for_tuples! {
100 Tuple2 {
101 (0) -> A
102 (1) -> B
103 }
104 Tuple3 {
105 (0) -> A
106 (1) -> B
107 (2) -> C
108 }
109 Tuple4 {
110 (0) -> A
111 (1) -> B
112 (2) -> C
113 (3) -> D
114 }
115 Tuple5 {
116 (0) -> A
117 (1) -> B
118 (2) -> C
119 (3) -> D
120 (4) -> E
121 }
122 Tuple6 {
123 (0) -> A
124 (1) -> B
125 (2) -> C
126 (3) -> D
127 (4) -> E
128 (5) -> F
129 }
130 Tuple7 {
131 (0) -> A
132 (1) -> B
133 (2) -> C
134 (3) -> D
135 (4) -> E
136 (5) -> F
137 (6) -> G
138 }
139 Tuple8 {
140 (0) -> A
141 (1) -> B
142 (2) -> C
143 (3) -> D
144 (4) -> E
145 (5) -> F
146 (6) -> G
147 (7) -> H
148 }
149 Tuple9 {
150 (0) -> A
151 (1) -> B
152 (2) -> C
153 (3) -> D
154 (4) -> E
155 (5) -> F
156 (6) -> G
157 (7) -> H
158 (8) -> I
159 }
160 Tuple10 {
161 (0) -> A
162 (1) -> B
163 (2) -> C
164 (3) -> D
165 (4) -> E
166 (5) -> F
167 (6) -> G
168 (7) -> H
169 (8) -> I
170 (9) -> J
171 }
172 Tuple11 {
173 (0) -> A
174 (1) -> B
175 (2) -> C
176 (3) -> D
177 (4) -> E
178 (5) -> F
179 (6) -> G
180 (7) -> H
181 (8) -> I
182 (9) -> J
183 (10) -> K
184 }
185 Tuple12 {
186 (0) -> A
187 (1) -> B
188 (2) -> C
189 (3) -> D
190 (4) -> E
191 (5) -> F
192 (6) -> G
193 (7) -> H
194 (8) -> I
195 (9) -> J
196 (10) -> K
197 (11) -> L
198 }
199}
200
201impl Decode for bool {
202 fn is_ssz_fixed_len() -> bool {
203 true
204 }
205
206 fn ssz_fixed_len() -> usize {
207 1
208 }
209
210 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
211 let len = bytes.len();
212 let expected = <Self as Decode>::ssz_fixed_len();
213
214 if len != expected {
215 Err(DecodeError::InvalidByteLength { len, expected })
216 } else {
217 match bytes[0] {
218 0b0000_0000 => Ok(false),
219 0b0000_0001 => Ok(true),
220 _ => Err(DecodeError::BytesInvalid(format!(
221 "Out-of-range for boolean: {}",
222 bytes[0]
223 ))),
224 }
225 }
226 }
227}
228
229impl Decode for NonZeroUsize {
230 fn is_ssz_fixed_len() -> bool {
231 <usize as Decode>::is_ssz_fixed_len()
232 }
233
234 fn ssz_fixed_len() -> usize {
235 <usize as Decode>::ssz_fixed_len()
236 }
237
238 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
239 let x = usize::from_ssz_bytes(bytes)?;
240
241 if x == 0 {
242 Err(DecodeError::BytesInvalid(
243 "NonZeroUsize cannot be zero.".to_string(),
244 ))
245 } else {
246 Ok(NonZeroUsize::new(x).unwrap())
249 }
250 }
251}
252
253impl<T: Decode> Decode for Option<T> {
254 fn is_ssz_fixed_len() -> bool {
255 false
256 }
257 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
258 let (selector, body) = split_union_bytes(bytes)?;
259 match selector.into() {
260 0u8 => Ok(None),
261 1u8 => <T as Decode>::from_ssz_bytes(body).map(Option::Some),
262 other => Err(DecodeError::UnionSelectorInvalid(other)),
263 }
264 }
265}
266
267impl<T: Decode> Decode for Arc<T> {
268 fn is_ssz_fixed_len() -> bool {
269 T::is_ssz_fixed_len()
270 }
271
272 fn ssz_fixed_len() -> usize {
273 T::ssz_fixed_len()
274 }
275
276 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
277 T::from_ssz_bytes(bytes).map(Arc::new)
278 }
279}
280
281impl Decode for Address {
282 fn is_ssz_fixed_len() -> bool {
283 true
284 }
285
286 fn ssz_fixed_len() -> usize {
287 20
288 }
289
290 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
291 let len = bytes.len();
292 let expected = <Self as Decode>::ssz_fixed_len();
293
294 if len != expected {
295 Err(DecodeError::InvalidByteLength { len, expected })
296 } else {
297 Ok(Self::from_slice(bytes))
298 }
299 }
300}
301
302impl<const N: usize> Decode for FixedBytes<N> {
303 fn is_ssz_fixed_len() -> bool {
304 true
305 }
306
307 fn ssz_fixed_len() -> usize {
308 N
309 }
310
311 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
312 if bytes.len() != N {
313 return Err(DecodeError::InvalidByteLength {
314 len: bytes.len(),
315 expected: N,
316 });
317 }
318
319 let mut fixed_array = [0u8; N];
320 fixed_array.copy_from_slice(bytes);
321
322 Ok(Self(fixed_array))
323 }
324}
325
326impl Decode for Bloom {
327 fn is_ssz_fixed_len() -> bool {
328 true
329 }
330
331 fn ssz_fixed_len() -> usize {
332 256
333 }
334
335 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
336 let len = bytes.len();
337 let expected = <Self as Decode>::ssz_fixed_len();
338
339 if len != expected {
340 Err(DecodeError::InvalidByteLength { len, expected })
341 } else {
342 Ok(Self::from_slice(bytes))
343 }
344 }
345}
346
347impl Decode for U256 {
348 fn is_ssz_fixed_len() -> bool {
349 true
350 }
351
352 fn ssz_fixed_len() -> usize {
353 32
354 }
355
356 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
357 let len = bytes.len();
358 let expected = <Self as Decode>::ssz_fixed_len();
359
360 if len != expected {
361 Err(DecodeError::InvalidByteLength { len, expected })
362 } else {
363 Ok(U256::from_le_slice(bytes))
364 }
365 }
366}
367
368impl Decode for Bytes {
369 #[inline]
370 fn is_ssz_fixed_len() -> bool {
371 false
372 }
373
374 #[inline]
375 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
376 Ok(bytes.to_vec().into())
377 }
378}
379
380impl Decode for U128 {
381 fn is_ssz_fixed_len() -> bool {
382 true
383 }
384
385 fn ssz_fixed_len() -> usize {
386 16
387 }
388
389 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
390 let len = bytes.len();
391 let expected = <Self as Decode>::ssz_fixed_len();
392
393 if len != expected {
394 Err(DecodeError::InvalidByteLength { len, expected })
395 } else {
396 Ok(U128::from_le_slice(bytes))
397 }
398 }
399}
400
401impl<const N: usize> Decode for [u8; N] {
402 fn is_ssz_fixed_len() -> bool {
403 true
404 }
405
406 fn ssz_fixed_len() -> usize {
407 N
408 }
409
410 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
411 let len = bytes.len();
412 let expected = <Self as Decode>::ssz_fixed_len();
413
414 if len != expected {
415 Err(DecodeError::InvalidByteLength { len, expected })
416 } else {
417 let mut array: [u8; N] = [0; N];
418 array.copy_from_slice(bytes);
419
420 Ok(array)
421 }
422 }
423}
424
425impl<T: Decode> Decode for Vec<T> {
426 fn is_ssz_fixed_len() -> bool {
427 false
428 }
429
430 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
431 if bytes.is_empty() {
432 Ok(vec![])
433 } else if T::is_ssz_fixed_len() {
434 bytes
435 .chunks(T::ssz_fixed_len())
436 .map(T::from_ssz_bytes)
437 .collect()
438 } else {
439 decode_list_of_variable_length_items(bytes, None)
440 }
441 }
442}
443
444impl<T: Decode, const N: usize> Decode for SmallVec<[T; N]> {
445 fn is_ssz_fixed_len() -> bool {
446 false
447 }
448
449 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
450 if bytes.is_empty() {
451 Ok(SmallVec::new())
452 } else if T::is_ssz_fixed_len() {
453 bytes
454 .chunks(T::ssz_fixed_len())
455 .map(T::from_ssz_bytes)
456 .collect()
457 } else {
458 decode_list_of_variable_length_items(bytes, None)
459 }
460 }
461}
462
463impl<K, V> Decode for BTreeMap<K, V>
464where
465 K: Decode + Ord,
466 V: Decode,
467{
468 fn is_ssz_fixed_len() -> bool {
469 false
470 }
471
472 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
473 if bytes.is_empty() {
474 Ok(Self::from_iter(iter::empty()))
475 } else if <(K, V)>::is_ssz_fixed_len() {
476 bytes
477 .chunks(<(K, V)>::ssz_fixed_len())
478 .map(<(K, V)>::from_ssz_bytes)
479 .collect()
480 } else {
481 decode_list_of_variable_length_items(bytes, None)
482 }
483 }
484}
485
486impl<T> Decode for BTreeSet<T>
487where
488 T: Decode + Ord,
489{
490 fn is_ssz_fixed_len() -> bool {
491 false
492 }
493
494 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
495 if bytes.is_empty() {
496 Ok(Self::from_iter(iter::empty()))
497 } else if T::is_ssz_fixed_len() {
498 bytes
499 .chunks(T::ssz_fixed_len())
500 .map(T::from_ssz_bytes)
501 .collect()
502 } else {
503 decode_list_of_variable_length_items(bytes, None)
504 }
505 }
506}
507
508pub fn decode_list_of_variable_length_items<T: Decode, Container: TryFromIter<T>>(
514 bytes: &[u8],
515 max_len: Option<usize>,
516) -> Result<Container, DecodeError> {
517 if bytes.is_empty() {
518 return Container::try_from_iter(iter::empty()).map_err(|e| {
519 DecodeError::BytesInvalid(format!("Error trying to collect empty list: {:?}", e))
520 });
521 }
522
523 let first_offset = read_offset(bytes)?;
524 sanitize_offset(first_offset, None, bytes.len(), Some(first_offset))?;
525
526 if first_offset % BYTES_PER_LENGTH_OFFSET != 0 || first_offset < BYTES_PER_LENGTH_OFFSET {
527 return Err(DecodeError::InvalidListFixedBytesLen(first_offset));
528 }
529
530 let num_items = first_offset / BYTES_PER_LENGTH_OFFSET;
531
532 if max_len.is_some_and(|max| num_items > max) {
533 return Err(DecodeError::BytesInvalid(format!(
534 "Variable length list of {} items exceeds maximum of {:?}",
535 num_items, max_len
536 )));
537 }
538
539 let mut offset = first_offset;
540 process_results(
541 (1..=num_items).map(|i| {
542 let slice_option = if i == num_items {
543 bytes.get(offset..)
544 } else {
545 let start = offset;
546
547 let next_offset = read_offset(&bytes[(i * BYTES_PER_LENGTH_OFFSET)..])?;
548 offset =
549 sanitize_offset(next_offset, Some(offset), bytes.len(), Some(first_offset))?;
550
551 bytes.get(start..offset)
552 };
553
554 let slice = slice_option.ok_or(DecodeError::OutOfBoundsByte { i: offset })?;
555 T::from_ssz_bytes(slice)
556 }),
557 |iter| iter.try_collect(),
558 )?
559 .map_err(|e| DecodeError::BytesInvalid(format!("Error collecting into container: {:?}", e)))
560}
561
562#[cfg(test)]
563mod tests {
564 use super::*;
565 use alloy_primitives::B256;
566
567 #[test]
571 fn invalid_u8_array_4() {
572 assert_eq!(
573 <[u8; 4]>::from_ssz_bytes(&[0; 3]),
574 Err(DecodeError::InvalidByteLength {
575 len: 3,
576 expected: 4
577 })
578 );
579
580 assert_eq!(
581 <[u8; 4]>::from_ssz_bytes(&[0; 5]),
582 Err(DecodeError::InvalidByteLength {
583 len: 5,
584 expected: 4
585 })
586 );
587 }
588
589 #[test]
590 fn invalid_bool() {
591 assert_eq!(
592 bool::from_ssz_bytes(&[0; 2]),
593 Err(DecodeError::InvalidByteLength {
594 len: 2,
595 expected: 1
596 })
597 );
598
599 assert_eq!(
600 bool::from_ssz_bytes(&[]),
601 Err(DecodeError::InvalidByteLength {
602 len: 0,
603 expected: 1
604 })
605 );
606
607 if let Err(DecodeError::BytesInvalid(_)) = bool::from_ssz_bytes(&[2]) {
608 } else {
610 panic!("Did not return error on invalid bool val")
611 }
612 }
613
614 #[test]
615 fn invalid_b256() {
616 assert_eq!(
617 B256::from_ssz_bytes(&[0; 33]),
618 Err(DecodeError::InvalidByteLength {
619 len: 33,
620 expected: 32
621 })
622 );
623
624 assert_eq!(
625 B256::from_ssz_bytes(&[0; 31]),
626 Err(DecodeError::InvalidByteLength {
627 len: 31,
628 expected: 32
629 })
630 );
631 }
632
633 #[test]
634 fn empty_list() {
635 let vec: Vec<Vec<u16>> = vec![];
636 let bytes = vec.as_ssz_bytes();
637 assert!(bytes.is_empty());
638 assert_eq!(Vec::from_ssz_bytes(&bytes), Ok(vec),);
639 }
640
641 #[test]
642 fn first_length_points_backwards() {
643 assert_eq!(
644 <Vec<Vec<u16>>>::from_ssz_bytes(&[0, 0, 0, 0]),
645 Err(DecodeError::InvalidListFixedBytesLen(0))
646 );
647
648 assert_eq!(
649 <Vec<Vec<u16>>>::from_ssz_bytes(&[1, 0, 0, 0]),
650 Err(DecodeError::InvalidListFixedBytesLen(1))
651 );
652
653 assert_eq!(
654 <Vec<Vec<u16>>>::from_ssz_bytes(&[2, 0, 0, 0]),
655 Err(DecodeError::InvalidListFixedBytesLen(2))
656 );
657
658 assert_eq!(
659 <Vec<Vec<u16>>>::from_ssz_bytes(&[3, 0, 0, 0]),
660 Err(DecodeError::InvalidListFixedBytesLen(3))
661 );
662 }
663
664 #[test]
665 fn lengths_are_decreasing() {
666 assert_eq!(
667 <Vec<Vec<u16>>>::from_ssz_bytes(&[12, 0, 0, 0, 14, 0, 0, 0, 12, 0, 0, 0, 1, 0, 1, 0]),
668 Err(DecodeError::OffsetsAreDecreasing(12))
669 );
670 }
671
672 #[test]
673 fn awkward_fixed_length_portion() {
674 assert_eq!(
675 <Vec<Vec<u16>>>::from_ssz_bytes(&[10, 0, 0, 0, 10, 0, 0, 0, 0, 0]),
676 Err(DecodeError::InvalidListFixedBytesLen(10))
677 );
678 }
679
680 #[test]
681 fn length_out_of_bounds() {
682 assert_eq!(
683 <Vec<Vec<u16>>>::from_ssz_bytes(&[5, 0, 0, 0]),
684 Err(DecodeError::OffsetOutOfBounds(5))
685 );
686 assert_eq!(
687 <Vec<Vec<u16>>>::from_ssz_bytes(&[8, 0, 0, 0, 9, 0, 0, 0]),
688 Err(DecodeError::OffsetOutOfBounds(9))
689 );
690 assert_eq!(
691 <Vec<Vec<u16>>>::from_ssz_bytes(&[8, 0, 0, 0, 16, 0, 0, 0]),
692 Err(DecodeError::OffsetOutOfBounds(16))
693 );
694 }
695
696 #[test]
697 fn vec_of_vec_of_u16() {
698 assert_eq!(
699 <Vec<Vec<u16>>>::from_ssz_bytes(&[4, 0, 0, 0]),
700 Ok(vec![vec![]])
701 );
702
703 assert_eq!(
704 <Vec<u16>>::from_ssz_bytes(&[0, 0, 1, 0, 2, 0, 3, 0]),
705 Ok(vec![0, 1, 2, 3])
706 );
707 assert_eq!(<u16>::from_ssz_bytes(&[16, 0]), Ok(16));
708 assert_eq!(<u16>::from_ssz_bytes(&[0, 1]), Ok(256));
709 assert_eq!(<u16>::from_ssz_bytes(&[255, 255]), Ok(65535));
710
711 assert_eq!(
712 <u16>::from_ssz_bytes(&[255]),
713 Err(DecodeError::InvalidByteLength {
714 len: 1,
715 expected: 2
716 })
717 );
718
719 assert_eq!(
720 <u16>::from_ssz_bytes(&[]),
721 Err(DecodeError::InvalidByteLength {
722 len: 0,
723 expected: 2
724 })
725 );
726
727 assert_eq!(
728 <u16>::from_ssz_bytes(&[0, 1, 2]),
729 Err(DecodeError::InvalidByteLength {
730 len: 3,
731 expected: 2
732 })
733 );
734 }
735
736 #[test]
737 fn vec_of_u16() {
738 assert_eq!(<Vec<u16>>::from_ssz_bytes(&[0, 0, 0, 0]), Ok(vec![0, 0]));
739 assert_eq!(
740 <Vec<u16>>::from_ssz_bytes(&[0, 0, 1, 0, 2, 0, 3, 0]),
741 Ok(vec![0, 1, 2, 3])
742 );
743 assert_eq!(<u16>::from_ssz_bytes(&[16, 0]), Ok(16));
744 assert_eq!(<u16>::from_ssz_bytes(&[0, 1]), Ok(256));
745 assert_eq!(<u16>::from_ssz_bytes(&[255, 255]), Ok(65535));
746
747 assert_eq!(
748 <u16>::from_ssz_bytes(&[255]),
749 Err(DecodeError::InvalidByteLength {
750 len: 1,
751 expected: 2
752 })
753 );
754
755 assert_eq!(
756 <u16>::from_ssz_bytes(&[]),
757 Err(DecodeError::InvalidByteLength {
758 len: 0,
759 expected: 2
760 })
761 );
762
763 assert_eq!(
764 <u16>::from_ssz_bytes(&[0, 1, 2]),
765 Err(DecodeError::InvalidByteLength {
766 len: 3,
767 expected: 2
768 })
769 );
770 }
771
772 #[test]
773 fn u16() {
774 assert_eq!(<u16>::from_ssz_bytes(&[0, 0]), Ok(0));
775 assert_eq!(<u16>::from_ssz_bytes(&[16, 0]), Ok(16));
776 assert_eq!(<u16>::from_ssz_bytes(&[0, 1]), Ok(256));
777 assert_eq!(<u16>::from_ssz_bytes(&[255, 255]), Ok(65535));
778
779 assert_eq!(
780 <u16>::from_ssz_bytes(&[255]),
781 Err(DecodeError::InvalidByteLength {
782 len: 1,
783 expected: 2
784 })
785 );
786
787 assert_eq!(
788 <u16>::from_ssz_bytes(&[]),
789 Err(DecodeError::InvalidByteLength {
790 len: 0,
791 expected: 2
792 })
793 );
794
795 assert_eq!(
796 <u16>::from_ssz_bytes(&[0, 1, 2]),
797 Err(DecodeError::InvalidByteLength {
798 len: 3,
799 expected: 2
800 })
801 );
802 }
803
804 #[test]
805 fn tuple() {
806 assert_eq!(<(u16, u16)>::from_ssz_bytes(&[0, 0, 0, 0]), Ok((0, 0)));
807 assert_eq!(<(u16, u16)>::from_ssz_bytes(&[16, 0, 17, 0]), Ok((16, 17)));
808 assert_eq!(<(u16, u16)>::from_ssz_bytes(&[0, 1, 2, 0]), Ok((256, 2)));
809 assert_eq!(
810 <(u16, u16)>::from_ssz_bytes(&[255, 255, 0, 0]),
811 Ok((65535, 0))
812 );
813 }
814
815 #[test]
816 fn vec_of_u128_roundtrip() {
817 let values = vec![
818 vec![0u128, 55u128, u128::MAX, u128::MAX - 3],
819 vec![],
820 vec![u128::MAX],
821 vec![u32::MAX as u128],
822 vec![0, 0, 0, 0],
823 vec![0, 0, 0, 0, 0, 0],
824 ];
825 for vec in values {
826 assert_eq!(
827 Vec::<u128>::from_ssz_bytes(&vec.as_ssz_bytes()).unwrap(),
828 vec
829 );
830 }
831 }
832}