diff --git a/ssz/src/decode.rs b/ssz/src/decode.rs index 7cc4c24965..18988457f4 100644 --- a/ssz/src/decode.rs +++ b/ssz/src/decode.rs @@ -10,7 +10,7 @@ pub enum DecodeError { } pub trait Decodable: Sized { - fn ssz_decode(bytes: &[u8], index: usize) -> Result; + fn ssz_decode(bytes: &[u8], index: usize) -> Result<(Self, usize), DecodeError>; } /// Decode the given bytes for the given type @@ -18,7 +18,7 @@ pub trait Decodable: Sized { /// The single ssz encoded value will be decoded as the given type at the /// given index. pub fn decode_ssz(ssz_bytes: &[u8], index: usize) - -> Result + -> Result<(T, usize), DecodeError> where T: Decodable { if index >= ssz_bytes.len() { @@ -79,24 +79,24 @@ mod tests { #[test] fn test_ssz_decode_length() { let decoded = decode_length( - &vec![0, 0, 1], + &vec![0, 0, 0, 1], LENGTH_BYTES); assert_eq!(decoded.unwrap(), 1); let decoded = decode_length( - &vec![0, 1, 0], + &vec![0, 0, 1, 0], LENGTH_BYTES); assert_eq!(decoded.unwrap(), 256); let decoded = decode_length( - &vec![0, 1, 255], + &vec![0, 0, 1, 255], LENGTH_BYTES); assert_eq!(decoded.unwrap(), 511); let decoded = decode_length( - &vec![255, 255, 255], + &vec![255, 255, 255, 255], LENGTH_BYTES); - assert_eq!(decoded.unwrap(), 16777215); + assert_eq!(decoded.unwrap(), 4294967295); } #[test] @@ -115,24 +115,4 @@ mod tests { assert_eq!(i, decoded); } } - - #[test] - fn test_ssz_nth_value() { - let ssz = vec![0, 0, 1, 0]; - let result = nth_value(&ssz, 0).unwrap(); - assert_eq!(result, vec![0].as_slice()); - - let ssz = vec![0, 0, 4, 1, 2, 3, 4]; - let result = nth_value(&ssz, 0).unwrap(); - assert_eq!(result, vec![1, 2, 3, 4].as_slice()); - - let ssz = vec![0, 0, 1, 0, 0, 0, 1, 1]; - let result = nth_value(&ssz, 1).unwrap(); - assert_eq!(result, vec![1].as_slice()); - - let mut ssz = vec![0, 1, 255]; - ssz.append(&mut vec![42; 511]); - let result = nth_value(&ssz, 0).unwrap(); - assert_eq!(result, vec![42; 511].as_slice()); - } } diff --git a/ssz/src/encode.rs b/ssz/src/encode.rs index b94c36ca5c..186c7582d8 100644 --- a/ssz/src/encode.rs +++ b/ssz/src/encode.rs @@ -96,29 +96,29 @@ mod tests { fn test_encode_length_4_bytes() { assert_eq!( encode_length(0, LENGTH_BYTES), - vec![0; 3] + vec![0; 4] ); assert_eq!( encode_length(1, LENGTH_BYTES), - vec![0, 0, 1] + vec![0, 0, 0, 1] ); assert_eq!( encode_length(255, LENGTH_BYTES), - vec![0, 0, 255] + vec![0, 0, 0, 255] ); assert_eq!( encode_length(256, LENGTH_BYTES), - vec![0, 1, 0] + vec![0, 0, 1, 0] ); assert_eq!( - encode_length(16777215, LENGTH_BYTES), // 2^(3*8) - 1 - vec![255, 255, 255] + encode_length(4294967295, LENGTH_BYTES), // 2^(3*8) - 1 + vec![255, 255, 255, 255] ); } #[test] #[should_panic] fn test_encode_length_4_bytes_panic() { - encode_length(16777216, LENGTH_BYTES); // 2^(3*8) + encode_length(4294967296, LENGTH_BYTES); // 2^(3*8) } } diff --git a/ssz/src/impl_decode.rs b/ssz/src/impl_decode.rs index b17e93a4f6..5dcc4104af 100644 --- a/ssz/src/impl_decode.rs +++ b/ssz/src/impl_decode.rs @@ -6,7 +6,7 @@ macro_rules! impl_decodable_for_uint { ($type: ident, $bit_size: expr) => { impl Decodable for $type { fn ssz_decode(bytes: &[u8], index: usize) - -> Result + -> Result<(Self, usize), DecodeError> { assert!((0 < $bit_size) & ($bit_size <= 64) & @@ -19,7 +19,7 @@ macro_rules! impl_decodable_for_uint { let offset = ((index + max_bytes) - i - 1) * 8; result = ((bytes[i] as $type) << offset) | result; }; - Ok(result) + Ok((result, end_bytes)) } else { Err(DecodeError::TooShort) } @@ -44,23 +44,28 @@ mod tests { #[test] fn test_ssz_decode_u16() { let ssz = vec![0, 0]; - let result: u16 = decode_ssz(&ssz, 0).unwrap(); + + let (result, index): (u16, usize) = decode_ssz(&ssz, 0).unwrap(); assert_eq!(result, 0); + assert_eq!(index, 2); let ssz = vec![0, 16]; - let result: u16 = decode_ssz(&ssz, 0).unwrap(); + let (result, index): (u16, usize) = decode_ssz(&ssz, 0).unwrap(); assert_eq!(result, 16); + assert_eq!(index, 2); let ssz = vec![1, 0]; - let result: u16 = decode_ssz(&ssz, 0).unwrap(); + let (result, index): (u16, usize) = decode_ssz(&ssz, 0).unwrap(); assert_eq!(result, 256); + assert_eq!(index, 2); let ssz = vec![255, 255]; - let result: u16 = decode_ssz(&ssz, 0).unwrap(); + let (result, index): (u16, usize) = decode_ssz(&ssz, 0).unwrap(); + assert_eq!(index, 2); assert_eq!(result, 65535); let ssz = vec![1]; - let result: Result = + let result: Result<(u16, usize), DecodeError> = decode_ssz(&ssz, 0); assert_eq!(result, Err(DecodeError::TooShort)); } @@ -68,27 +73,32 @@ mod tests { #[test] fn test_ssz_decode_u32() { let ssz = vec![0, 0, 0, 0]; - let result: u32 = decode_ssz(&ssz, 0).unwrap(); + let (result, index): (u32, usize) = decode_ssz(&ssz, 0).unwrap(); assert_eq!(result, 0); + assert_eq!(index, 4); let ssz = vec![0, 0, 1, 0]; - let result: u32 = decode_ssz(&ssz, 0).unwrap(); + let (result, index): (u32, usize) = decode_ssz(&ssz, 0).unwrap(); + assert_eq!(index, 4); assert_eq!(result, 256); let ssz = vec![255, 255, 255, 0, 0, 1, 0]; - let result: u32 = decode_ssz(&ssz, 3).unwrap(); + let (result, index): (u32, usize) = decode_ssz(&ssz, 3).unwrap(); + assert_eq!(index, 7); assert_eq!(result, 256); let ssz = vec![0,200, 1, 0]; - let result: u32 = decode_ssz(&ssz, 0).unwrap(); + let (result, index): (u32, usize) = decode_ssz(&ssz, 0).unwrap(); + assert_eq!(index, 4); assert_eq!(result, 13107456); let ssz = vec![255, 255, 255, 255]; - let result: u32 = decode_ssz(&ssz, 0).unwrap(); + let (result, index): (u32, usize) = decode_ssz(&ssz, 0).unwrap(); + assert_eq!(index, 4); assert_eq!(result, 4294967295); let ssz = vec![0, 0, 1]; - let result: Result = + let result: Result<(u32, usize), DecodeError> = decode_ssz(&ssz, 0); assert_eq!(result, Err(DecodeError::TooShort)); } @@ -96,19 +106,22 @@ mod tests { #[test] fn test_ssz_decode_u64() { let ssz = vec![0, 0, 0, 0, 0, 0, 0, 0]; - let result: u64 = decode_ssz(&ssz, 0).unwrap(); + let (result, index): (u64, usize) = decode_ssz(&ssz, 0).unwrap(); + assert_eq!(index, 8); assert_eq!(result, 0); let ssz = vec![255, 255, 255, 255, 255, 255, 255, 255]; - let result: u64 = decode_ssz(&ssz, 0).unwrap(); + let (result, index): (u64, usize) = decode_ssz(&ssz, 0).unwrap(); + assert_eq!(index, 8); assert_eq!(result, 18446744073709551615); - let ssz = vec![255, 255, 255, 0, 0, 0, 0, 0, 0, 0]; - let result: u64 = decode_ssz(&ssz, 2).unwrap(); + let ssz = vec![0, 0, 8, 255, 0, 0, 0, 0, 0, 0, 0]; + let (result, index): (u64, usize) = decode_ssz(&ssz, 3).unwrap(); + assert_eq!(index, 11); assert_eq!(result, 18374686479671623680); let ssz = vec![0,0,0,0,0,0,0]; - let result: Result = + let result: Result<(u64, usize), DecodeError> = decode_ssz(&ssz, 0); assert_eq!(result, Err(DecodeError::TooShort)); } @@ -116,32 +129,35 @@ mod tests { #[test] fn test_ssz_decode_usize() { let ssz = vec![0, 0, 0, 0, 0, 0, 0, 0]; - let result: usize = decode_ssz(&ssz, 0).unwrap(); + let (result, index): (usize, usize) = decode_ssz(&ssz, 0).unwrap(); + assert_eq!(index, 8); assert_eq!(result, 0); let ssz = vec![0, 0, 8, 255, 255, 255, 255, 255, 255, 255, 255]; - let result: usize = decode_ssz(&ssz, 3).unwrap(); + let (result, index): (usize, usize) = decode_ssz(&ssz, 3).unwrap(); + assert_eq!(index, 11); assert_eq!(result, 18446744073709551615); - let ssz = vec![255, 255, 255, 255, 255, 255, 255, 255]; - let result: usize = decode_ssz(&ssz, 0).unwrap(); + let ssz = vec![255, 255, 255, 255, 255, 255, 255, 255, 255]; + let (result, index): (usize, usize) = decode_ssz(&ssz, 0).unwrap(); + assert_eq!(index, 8); assert_eq!(result, 18446744073709551615); let ssz = vec![0, 0, 0, 0, 0, 0, 1]; - let result: Result = + let result: Result<(usize, usize), DecodeError> = decode_ssz(&ssz, 0); assert_eq!(result, Err(DecodeError::TooShort)); } #[test] fn test_decode_ssz_bounds() { - let err: Result = decode_ssz( + let err: Result<(u16, usize), DecodeError> = decode_ssz( &vec![1], 2 ); assert_eq!(err, Err(DecodeError::OutOfBounds)); - let err: Result = decode_ssz( + let err: Result<(u16,usize), DecodeError> = decode_ssz( &vec![0, 0, 0, 0], 3 ); @@ -150,7 +166,7 @@ mod tests { let result: u16 = decode_ssz( &vec![0,0,0,0,1], 3 - ).unwrap(); + ).unwrap().0; assert_eq!(result, 1); } } diff --git a/ssz/src/lib.rs b/ssz/src/lib.rs index 7fa2642067..6a0fd66ce3 100644 --- a/ssz/src/lib.rs +++ b/ssz/src/lib.rs @@ -25,4 +25,4 @@ pub use encode::{ SszStream, }; -pub const LENGTH_BYTES: usize = 3; +pub const LENGTH_BYTES: usize = 4;