diff --git a/ssz/src/decode.rs b/ssz/src/decode.rs index ae7a78c838..a44c92b0f1 100644 --- a/ssz/src/decode.rs +++ b/ssz/src/decode.rs @@ -2,7 +2,7 @@ use super::{ LENGTH_BYTES, }; -#[derive(Debug)] +#[derive(Debug,PartialEq)] pub enum DecodeError { OutOfBounds, TooShort, @@ -120,16 +120,4 @@ mod tests { let result = nth_value(&ssz, 0).unwrap(); assert_eq!(result, vec![42; 511].as_slice()); } - - /* - #[test] - fn test_ssz_decode_u16() { - let x: u16 = 100; - let mut s = SszStream::new(); - s.append(&x); - let y: u16 = u16::ssz_decode(s.nth_value(0).unwrap()) - .unwrap(); - assert_eq!(x, y); - } - */ } diff --git a/ssz/src/impls.rs b/ssz/src/impls.rs index d61ccdda9c..0409fe5e5f 100644 --- a/ssz/src/impls.rs +++ b/ssz/src/impls.rs @@ -16,17 +16,17 @@ macro_rules! impl_decodable_for_uint { fn ssz_decode(bytes: &[u8]) -> Result { - assert!(0 < $bit_size && - $bit_size <= 64 && - $bit_size % 8 == 0); - let bytes_required = $bit_size / 8; - if bytes_required <= bytes.len() { - let mut result = 0; + assert!((0 < $bit_size) & + ($bit_size <= 64) & + ($bit_size % 8 == 0)); + let max_bytes = $bit_size / 8; + if bytes.len() <= max_bytes { + let mut result: $type = 0; for i in 0..bytes.len() { let offset = (bytes.len() - i - 1) * 8; - result = (bytes[i] << offset) | result; + result = ((bytes[i] as $type) << offset) | result; }; - Ok(result.into()) + Ok(result) } else { Err(DecodeError::TooLong) } @@ -35,8 +35,10 @@ macro_rules! impl_decodable_for_uint { } } -impl_decodable_for_uint!(u64, 64 / 8); -impl_decodable_for_uint!(u16, 16 / 8); +impl_decodable_for_uint!(u16, 16); +impl_decodable_for_uint!(u32, 32); +impl_decodable_for_uint!(u64, 64); +impl_decodable_for_uint!(usize, 64); impl Encodable for u8 { fn ssz_append(&self, s: &mut SszStream) { @@ -81,3 +83,84 @@ impl Encodable for U256 { s.append_encoded_val(&a.to_vec()); } } + + +#[cfg(test)] +mod tests { + use super::super::{ + DecodeError, + decode_ssz_list_element, + }; + + #[test] + fn test_ssz_decode_u16() { + let ssz = vec![0, 0, 0, 1, 0]; + let result: u16 = decode_ssz_list_element(&ssz, 0).unwrap(); + assert_eq!(result, 0); + + let ssz = vec![0, 0, 0, 1, 16]; + let result: u16 = decode_ssz_list_element(&ssz, 0).unwrap(); + assert_eq!(result, 16); + + let ssz = vec![0, 0, 0, 2, 1, 0]; + let result: u16 = decode_ssz_list_element(&ssz, 0).unwrap(); + assert_eq!(result, 256); + + let ssz = vec![0, 0, 0, 2, 255, 255]; + let result: u16 = decode_ssz_list_element(&ssz, 0).unwrap(); + assert_eq!(result, 65535); + + let ssz = vec![0, 0, 0, 3, 0, 0, 1]; + let result: Result = + decode_ssz_list_element(&ssz, 0); + assert_eq!(result, Err(DecodeError::TooLong)); + } + + #[test] + fn test_ssz_decode_u32() { + let ssz = vec![0, 0, 0, 1, 0]; + let result: u32 = decode_ssz_list_element(&ssz, 0).unwrap(); + assert_eq!(result, 0); + + let ssz = vec![0, 0, 0, 4, 255, 255, 255, 255]; + let result: u32 = decode_ssz_list_element(&ssz, 0).unwrap(); + assert_eq!(result, 4294967295); + + let ssz = vec![0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 1]; + let result: Result = + decode_ssz_list_element(&ssz, 0); + assert_eq!(result, Err(DecodeError::TooLong)); + } + + #[test] + fn test_ssz_decode_u64() { + let ssz = vec![0, 0, 0, 1, 0]; + let result: u64 = decode_ssz_list_element(&ssz, 0).unwrap(); + assert_eq!(result, 0); + + let ssz = vec![0, 0, 0, 8, 255, 255, 255, 255, 255, 255, 255, 255]; + let result: u64 = decode_ssz_list_element(&ssz, 0).unwrap(); + assert_eq!(result, 18446744073709551615); + + let ssz = vec![0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 1]; + let result: Result = + decode_ssz_list_element(&ssz, 0); + assert_eq!(result, Err(DecodeError::TooLong)); + } + + #[test] + fn test_ssz_decode_usize() { + let ssz = vec![0, 0, 0, 1, 0]; + let result: usize = decode_ssz_list_element(&ssz, 0).unwrap(); + assert_eq!(result, 0); + + let ssz = vec![0, 0, 0, 8, 255, 255, 255, 255, 255, 255, 255, 255]; + let result: usize = decode_ssz_list_element(&ssz, 0).unwrap(); + assert_eq!(result, 18446744073709551615); + + let ssz = vec![0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 1]; + let result: Result = + decode_ssz_list_element(&ssz, 0); + assert_eq!(result, Err(DecodeError::TooLong)); + } +}