Skip to main content

fastrlp/
decode.rs

1use crate::types::Header;
2use arrayvec::ArrayVec;
3use bytes::{Buf, Bytes, BytesMut};
4use core::{any::Any, num::NonZeroUsize};
5
6pub trait Decodable: Sized {
7    fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError>;
8}
9
10#[cfg(feature = "alloc")]
11mod alloc_impl {
12    use super::*;
13
14    impl<T> Decodable for ::alloc::boxed::Box<T>
15    where
16        T: Decodable + Sized,
17    {
18        fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
19            T::decode(buf).map(::alloc::boxed::Box::new)
20        }
21    }
22
23    impl<T> Decodable for ::alloc::sync::Arc<T>
24    where
25        T: Decodable + Sized,
26    {
27        fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
28            T::decode(buf).map(::alloc::sync::Arc::new)
29        }
30    }
31
32    impl Decodable for ::alloc::string::String {
33        fn decode(from: &mut &[u8]) -> Result<Self, DecodeError> {
34            let h = Header::decode(from)?;
35            if h.list {
36                return Err(DecodeError::UnexpectedList);
37            }
38            let mut to = ::alloc::vec::Vec::with_capacity(h.payload_length);
39            to.extend_from_slice(&from[..h.payload_length]);
40            from.advance(h.payload_length);
41
42            Self::from_utf8(to).map_err(|_| DecodeError::Custom("invalid string"))
43        }
44    }
45
46    impl<T> Decodable for ::alloc::vec::Vec<T>
47    where
48        T: Decodable + 'static,
49    {
50        fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
51            let h = Header::decode(buf)?;
52
53            let mut to = ::alloc::vec::Vec::new();
54            if let Some(to) = <dyn Any>::downcast_mut::<::alloc::vec::Vec<u8>>(&mut to) {
55                if h.list {
56                    return Err(DecodeError::UnexpectedList);
57                }
58                to.extend_from_slice(&buf[..h.payload_length]);
59                buf.advance(h.payload_length);
60            } else {
61                if !h.list {
62                    return Err(DecodeError::UnexpectedString);
63                }
64
65                let payload_view = &mut &buf[..h.payload_length];
66
67                while !payload_view.is_empty() {
68                    to.push(T::decode(payload_view)?);
69                }
70
71                buf.advance(h.payload_length);
72            }
73
74            Ok(to)
75        }
76    }
77}
78
79#[derive(Clone, Copy, Debug, PartialEq, Eq)]
80pub enum DecodeError {
81    Overflow,
82    LeadingZero,
83    InputTooShort { needed: Option<NonZeroUsize> },
84    NonCanonicalSingleByte,
85    NonCanonicalSize,
86    UnexpectedLength,
87    UnexpectedString,
88    UnexpectedList,
89    ListLengthMismatch { expected: usize, got: usize },
90    Custom(&'static str),
91}
92
93#[cfg(feature = "std")]
94impl std::error::Error for DecodeError {}
95
96impl core::fmt::Display for DecodeError {
97    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
98        match self {
99            DecodeError::Overflow => write!(f, "overflow"),
100            DecodeError::LeadingZero => write!(f, "leading zero"),
101            DecodeError::InputTooShort { needed } => {
102                write!(f, "input too short")?;
103                if let Some(needed) = needed {
104                    write!(f, ": need {needed} more bytes")?;
105                }
106
107                Ok(())
108            }
109            DecodeError::NonCanonicalSingleByte => write!(f, "non-canonical single byte"),
110            DecodeError::NonCanonicalSize => write!(f, "non-canonical size"),
111            DecodeError::UnexpectedLength => write!(f, "unexpected length"),
112            DecodeError::UnexpectedString => write!(f, "unexpected string"),
113            DecodeError::UnexpectedList => write!(f, "unexpected list"),
114            DecodeError::ListLengthMismatch { expected, got } => {
115                write!(f, "list length mismatch: expected {expected}, got {got}")
116            }
117            DecodeError::Custom(err) => write!(f, "{err}"),
118        }
119    }
120}
121
122impl Header {
123    pub fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
124        if !buf.has_remaining() {
125            return Err(DecodeError::InputTooShort { needed: None });
126        }
127
128        let b = buf[0];
129        let h: Self = {
130            if b < 0x80 {
131                Self {
132                    list: false,
133                    payload_length: 1,
134                }
135            } else if b < 0xB8 {
136                buf.advance(1);
137                let h = Self {
138                    list: false,
139                    payload_length: b as usize - 0x80,
140                };
141
142                if h.payload_length == 1 {
143                    if !buf.has_remaining() {
144                        return Err(DecodeError::InputTooShort { needed: None });
145                    }
146                    if buf[0] < 0x80 {
147                        return Err(DecodeError::NonCanonicalSingleByte);
148                    }
149                }
150
151                h
152            } else if b < 0xC0 {
153                buf.advance(1);
154                let len_of_len = b as usize - 0xB7;
155                if let Some(needed) = len_of_len
156                    .checked_sub(buf.len())
157                    .and_then(NonZeroUsize::new)
158                {
159                    return Err(DecodeError::InputTooShort {
160                        needed: Some(needed),
161                    });
162                }
163                let payload_length = usize::try_from(u64::from_be_bytes(
164                    static_left_pad(&buf[..len_of_len]).ok_or(DecodeError::LeadingZero)?,
165                ))
166                .map_err(|_| DecodeError::Custom("Input too big"))?;
167                buf.advance(len_of_len);
168                if payload_length < 56 {
169                    return Err(DecodeError::NonCanonicalSize);
170                }
171
172                Self {
173                    list: false,
174                    payload_length,
175                }
176            } else if b < 0xF8 {
177                buf.advance(1);
178                Self {
179                    list: true,
180                    payload_length: b as usize - 0xC0,
181                }
182            } else {
183                buf.advance(1);
184                let list = true;
185                let len_of_len = b as usize - 0xF7;
186                if let Some(needed) = len_of_len
187                    .checked_sub(buf.len())
188                    .and_then(NonZeroUsize::new)
189                {
190                    return Err(DecodeError::InputTooShort {
191                        needed: Some(needed),
192                    });
193                }
194                let payload_length = usize::try_from(u64::from_be_bytes(
195                    static_left_pad(&buf[..len_of_len]).ok_or(DecodeError::LeadingZero)?,
196                ))
197                .map_err(|_| DecodeError::Custom("Input too big"))?;
198                buf.advance(len_of_len);
199                if payload_length < 56 {
200                    return Err(DecodeError::NonCanonicalSize);
201                }
202
203                Self {
204                    list,
205                    payload_length,
206                }
207            }
208        };
209
210        if let Some(needed) = h
211            .payload_length
212            .checked_sub(buf.remaining())
213            .and_then(NonZeroUsize::new)
214        {
215            return Err(DecodeError::InputTooShort {
216                needed: Some(needed),
217            });
218        }
219
220        Ok(h)
221    }
222}
223
224fn static_left_pad<const LEN: usize>(data: &[u8]) -> Option<[u8; LEN]> {
225    if data.len() > LEN {
226        return None;
227    }
228
229    let mut v = [0; LEN];
230
231    if data.is_empty() {
232        return Some(v);
233    }
234
235    if data[0] == 0 {
236        return None;
237    }
238
239    v[LEN - data.len()..].copy_from_slice(data);
240    Some(v)
241}
242
243macro_rules! decode_integer {
244    ($t:ty) => {
245        impl Decodable for $t {
246            fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
247                let h = Header::decode(buf)?;
248                if h.list {
249                    return Err(DecodeError::UnexpectedList);
250                }
251                if h.payload_length > (<$t>::BITS as usize / 8) {
252                    return Err(DecodeError::Overflow);
253                }
254                if let Some(needed) = h
255                    .payload_length
256                    .checked_sub(buf.remaining())
257                    .and_then(NonZeroUsize::new)
258                {
259                    return Err(DecodeError::InputTooShort {
260                        needed: Some(needed),
261                    });
262                }
263                let v = <$t>::from_be_bytes(
264                    static_left_pad(&buf[..h.payload_length]).ok_or(DecodeError::LeadingZero)?,
265                );
266                buf.advance(h.payload_length);
267                Ok(v)
268            }
269        }
270    };
271}
272
273decode_integer!(usize);
274decode_integer!(u8);
275decode_integer!(u16);
276decode_integer!(u32);
277decode_integer!(u64);
278decode_integer!(u128);
279
280impl Decodable for bool {
281    fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
282        Ok(match u8::decode(buf)? {
283            0 => false,
284            1 => true,
285            _ => return Err(DecodeError::Custom("invalid bool value, must be 0 or 1")),
286        })
287    }
288}
289
290#[cfg(feature = "ethnum")]
291decode_integer!(ethnum::U256);
292
293#[cfg(feature = "ethereum-types")]
294mod ethereum_types_support {
295    use super::*;
296    use ethereum_types::*;
297
298    macro_rules! fixed_hash_impl {
299        ($t:ty) => {
300            impl Decodable for $t {
301                fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
302                    Decodable::decode(buf).map(Self)
303                }
304            }
305        };
306    }
307
308    fixed_hash_impl!(H64);
309    fixed_hash_impl!(H128);
310    fixed_hash_impl!(H160);
311    fixed_hash_impl!(H256);
312    fixed_hash_impl!(H512);
313    fixed_hash_impl!(H520);
314    #[cfg(feature = "ethbloom")]
315    fixed_hash_impl!(Bloom);
316
317    macro_rules! fixed_uint_impl {
318        ($t:ty, $n_bytes:tt) => {
319            impl Decodable for $t {
320                fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
321                    let h = Header::decode(buf)?;
322                    if h.list {
323                        return Err(DecodeError::UnexpectedList);
324                    }
325                    if h.payload_length > $n_bytes {
326                        return Err(DecodeError::Overflow);
327                    }
328                    if let Some(needed) = h
329                        .payload_length
330                        .checked_sub(buf.remaining())
331                        .and_then(NonZeroUsize::new)
332                    {
333                        return Err(DecodeError::InputTooShort {
334                            needed: Some(needed),
335                        });
336                    }
337                    let n = <$t>::from_big_endian(
338                        &static_left_pad::<$n_bytes>(&buf[..h.payload_length])
339                            .ok_or(DecodeError::LeadingZero)?,
340                    );
341                    buf.advance(h.payload_length);
342                    Ok(n)
343                }
344            }
345        };
346    }
347
348    fixed_uint_impl!(U64, 8);
349    fixed_uint_impl!(U128, 16);
350    fixed_uint_impl!(U256, 32);
351    fixed_uint_impl!(U512, 64);
352}
353
354impl<T, const LEN: usize> Decodable for [T; LEN]
355where
356    T: Decodable + 'static,
357{
358    fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
359        ArrayVec::<T, LEN>::decode(buf)?
360            .into_inner()
361            .map_err(|arr| DecodeError::ListLengthMismatch {
362                expected: LEN,
363                got: arr.len(),
364            })
365    }
366}
367
368impl Decodable for BytesMut {
369    fn decode(from: &mut &[u8]) -> Result<Self, DecodeError> {
370        let h = Header::decode(from)?;
371        if h.list {
372            return Err(DecodeError::UnexpectedList);
373        }
374        let mut to = BytesMut::with_capacity(h.payload_length);
375        to.extend_from_slice(&from[..h.payload_length]);
376        from.advance(h.payload_length);
377
378        Ok(to)
379    }
380}
381
382impl Decodable for Bytes {
383    fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
384        BytesMut::decode(buf).map(BytesMut::freeze)
385    }
386}
387
388pub struct Rlp<'a> {
389    payload_view: &'a [u8],
390}
391
392impl<'a> Rlp<'a> {
393    pub fn new(mut payload: &'a [u8]) -> Result<Self, DecodeError> {
394        let h = Header::decode(&mut payload)?;
395        if !h.list {
396            return Err(DecodeError::UnexpectedString);
397        }
398
399        let payload_view = &payload[..h.payload_length];
400        Ok(Self { payload_view })
401    }
402
403    pub fn get_next<T: Decodable>(&mut self) -> Result<Option<T>, DecodeError> {
404        if self.payload_view.is_empty() {
405            return Ok(None);
406        }
407
408        Ok(Some(T::decode(&mut self.payload_view)?))
409    }
410}
411
412impl<T, const LEN: usize> Decodable for ArrayVec<T, LEN>
413where
414    T: Decodable + 'static,
415{
416    fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
417        let mut arr: ArrayVec<T, LEN> = ArrayVec::new();
418        if let Some(s) = <dyn Any>::downcast_mut::<ArrayVec<u8, LEN>>(&mut arr) {
419            let h = Header::decode(buf)?;
420            if h.list {
421                return Err(DecodeError::UnexpectedList);
422            }
423            if h.payload_length != LEN {
424                return Err(DecodeError::UnexpectedLength);
425            }
426
427            s.try_extend_from_slice(&buf[..LEN]).unwrap();
428            buf.advance(LEN);
429        } else {
430            let h = Header::decode(buf)?;
431            if !h.list {
432                return Err(DecodeError::UnexpectedString);
433            }
434
435            let payload_view = &mut &buf[..h.payload_length];
436
437            while !payload_view.is_empty() {
438                if arr.try_push(T::decode(payload_view)?).is_err() {
439                    return Err(DecodeError::ListLengthMismatch {
440                        expected: LEN,
441                        got: LEN + 1,
442                    });
443                }
444            }
445
446            buf.advance(h.payload_length);
447        }
448
449        Ok(arr)
450    }
451}
452
453#[cfg(test)]
454mod tests {
455    extern crate alloc;
456
457    use super::*;
458    use alloc::vec;
459    use core::fmt::Debug;
460    use ethereum_types::{U64, U128, U256, U512};
461    use ethnum::AsU256;
462    use hex_literal::hex;
463
464    fn check_decode<T, IT>(fixtures: IT)
465    where
466        T: Decodable + PartialEq + Debug,
467        IT: IntoIterator<Item = (Result<T, DecodeError>, &'static [u8])>,
468    {
469        for (expected, mut input) in fixtures {
470            assert_eq!(T::decode(&mut input), expected);
471            if expected.is_ok() {
472                assert_eq!(input, &[]);
473            }
474        }
475    }
476
477    fn check_decode_list<T, IT>(fixtures: IT)
478    where
479        T: Decodable + PartialEq + Debug + 'static,
480        IT: IntoIterator<Item = (Result<alloc::vec::Vec<T>, DecodeError>, &'static [u8])>,
481    {
482        for (expected, mut input) in fixtures {
483            assert_eq!(vec::Vec::<T>::decode(&mut input), expected);
484            if expected.is_ok() {
485                assert_eq!(input, &[]);
486            }
487        }
488    }
489
490    #[test]
491    fn rlp_strings() {
492        check_decode::<Bytes, _>(vec![
493            (Ok((hex!("00")[..]).to_vec().into()), &hex!("00")[..]),
494            (
495                Ok((hex!("6f62636465666768696a6b6c6d")[..]).to_vec().into()),
496                &hex!("8D6F62636465666768696A6B6C6D")[..],
497            ),
498            (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
499        ])
500    }
501
502    #[test]
503    fn rlp_fixed_length() {
504        check_decode(vec![
505            (
506                Ok(hex!("6f62636465666768696a6b6c6d")),
507                &hex!("8D6F62636465666768696A6B6C6D")[..],
508            ),
509            (
510                Err(DecodeError::UnexpectedLength),
511                &hex!("8C6F62636465666768696A6B6C")[..],
512            ),
513            (
514                Err(DecodeError::UnexpectedLength),
515                &hex!("8E6F62636465666768696A6B6C6D6E")[..],
516            ),
517        ])
518    }
519
520    #[test]
521    fn rlp_u64() {
522        check_decode(vec![
523            (Ok(9_u64), &hex!("09")[..]),
524            (Ok(0_u64), &hex!("80")[..]),
525            (Ok(0x0505_u64), &hex!("820505")[..]),
526            (Ok(0xCE05050505_u64), &hex!("85CE05050505")[..]),
527            (
528                Err(DecodeError::Overflow),
529                &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..],
530            ),
531            (
532                Err(DecodeError::InputTooShort {
533                    needed: Some(NonZeroUsize::new(1).unwrap()),
534                }),
535                &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..],
536            ),
537            (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
538            (Err(DecodeError::LeadingZero), &hex!("00")[..]),
539            (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]),
540            (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]),
541            (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]),
542            (
543                Err(DecodeError::Overflow),
544                &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
545            ),
546        ])
547    }
548
549    #[test]
550    fn rlp_u256() {
551        check_decode(vec![
552            (Ok(9_u8.as_u256()), &hex!("09")[..]),
553            (Ok(0_u8.as_u256()), &hex!("80")[..]),
554            (Ok(0x0505_u16.as_u256()), &hex!("820505")[..]),
555            (Ok(0xCE05050505_u64.as_u256()), &hex!("85CE05050505")[..]),
556            (
557                Ok(0xFFFFFFFFFFFFFFFFFF7C_u128.as_u256()),
558                &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..],
559            ),
560            (
561                Err(DecodeError::InputTooShort {
562                    needed: Some(NonZeroUsize::new(1).unwrap()),
563                }),
564                &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..],
565            ),
566            (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
567            (Err(DecodeError::LeadingZero), &hex!("00")[..]),
568            (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]),
569            (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]),
570            (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]),
571            (
572                Err(DecodeError::Overflow),
573                &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
574            ),
575        ])
576    }
577
578    #[cfg(feature = "ethereum-types")]
579    #[test]
580    fn rlp_ethereum_types_u64() {
581        check_decode(vec![
582            (Ok(U64::from(9_u8)), &hex!("09")[..]),
583            (Ok(U64::from(0_u8)), &hex!("80")[..]),
584            (Ok(U64::from(0x0505_u16)), &hex!("820505")[..]),
585            (Ok(U64::from(0xCE05050505_u64)), &hex!("85CE05050505")[..]),
586            (
587                Err(DecodeError::Overflow),
588                &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..],
589            ),
590            (
591                Err(DecodeError::InputTooShort {
592                    needed: Some(NonZeroUsize::new(1).unwrap()),
593                }),
594                &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..],
595            ),
596            (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
597            (Err(DecodeError::LeadingZero), &hex!("00")[..]),
598            (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]),
599            (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]),
600            (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]),
601            (
602                Err(DecodeError::Overflow),
603                &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
604            ),
605        ])
606    }
607
608    #[cfg(feature = "ethereum-types")]
609    #[test]
610    fn rlp_ethereum_types_u128() {
611        check_decode(vec![
612            (Ok(U128::from(9_u8)), &hex!("09")[..]),
613            (Ok(U128::from(0_u8)), &hex!("80")[..]),
614            (Ok(U128::from(0x0505_u16)), &hex!("820505")[..]),
615            (Ok(U128::from(0xCE05050505_u64)), &hex!("85CE05050505")[..]),
616            (
617                Ok(U128::from(0xFFFFFFFFFFFFFFFFFF7C_u128)),
618                &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..],
619            ),
620            (
621                Err(DecodeError::InputTooShort {
622                    needed: Some(NonZeroUsize::new(1).unwrap()),
623                }),
624                &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..],
625            ),
626            (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
627            (Err(DecodeError::LeadingZero), &hex!("00")[..]),
628            (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]),
629            (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]),
630            (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]),
631            (
632                Err(DecodeError::Overflow),
633                &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
634            ),
635        ])
636    }
637
638    #[cfg(feature = "ethereum-types")]
639    #[test]
640    fn rlp_ethereum_types_u256() {
641        check_decode(vec![
642            (Ok(U256::from(9_u8)), &hex!("09")[..]),
643            (Ok(U256::from(0_u8)), &hex!("80")[..]),
644            (Ok(U256::from(0x0505_u16)), &hex!("820505")[..]),
645            (Ok(U256::from(0xCE05050505_u64)), &hex!("85CE05050505")[..]),
646            (
647                Ok(U256::from(0xFFFFFFFFFFFFFFFFFF7C_u128)),
648                &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..],
649            ),
650            (
651                Err(DecodeError::InputTooShort {
652                    needed: Some(NonZeroUsize::new(1).unwrap()),
653                }),
654                &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..],
655            ),
656            (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
657            (Err(DecodeError::LeadingZero), &hex!("00")[..]),
658            (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]),
659            (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]),
660            (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]),
661            (
662                Err(DecodeError::Overflow),
663                &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
664            ),
665        ])
666    }
667
668    #[cfg(feature = "ethereum-types")]
669    #[test]
670    fn rlp_ethereum_types_u512() {
671        check_decode(vec![
672            (Ok(U512::from(9_u8)), &hex!("09")[..]),
673            (Ok(U512::from(0_u8)), &hex!("80")[..]),
674            (Ok(U512::from(0x0505_u16)), &hex!("820505")[..]),
675            (Ok(U512::from(0xCE05050505_u64)), &hex!("85CE05050505")[..]),
676            (
677                Ok(U512::from(0xFFFFFFFFFFFFFFFFFF7C_u128)),
678                &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..],
679            ),
680            (
681                Err(DecodeError::InputTooShort{
682                    needed: Some(NonZeroUsize::new(1).unwrap()),
683                }),
684                &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..],
685            ),
686            (Err(DecodeError::UnexpectedList), &hex!("C0")[..]),
687            (Err(DecodeError::LeadingZero), &hex!("00")[..]),
688            (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]),
689            (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]),
690            (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]),
691            (
692                Ok(U512::from_dec_str("115792089237316195423570985008687907853269984676653278628940326933415738736640").unwrap()),
693                &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..],
694            ),
695            (
696                Err(DecodeError::Overflow),
697                &hex!("B84101000000000000000000000000000000000000008B000000000000000000000000000000000000000000000000000000000000008B000000000000000000000000")[..],
698            ),
699        ])
700    }
701
702    #[test]
703    fn rlp_vectors() {
704        check_decode_list(vec![
705            (Ok(vec![]), &hex!("C0")[..]),
706            (
707                Ok(vec![0xBBCCB5_u64, 0xFFC0B5_u64]),
708                &hex!("C883BBCCB583FFC0B5")[..],
709            ),
710        ])
711    }
712
713    #[test]
714    fn vec_specialization() {
715        const SPECIALIZED: [u8; 2] = [0x42_u8, 0x43_u8];
716        const GENERAL: [u64; 2] = [0xFFCCB5_u64, 0xFFC0B5_u64];
717
718        const SPECIALIZED_EXP: &[u8] = &hex!("824243");
719        const GENERAL_EXP: &[u8] = &hex!("C883FFCCB583FFC0B5");
720
721        check_decode([(Ok(SPECIALIZED), SPECIALIZED_EXP)]);
722        check_decode([(Ok(GENERAL), GENERAL_EXP)]);
723
724        check_decode([(Ok(ArrayVec::from(SPECIALIZED)), SPECIALIZED_EXP)]);
725        check_decode([(Ok(ArrayVec::from(GENERAL)), GENERAL_EXP)]);
726
727        #[cfg(feature = "alloc")]
728        {
729            check_decode([(Ok(SPECIALIZED.to_vec()), SPECIALIZED_EXP)]);
730            check_decode([(Ok(GENERAL.to_vec()), GENERAL_EXP)]);
731        }
732    }
733}