1use super::*;
2use alloy_primitives::{Address, Bloom, Bytes, FixedBytes, U128, U256};
3use core::num::NonZeroUsize;
4use smallvec::SmallVec;
5use std::collections::{BTreeMap, BTreeSet};
6use std::sync::Arc;
7
8macro_rules! impl_encodable_for_uint {
9 ($type: ident, $bit_size: expr) => {
10 impl Encode for $type {
11 #[inline(always)]
12 fn is_ssz_fixed_len() -> bool {
13 true
14 }
15
16 #[inline(always)]
17 fn ssz_fixed_len() -> usize {
18 $bit_size / 8
19 }
20
21 #[inline(always)]
22 fn ssz_bytes_len(&self) -> usize {
23 $bit_size / 8
24 }
25
26 #[inline(always)]
27 fn ssz_append(&self, buf: &mut Vec<u8>) {
28 buf.extend_from_slice(&self.to_le_bytes());
29 }
30 }
31 };
32}
33
34impl_encodable_for_uint!(u8, 8);
35impl_encodable_for_uint!(u16, 16);
36impl_encodable_for_uint!(u32, 32);
37impl_encodable_for_uint!(u64, 64);
38impl_encodable_for_uint!(u128, 128);
39
40#[cfg(target_pointer_width = "32")]
41impl_encodable_for_uint!(usize, 32);
42
43#[cfg(target_pointer_width = "64")]
44impl_encodable_for_uint!(usize, 64);
45
46macro_rules! impl_encode_for_tuples {
48 ($(
49 $Tuple:ident {
50 $(($idx:tt) -> $T:ident)+
51 }
52 )+) => {
53 $(
54 impl<$($T: Encode),+> Encode for ($($T,)+) {
55 fn is_ssz_fixed_len() -> bool {
56 $(
57 <$T as Encode>::is_ssz_fixed_len() &&
58 )*
59 true
60 }
61
62 fn ssz_fixed_len() -> usize {
63 if <Self as Encode>::is_ssz_fixed_len() {
64 $(
65 <$T as Encode>::ssz_fixed_len() +
66 )*
67 0
68 } else {
69 BYTES_PER_LENGTH_OFFSET
70 }
71 }
72
73 fn ssz_bytes_len(&self) -> usize {
74 if <Self as Encode>::is_ssz_fixed_len() {
75 <Self as Encode>::ssz_fixed_len()
76 } else {
77 let mut len = 0;
78 $(
79 len += if <$T as Encode>::is_ssz_fixed_len() {
80 <$T as Encode>::ssz_fixed_len()
81 } else {
82 BYTES_PER_LENGTH_OFFSET +
83 self.$idx.ssz_bytes_len()
84 };
85 )*
86 len
87 }
88 }
89
90 fn ssz_append(&self, buf: &mut Vec<u8>) {
91 let offset = $(
92 <$T as Encode>::ssz_fixed_len() +
93 )*
94 0;
95
96 let mut encoder = SszEncoder::container(buf, offset);
97
98 $(
99 encoder.append(&self.$idx);
100 )*
101
102 encoder.finalize();
103 }
104 }
105 )+
106 }
107}
108
109impl_encode_for_tuples! {
110 Tuple2 {
111 (0) -> A
112 (1) -> B
113 }
114 Tuple3 {
115 (0) -> A
116 (1) -> B
117 (2) -> C
118 }
119 Tuple4 {
120 (0) -> A
121 (1) -> B
122 (2) -> C
123 (3) -> D
124 }
125 Tuple5 {
126 (0) -> A
127 (1) -> B
128 (2) -> C
129 (3) -> D
130 (4) -> E
131 }
132 Tuple6 {
133 (0) -> A
134 (1) -> B
135 (2) -> C
136 (3) -> D
137 (4) -> E
138 (5) -> F
139 }
140 Tuple7 {
141 (0) -> A
142 (1) -> B
143 (2) -> C
144 (3) -> D
145 (4) -> E
146 (5) -> F
147 (6) -> G
148 }
149 Tuple8 {
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 }
159 Tuple9 {
160 (0) -> A
161 (1) -> B
162 (2) -> C
163 (3) -> D
164 (4) -> E
165 (5) -> F
166 (6) -> G
167 (7) -> H
168 (8) -> I
169 }
170 Tuple10 {
171 (0) -> A
172 (1) -> B
173 (2) -> C
174 (3) -> D
175 (4) -> E
176 (5) -> F
177 (6) -> G
178 (7) -> H
179 (8) -> I
180 (9) -> J
181 }
182 Tuple11 {
183 (0) -> A
184 (1) -> B
185 (2) -> C
186 (3) -> D
187 (4) -> E
188 (5) -> F
189 (6) -> G
190 (7) -> H
191 (8) -> I
192 (9) -> J
193 (10) -> K
194 }
195 Tuple12 {
196 (0) -> A
197 (1) -> B
198 (2) -> C
199 (3) -> D
200 (4) -> E
201 (5) -> F
202 (6) -> G
203 (7) -> H
204 (8) -> I
205 (9) -> J
206 (10) -> K
207 (11) -> L
208 }
209}
210
211impl<T: Encode> Encode for Option<T> {
212 fn is_ssz_fixed_len() -> bool {
213 false
214 }
215 fn ssz_append(&self, buf: &mut Vec<u8>) {
216 match self {
217 Option::None => {
218 let union_selector: u8 = 0u8;
219 buf.push(union_selector);
220 }
221 Option::Some(ref inner) => {
222 let union_selector: u8 = 1u8;
223 buf.push(union_selector);
224 inner.ssz_append(buf);
225 }
226 }
227 }
228 fn ssz_bytes_len(&self) -> usize {
229 match self {
230 Option::None => 1usize,
231 Option::Some(ref inner) => inner
232 .ssz_bytes_len()
233 .checked_add(1)
234 .expect("encoded length must be less than usize::max_value"),
235 }
236 }
237}
238
239impl<T: Encode> Encode for Arc<T> {
240 fn is_ssz_fixed_len() -> bool {
241 T::is_ssz_fixed_len()
242 }
243
244 fn ssz_fixed_len() -> usize {
245 T::ssz_fixed_len()
246 }
247
248 fn ssz_append(&self, buf: &mut Vec<u8>) {
249 self.as_ref().ssz_append(buf)
250 }
251
252 fn ssz_bytes_len(&self) -> usize {
253 self.as_ref().ssz_bytes_len()
254 }
255}
256
257impl<T: Encode> Encode for &T {
259 fn is_ssz_fixed_len() -> bool {
260 T::is_ssz_fixed_len()
261 }
262
263 fn ssz_fixed_len() -> usize {
264 T::ssz_fixed_len()
265 }
266
267 fn ssz_append(&self, buf: &mut Vec<u8>) {
268 T::ssz_append(self, buf)
269 }
270
271 fn ssz_bytes_len(&self) -> usize {
272 T::ssz_bytes_len(self)
273 }
274}
275
276pub fn sequence_ssz_bytes_len<I, T>(iter: I) -> usize
278where
279 I: Iterator<Item = T> + ExactSizeIterator,
280 T: Encode,
281{
282 let length = iter.len();
284 if <T as Encode>::is_ssz_fixed_len() {
285 <T as Encode>::ssz_fixed_len() * length
286 } else {
287 let mut len = iter.map(|item| item.ssz_bytes_len()).sum();
288 len += BYTES_PER_LENGTH_OFFSET * length;
289 len
290 }
291}
292
293pub fn sequence_ssz_append<I, T>(iter: I, buf: &mut Vec<u8>)
295where
296 I: Iterator<Item = T> + ExactSizeIterator,
297 T: Encode,
298{
299 if T::is_ssz_fixed_len() {
300 buf.reserve(T::ssz_fixed_len() * iter.len());
301
302 for item in iter {
303 item.ssz_append(buf);
304 }
305 } else {
306 let mut encoder = SszEncoder::container(buf, iter.len() * BYTES_PER_LENGTH_OFFSET);
307
308 for item in iter {
309 encoder.append(&item);
310 }
311
312 encoder.finalize();
313 }
314}
315
316impl<T: Encode> Encode for Vec<T> {
317 fn is_ssz_fixed_len() -> bool {
318 false
319 }
320
321 fn ssz_bytes_len(&self) -> usize {
322 sequence_ssz_bytes_len(self.iter())
323 }
324
325 fn ssz_append(&self, buf: &mut Vec<u8>) {
326 sequence_ssz_append(self.iter(), buf)
327 }
328}
329
330impl<T: Encode, const N: usize> Encode for SmallVec<[T; N]> {
331 fn is_ssz_fixed_len() -> bool {
332 false
333 }
334
335 fn ssz_bytes_len(&self) -> usize {
336 sequence_ssz_bytes_len(self.iter())
337 }
338
339 fn ssz_append(&self, buf: &mut Vec<u8>) {
340 sequence_ssz_append(self.iter(), buf)
341 }
342}
343
344impl<K, V> Encode for BTreeMap<K, V>
345where
346 K: Encode + Ord,
347 V: Encode,
348{
349 fn is_ssz_fixed_len() -> bool {
350 false
351 }
352
353 fn ssz_bytes_len(&self) -> usize {
354 sequence_ssz_bytes_len(self.iter())
355 }
356
357 fn ssz_append(&self, buf: &mut Vec<u8>) {
358 sequence_ssz_append(self.iter(), buf)
359 }
360}
361
362impl<T> Encode for BTreeSet<T>
363where
364 T: Encode + Ord,
365{
366 fn is_ssz_fixed_len() -> bool {
367 false
368 }
369
370 fn ssz_bytes_len(&self) -> usize {
371 sequence_ssz_bytes_len(self.iter())
372 }
373
374 fn ssz_append(&self, buf: &mut Vec<u8>) {
375 sequence_ssz_append(self.iter(), buf)
376 }
377}
378
379impl Encode for bool {
380 fn is_ssz_fixed_len() -> bool {
381 true
382 }
383
384 fn ssz_fixed_len() -> usize {
385 1
386 }
387
388 fn ssz_bytes_len(&self) -> usize {
389 1
390 }
391
392 fn ssz_append(&self, buf: &mut Vec<u8>) {
393 buf.extend_from_slice(&(*self as u8).to_le_bytes());
394 }
395}
396
397impl Encode for NonZeroUsize {
398 fn is_ssz_fixed_len() -> bool {
399 <usize as Encode>::is_ssz_fixed_len()
400 }
401
402 fn ssz_fixed_len() -> usize {
403 <usize as Encode>::ssz_fixed_len()
404 }
405
406 fn ssz_bytes_len(&self) -> usize {
407 std::mem::size_of::<usize>()
408 }
409
410 fn ssz_append(&self, buf: &mut Vec<u8>) {
411 self.get().ssz_append(buf)
412 }
413}
414
415impl Encode for Address {
416 fn is_ssz_fixed_len() -> bool {
417 true
418 }
419
420 fn ssz_fixed_len() -> usize {
421 20
422 }
423
424 fn ssz_bytes_len(&self) -> usize {
425 20
426 }
427
428 fn ssz_append(&self, buf: &mut Vec<u8>) {
429 buf.extend_from_slice(self.as_slice());
430 }
431}
432
433impl<const N: usize> Encode for FixedBytes<N> {
434 #[inline]
435 fn is_ssz_fixed_len() -> bool {
436 true
437 }
438
439 #[inline]
440 fn ssz_bytes_len(&self) -> usize {
441 N
442 }
443
444 #[inline]
445 fn ssz_fixed_len() -> usize {
446 N
447 }
448
449 #[inline]
450 fn ssz_append(&self, buf: &mut Vec<u8>) {
451 buf.extend_from_slice(&self.0);
452 }
453
454 #[inline]
455 fn as_ssz_bytes(&self) -> Vec<u8> {
456 self.0.to_vec()
457 }
458}
459
460impl Encode for Bloom {
461 #[inline]
462 fn is_ssz_fixed_len() -> bool {
463 true
464 }
465
466 #[inline]
467 fn ssz_bytes_len(&self) -> usize {
468 256
469 }
470
471 #[inline]
472 fn ssz_fixed_len() -> usize {
473 256
474 }
475
476 #[inline]
477 fn ssz_append(&self, buf: &mut Vec<u8>) {
478 buf.extend_from_slice(&self.0 .0);
479 }
480
481 #[inline]
482 fn as_ssz_bytes(&self) -> Vec<u8> {
483 self.0.to_vec()
484 }
485}
486
487impl Encode for Bytes {
488 #[inline]
489 fn is_ssz_fixed_len() -> bool {
490 false
491 }
492
493 #[inline]
494 fn ssz_bytes_len(&self) -> usize {
495 self.0.len()
496 }
497
498 #[inline]
499 fn ssz_append(&self, buf: &mut Vec<u8>) {
500 buf.extend_from_slice(&self.0);
501 }
502
503 #[inline]
504 fn as_ssz_bytes(&self) -> Vec<u8> {
505 self.0.to_vec()
506 }
507}
508
509impl Encode for U256 {
510 fn is_ssz_fixed_len() -> bool {
511 true
512 }
513
514 fn ssz_fixed_len() -> usize {
515 32
516 }
517
518 fn ssz_bytes_len(&self) -> usize {
519 32
520 }
521
522 fn ssz_append(&self, buf: &mut Vec<u8>) {
523 buf.extend_from_slice(self.as_le_slice());
524 }
525}
526
527impl Encode for U128 {
528 fn is_ssz_fixed_len() -> bool {
529 true
530 }
531
532 fn ssz_fixed_len() -> usize {
533 16
534 }
535
536 fn ssz_bytes_len(&self) -> usize {
537 16
538 }
539
540 fn ssz_append(&self, buf: &mut Vec<u8>) {
541 buf.extend_from_slice(self.as_le_slice());
542 }
543}
544
545impl<const N: usize> Encode for [u8; N] {
546 fn is_ssz_fixed_len() -> bool {
547 true
548 }
549
550 fn ssz_fixed_len() -> usize {
551 N
552 }
553
554 fn ssz_bytes_len(&self) -> usize {
555 N
556 }
557
558 fn ssz_append(&self, buf: &mut Vec<u8>) {
559 buf.extend_from_slice(&self[..]);
560 }
561}
562
563#[cfg(test)]
564mod tests {
565 use super::*;
566 use alloy_primitives::B256;
567
568 #[test]
569 fn vec_of_u8() {
570 let vec: Vec<u8> = vec![];
571 assert_eq!(vec.as_ssz_bytes(), Vec::<u8>::new());
572
573 let vec: Vec<u8> = vec![1];
574 assert_eq!(vec.as_ssz_bytes(), vec![1]);
575
576 let vec: Vec<u8> = vec![0, 1, 2, 3];
577 assert_eq!(vec.as_ssz_bytes(), vec![0, 1, 2, 3]);
578 }
579
580 #[test]
581 fn vec_of_vec_of_u8() {
582 let vec: Vec<Vec<u8>> = vec![];
583 assert_eq!(vec.as_ssz_bytes(), Vec::<u8>::new());
584
585 let vec: Vec<Vec<u8>> = vec![vec![]];
586 assert_eq!(vec.as_ssz_bytes(), vec![4, 0, 0, 0]);
587
588 let vec: Vec<Vec<u8>> = vec![vec![], vec![]];
589 assert_eq!(vec.as_ssz_bytes(), vec![8, 0, 0, 0, 8, 0, 0, 0]);
590
591 let vec: Vec<Vec<u8>> = vec![vec![0, 1, 2], vec![11, 22, 33]];
592 assert_eq!(
593 vec.as_ssz_bytes(),
594 vec![8, 0, 0, 0, 11, 0, 0, 0, 0, 1, 2, 11, 22, 33]
595 );
596 }
597
598 #[test]
599 fn ssz_encode_u8() {
600 assert_eq!(0_u8.as_ssz_bytes(), vec![0]);
601 assert_eq!(1_u8.as_ssz_bytes(), vec![1]);
602 assert_eq!(100_u8.as_ssz_bytes(), vec![100]);
603 assert_eq!(255_u8.as_ssz_bytes(), vec![255]);
604 }
605
606 #[test]
607 fn ssz_encode_u16() {
608 assert_eq!(1_u16.as_ssz_bytes(), vec![1, 0]);
609 assert_eq!(100_u16.as_ssz_bytes(), vec![100, 0]);
610 assert_eq!((1_u16 << 8).as_ssz_bytes(), vec![0, 1]);
611 assert_eq!(65535_u16.as_ssz_bytes(), vec![255, 255]);
612 }
613
614 #[test]
615 fn ssz_encode_u32() {
616 assert_eq!(1_u32.as_ssz_bytes(), vec![1, 0, 0, 0]);
617 assert_eq!(100_u32.as_ssz_bytes(), vec![100, 0, 0, 0]);
618 assert_eq!((1_u32 << 16).as_ssz_bytes(), vec![0, 0, 1, 0]);
619 assert_eq!((1_u32 << 24).as_ssz_bytes(), vec![0, 0, 0, 1]);
620 assert_eq!((!0_u32).as_ssz_bytes(), vec![255, 255, 255, 255]);
621 }
622
623 #[test]
624 fn ssz_encode_u64() {
625 assert_eq!(1_u64.as_ssz_bytes(), vec![1, 0, 0, 0, 0, 0, 0, 0]);
626 assert_eq!(
627 (!0_u64).as_ssz_bytes(),
628 vec![255, 255, 255, 255, 255, 255, 255, 255]
629 );
630 }
631
632 #[test]
633 fn ssz_encode_u128() {
634 assert_eq!(
635 1_u128.as_ssz_bytes(),
636 vec![1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
637 );
638 assert_eq!(
639 (!0_u128).as_ssz_bytes(),
640 vec![255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]
641 );
642 }
643
644 #[test]
645 fn ssz_encode_usize() {
646 assert_eq!(1_usize.as_ssz_bytes(), vec![1, 0, 0, 0, 0, 0, 0, 0]);
647 assert_eq!(
648 (!0_usize).as_ssz_bytes(),
649 vec![255, 255, 255, 255, 255, 255, 255, 255]
650 );
651 }
652
653 #[test]
654 fn ssz_encode_option_u8() {
655 let opt: Option<u8> = None;
656 assert_eq!(opt.as_ssz_bytes(), vec![0]);
657 let opt: Option<u8> = Some(2);
658 assert_eq!(opt.as_ssz_bytes(), vec![1, 2]);
659 }
660
661 #[test]
662 fn ssz_encode_bool() {
663 assert_eq!(true.as_ssz_bytes(), vec![1]);
664 assert_eq!(false.as_ssz_bytes(), vec![0]);
665 }
666
667 #[test]
668 fn ssz_encode_b256() {
669 assert_eq!(B256::from(&[0; 32]).as_ssz_bytes(), vec![0; 32]);
670 assert_eq!(B256::from(&[1; 32]).as_ssz_bytes(), vec![1; 32]);
671
672 let bytes = vec![
673 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
674 0, 0, 0,
675 ];
676
677 assert_eq!(B256::from_slice(&bytes).as_ssz_bytes(), bytes);
678 }
679
680 #[test]
681 fn ssz_encode_u8_array_4() {
682 assert_eq!([0, 0, 0, 0].as_ssz_bytes(), vec![0; 4]);
683 assert_eq!([1, 0, 0, 0].as_ssz_bytes(), vec![1, 0, 0, 0]);
684 assert_eq!([1, 2, 3, 4].as_ssz_bytes(), vec![1, 2, 3, 4]);
685 }
686
687 #[test]
688 fn tuple() {
689 assert_eq!((10u8, 11u8).as_ssz_bytes(), vec![10, 11]);
690 assert_eq!((10u32, 11u8).as_ssz_bytes(), vec![10, 0, 0, 0, 11]);
691 assert_eq!((10u8, 11u8, 12u8).as_ssz_bytes(), vec![10, 11, 12]);
692 }
693}