Remove old code, fix bug with MAX_LENGTH_VALUE
				
					
				
			This commit is contained in:
		
							parent
							
								
									9d27f67643
								
							
						
					
					
						commit
						c31ef5cf7f
					
				| @ -173,209 +173,3 @@ fn decode_offset(bytes: &[u8]) -> Result<usize, DecodeError> { | ||||
|         Ok(u32::from_le_bytes(array) as usize) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 
 | ||||
| /// Decode the given bytes for the given type
 | ||||
| ///
 | ||||
| /// The single ssz encoded value/container/list will be decoded as the given type,
 | ||||
| /// by recursively calling `ssz_decode`.
 | ||||
| /// Check on totality for underflowing the length of bytes and overflow checks done per container
 | ||||
| pub fn decode<T>(ssz_bytes: &[u8]) -> Result<(T), DecodeError> | ||||
| where | ||||
|     T: Decodable, | ||||
| { | ||||
|     let (decoded, i): (T, usize) = match T::ssz_decode(ssz_bytes, 0) { | ||||
|         Err(e) => return Err(e), | ||||
|         Ok(v) => v, | ||||
|     }; | ||||
| 
 | ||||
|     if i < ssz_bytes.len() { | ||||
|         return Err(DecodeError::TooLong); | ||||
|     } | ||||
| 
 | ||||
|     Ok(decoded) | ||||
| } | ||||
| 
 | ||||
| /// Decode a vector (list) of encoded bytes.
 | ||||
| ///
 | ||||
| /// Each element in the list will be decoded and placed into the vector.
 | ||||
| pub fn decode_ssz_list<T>(ssz_bytes: &[u8], index: usize) -> Result<(Vec<T>, usize), DecodeError> | ||||
| where | ||||
|     T: Decodable, | ||||
| { | ||||
|     if index + LENGTH_BYTES > ssz_bytes.len() { | ||||
|         return Err(DecodeError::TooShort); | ||||
|     }; | ||||
| 
 | ||||
|     // get the length
 | ||||
|     let serialized_length = match decode_length(ssz_bytes, index, LENGTH_BYTES) { | ||||
|         Err(v) => return Err(v), | ||||
|         Ok(v) => v, | ||||
|     }; | ||||
| 
 | ||||
|     let final_len: usize = index + LENGTH_BYTES + serialized_length; | ||||
| 
 | ||||
|     if final_len > ssz_bytes.len() { | ||||
|         return Err(DecodeError::TooShort); | ||||
|     }; | ||||
| 
 | ||||
|     let mut tmp_index = index + LENGTH_BYTES; | ||||
|     let mut res_vec: Vec<T> = Vec::new(); | ||||
| 
 | ||||
|     while tmp_index < final_len { | ||||
|         match T::ssz_decode(ssz_bytes, tmp_index) { | ||||
|             Err(v) => return Err(v), | ||||
|             Ok(v) => { | ||||
|                 tmp_index = v.1; | ||||
|                 res_vec.push(v.0); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     Ok((res_vec, final_len)) | ||||
| } | ||||
| 
 | ||||
| /// Given some number of bytes, interpret the first four
 | ||||
| /// bytes as a 32-bit little-endian integer and return the
 | ||||
| /// result.
 | ||||
| pub fn decode_length( | ||||
|     bytes: &[u8], | ||||
|     index: usize, | ||||
|     length_bytes: usize, | ||||
| ) -> Result<usize, DecodeError> { | ||||
|     if bytes.len() < index + length_bytes { | ||||
|         return Err(DecodeError::TooShort); | ||||
|     }; | ||||
|     let mut len: usize = 0; | ||||
|     for (i, byte) in bytes | ||||
|         .iter() | ||||
|         .enumerate() | ||||
|         .take(index + length_bytes) | ||||
|         .skip(index) | ||||
|     { | ||||
|         let offset = (i - index) * 8; | ||||
|         len |= (*byte as usize) << offset; | ||||
|     } | ||||
|     Ok(len) | ||||
| } | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::super::encode::*; | ||||
|     use super::*; | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_ssz_decode_length() { | ||||
|         let decoded = decode_length(&vec![1, 0, 0, 0], 0, LENGTH_BYTES); | ||||
|         assert_eq!(decoded.unwrap(), 1); | ||||
| 
 | ||||
|         let decoded = decode_length(&vec![0, 1, 0, 0], 0, LENGTH_BYTES); | ||||
|         assert_eq!(decoded.unwrap(), 256); | ||||
| 
 | ||||
|         let decoded = decode_length(&vec![255, 1, 0, 0], 0, LENGTH_BYTES); | ||||
|         assert_eq!(decoded.unwrap(), 511); | ||||
| 
 | ||||
|         let decoded = decode_length(&vec![255, 255, 255, 255], 0, LENGTH_BYTES); | ||||
|         assert_eq!(decoded.unwrap(), 4294967295); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_encode_decode_length() { | ||||
|         let params: Vec<usize> = vec![ | ||||
|             0, | ||||
|             1, | ||||
|             2, | ||||
|             3, | ||||
|             7, | ||||
|             8, | ||||
|             16, | ||||
|             2 ^ 8, | ||||
|             2 ^ 8 + 1, | ||||
|             2 ^ 16, | ||||
|             2 ^ 16 + 1, | ||||
|             2 ^ 24, | ||||
|             2 ^ 24 + 1, | ||||
|             2 ^ 32, | ||||
|         ]; | ||||
|         for i in params { | ||||
|             let decoded = decode_length(&encode_length(i, LENGTH_BYTES), 0, LENGTH_BYTES).unwrap(); | ||||
|             assert_eq!(i, decoded); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_encode_decode_ssz_list() { | ||||
|         let test_vec: Vec<u16> = vec![256; 12]; | ||||
|         let mut stream = SszStream::new(); | ||||
|         stream.append_vec(&test_vec); | ||||
|         let ssz = stream.drain(); | ||||
| 
 | ||||
|         // u16
 | ||||
|         let decoded: (Vec<u16>, usize) = decode_ssz_list(&ssz, 0).unwrap(); | ||||
| 
 | ||||
|         assert_eq!(decoded.0, test_vec); | ||||
|         assert_eq!(decoded.1, LENGTH_BYTES + (12 * 2)); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_decode_ssz_list() { | ||||
|         // u16
 | ||||
|         let v: Vec<u16> = vec![10, 10, 10, 10]; | ||||
|         let decoded: (Vec<u16>, usize) = | ||||
|             decode_ssz_list(&vec![8, 0, 0, 0, 10, 0, 10, 0, 10, 0, 10, 0], 0).unwrap(); | ||||
| 
 | ||||
|         assert_eq!(decoded.0, v); | ||||
|         assert_eq!(decoded.1, LENGTH_BYTES + (4 * 2)); | ||||
| 
 | ||||
|         // u32
 | ||||
|         let v: Vec<u32> = vec![10, 10, 10, 10]; | ||||
|         let decoded: (Vec<u32>, usize) = decode_ssz_list( | ||||
|             &vec![ | ||||
|                 16, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 00, | ||||
|             ], | ||||
|             0, | ||||
|         ) | ||||
|         .unwrap(); | ||||
|         assert_eq!(decoded.0, v); | ||||
|         assert_eq!(decoded.1, 20); | ||||
| 
 | ||||
|         // u64
 | ||||
|         let v: Vec<u64> = vec![10, 10, 10, 10]; | ||||
|         let decoded: (Vec<u64>, usize) = decode_ssz_list( | ||||
|             &vec![ | ||||
|                 32, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, | ||||
|                 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, | ||||
|             ], | ||||
|             0, | ||||
|         ) | ||||
|         .unwrap(); | ||||
|         assert_eq!(decoded.0, v); | ||||
|         assert_eq!(decoded.1, LENGTH_BYTES + (8 * 4)); | ||||
| 
 | ||||
|         // Check that it can accept index
 | ||||
|         let v: Vec<usize> = vec![15, 15, 15, 15]; | ||||
|         let offset = 10; | ||||
|         let decoded: (Vec<usize>, usize) = decode_ssz_list( | ||||
|             &vec![ | ||||
|                 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 32, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, | ||||
|                 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, | ||||
|             ], | ||||
|             offset, | ||||
|         ) | ||||
|         .unwrap(); | ||||
|         assert_eq!(decoded.0, v); | ||||
|         assert_eq!(decoded.1, offset + LENGTH_BYTES + (8 * 4)); | ||||
| 
 | ||||
|         // Check that length > bytes throws error
 | ||||
|         let decoded: Result<(Vec<usize>, usize), DecodeError> = | ||||
|             decode_ssz_list(&vec![32, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0], 0); | ||||
|         assert_eq!(decoded, Err(DecodeError::TooShort)); | ||||
| 
 | ||||
|         // Check that incorrect index throws error
 | ||||
|         let decoded: Result<(Vec<usize>, usize), DecodeError> = | ||||
|             decode_ssz_list(&vec![15, 0, 0, 0, 0, 0, 0, 0], 16); | ||||
|         assert_eq!(decoded, Err(DecodeError::TooShort)); | ||||
|     } | ||||
| } | ||||
| */ | ||||
|  | ||||
| @ -64,197 +64,62 @@ impl<'a> SszEncoder<'a> { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| pub struct VariableLengths { | ||||
|     pub fixed_bytes_position: usize, | ||||
|     pub variable_bytes_length: usize, | ||||
| } | ||||
| 
 | ||||
| /// Provides a buffer for appending SSZ values.
 | ||||
| #[derive(Default)] | ||||
| pub struct SszStream { | ||||
|     fixed_bytes: Vec<u8>, | ||||
|     variable_bytes: Vec<u8>, | ||||
|     variable_lengths: Vec<VariableLengths>, | ||||
| } | ||||
| 
 | ||||
| impl SszStream { | ||||
|     /// Create a new, empty stream for writing SSZ values.
 | ||||
|     pub fn new() -> Self { | ||||
|         SszStream { | ||||
|             fixed_bytes: vec![], | ||||
|             variable_bytes: vec![], | ||||
|             variable_lengths: vec![], | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /* | ||||
|     /// Append some item to the stream.
 | ||||
|     pub fn append<T: Encodable>(&mut self, item: &T) { | ||||
|         let mut bytes = item.as_ssz_bytes(); | ||||
| 
 | ||||
|         if T::is_ssz_fixed_len() { | ||||
|             self.app | ||||
|             self.fixed_bytes.append(&mut bytes); | ||||
|         } else { | ||||
|             self.variable_lengths.push(VariableLengths { | ||||
|                 fixed_bytes_position: self.fixed_bytes.len(), | ||||
|                 variable_bytes_length: bytes.len(), | ||||
|             }); | ||||
| 
 | ||||
|             self.fixed_bytes | ||||
|                 .append(&mut vec![0; BYTES_PER_LENGTH_OFFSET]); | ||||
|             self.variable_bytes.append(&mut bytes); | ||||
|         } | ||||
|     } | ||||
|     */ | ||||
|     pub fn reserve<T: Encodable>(&mut self, additional: usize) { | ||||
|         if T::is_ssz_fixed_len() { | ||||
|             self.fixed_bytes.reserve(additional * T::ssz_fixed_len()); | ||||
|         } else { | ||||
|             self.fixed_bytes | ||||
|                 .reserve(additional * BYTES_PER_LENGTH_OFFSET); | ||||
|             self.variable_lengths.reserve(additional); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn append_fixed_bytes(&mut self, bytes: &[u8]) { | ||||
|         self.fixed_bytes.extend_from_slice(bytes) | ||||
|     } | ||||
| 
 | ||||
|     pub fn append_variable_bytes(&mut self, bytes: &[u8]) { | ||||
|         self.variable_lengths.push(VariableLengths { | ||||
|             fixed_bytes_position: self.fixed_bytes.len(), | ||||
|             variable_bytes_length: bytes.len(), | ||||
|         }); | ||||
| 
 | ||||
|         self.fixed_bytes | ||||
|             .append(&mut vec![0; BYTES_PER_LENGTH_OFFSET]); | ||||
| 
 | ||||
|         self.variable_bytes.extend_from_slice(bytes); | ||||
|     } | ||||
| 
 | ||||
|     /// Update the offsets (if any) in the fixed-length bytes to correctly point to the values in
 | ||||
|     /// the variable length part.
 | ||||
|     pub fn apply_offsets(&mut self) { | ||||
|         let mut running_offset = self.fixed_bytes.len(); | ||||
| 
 | ||||
|         for v in &self.variable_lengths { | ||||
|             let offset = running_offset; | ||||
|             running_offset += v.variable_bytes_length; | ||||
| 
 | ||||
|             self.fixed_bytes.splice( | ||||
|                 v.fixed_bytes_position..v.fixed_bytes_position + BYTES_PER_LENGTH_OFFSET, | ||||
|                 encode_length(offset), | ||||
|             ); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Append the variable-length bytes to the fixed-length bytes and return the result.
 | ||||
|     pub fn drain(mut self) -> Vec<u8> { | ||||
|         self.apply_offsets(); | ||||
| 
 | ||||
|         self.fixed_bytes.append(&mut self.variable_bytes); | ||||
| 
 | ||||
|         self.fixed_bytes | ||||
|     } | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| /// Encode `len` as a little-endian byte vec of `BYTES_PER_LENGTH_OFFSET` length.
 | ||||
| ///
 | ||||
| /// If `len` is larger than `2 ^ BYTES_PER_LENGTH_OFFSET`, a `debug_assert` is raised.
 | ||||
| pub fn encode_length(len: usize) -> Vec<u8> { | ||||
|     // Note: it is possible for `len` to be larger than what can be encoded in
 | ||||
|     // `BYTES_PER_LENGTH_OFFSET` bytes, triggering this debug assertion.
 | ||||
|     //
 | ||||
|     // These are the alternatives to using a `debug_assert` here:
 | ||||
|     //
 | ||||
|     // 1. Use `assert`.
 | ||||
|     // 2. Push an error to the caller (e.g., `Option` or `Result`).
 | ||||
|     // 3. Ignore it completely.
 | ||||
|     //
 | ||||
|     // I have avoided (1) because it's basically a choice between "produce invalid SSZ" or "kill
 | ||||
|     // the entire program". I figure it may be possible for an attacker to trigger this assert and
 | ||||
|     // take the program down -- I think producing invalid SSZ is a better option than this.
 | ||||
|     //
 | ||||
|     // I have avoided (2) because this error will need to be propagated upstream, making encoding a
 | ||||
|     // function which may fail. I don't think this is ergonomic and the upsides don't outweigh the
 | ||||
|     // downsides.
 | ||||
|     //
 | ||||
|     // I figure a `debug_assertion` is better than (3) as it will give us a change to detect the
 | ||||
|     // error during testing.
 | ||||
|     //
 | ||||
|     // If you have a different opinion, feel free to start an issue and tag @paulhauner.
 | ||||
|     debug_assert!(len <= MAX_LENGTH_VALUE); | ||||
| 
 | ||||
|     len.to_le_bytes()[0..BYTES_PER_LENGTH_OFFSET].to_vec() | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     use super::*; | ||||
| 
 | ||||
|     #[test] | ||||
|     #[should_panic] | ||||
|     fn test_encode_length_0_bytes_panic() { | ||||
|         encode_length(0, 0); | ||||
|     } | ||||
|     fn test_encode_length() { | ||||
|         assert_eq!(encode_length(0), vec![0; 4]); | ||||
| 
 | ||||
|         assert_eq!(encode_length(1), vec![1, 0, 0, 0]); | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_encode_length_4_bytes() { | ||||
|         assert_eq!(encode_length(0, LENGTH_BYTES), vec![0; 4]); | ||||
|         assert_eq!(encode_length(1, LENGTH_BYTES), vec![1, 0, 0, 0]); | ||||
|         assert_eq!(encode_length(255, LENGTH_BYTES), vec![255, 0, 0, 0]); | ||||
|         assert_eq!(encode_length(256, LENGTH_BYTES), vec![0, 1, 0, 0]); | ||||
|         assert_eq!( | ||||
|             encode_length(4294967295, LENGTH_BYTES), // 2^(3*8) - 1
 | ||||
|             vec![255, 255, 255, 255] | ||||
|             encode_length(MAX_LENGTH_VALUE), | ||||
|             vec![255; BYTES_PER_LENGTH_OFFSET] | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_encode_lower_length() { | ||||
|         assert_eq!(encode_length(0, LENGTH_BYTES - 2), vec![0; 2]); | ||||
|         assert_eq!(encode_length(1, LENGTH_BYTES - 2), vec![1, 0]); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_encode_higher_length() { | ||||
|         assert_eq!(encode_length(0, LENGTH_BYTES + 2), vec![0; 6]); | ||||
|         assert_eq!(encode_length(1, LENGTH_BYTES + 2), vec![1, 0, 0, 0, 0, 0]); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     #[should_panic] | ||||
|     fn test_encode_length_4_bytes_panic() { | ||||
|         encode_length(4294967296, LENGTH_BYTES); // 2^(3*8)
 | ||||
|     #[cfg(debug_assertions)] | ||||
|     fn test_encode_length_above_max_debug_panics() { | ||||
|         encode_length(MAX_LENGTH_VALUE + 1); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_encode_list() { | ||||
|         let test_vec: Vec<u16> = vec![256; 12]; | ||||
|         let mut stream = SszStream::new(); | ||||
|         stream.append_vec(&test_vec); | ||||
|         let ssz = stream.drain(); | ||||
| 
 | ||||
|         assert_eq!(ssz.len(), LENGTH_BYTES + (12 * 2)); | ||||
|         assert_eq!(ssz[0..4], *vec![24, 0, 0, 0]); | ||||
|         assert_eq!(ssz[4..6], *vec![0, 1]); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_encode_mixed_prefixed() { | ||||
|         let test_vec: Vec<u16> = vec![100, 200]; | ||||
|         let test_value: u8 = 5; | ||||
| 
 | ||||
|         let mut stream = SszStream::new(); | ||||
|         stream.append_vec(&test_vec); | ||||
|         stream.append(&test_value); | ||||
|         let ssz = stream.drain(); | ||||
| 
 | ||||
|         assert_eq!(ssz.len(), LENGTH_BYTES + (2 * 2) + 1); | ||||
|         assert_eq!(ssz[0..4], *vec![4, 0, 0, 0]); | ||||
|         assert_eq!(ssz[4..6], *vec![100, 0]); | ||||
|         assert_eq!(ssz[6..8], *vec![200, 0]); | ||||
|         assert_eq!(ssz[8], 5); | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     fn test_encode_mixed_postfixed() { | ||||
|         let test_value: u8 = 5; | ||||
|         let test_vec: Vec<u16> = vec![100, 200]; | ||||
| 
 | ||||
|         let mut stream = SszStream::new(); | ||||
|         stream.append(&test_value); | ||||
|         stream.append_vec(&test_vec); | ||||
|         let ssz = stream.drain(); | ||||
| 
 | ||||
|         assert_eq!(ssz.len(), 1 + LENGTH_BYTES + (2 * 2)); | ||||
|         assert_eq!(ssz[0], 5); | ||||
|         assert_eq!(ssz[1..5], *vec![4, 0, 0, 0]); | ||||
|         assert_eq!(ssz[5..7], *vec![100, 0]); | ||||
|         assert_eq!(ssz[7..9], *vec![200, 0]); | ||||
|     #[cfg(not(debug_assertions))] | ||||
|     fn test_encode_length_above_max_not_debug_does_not_panic() { | ||||
|         assert_eq!(encode_length(MAX_LENGTH_VALUE + 1), vec![0; 4]); | ||||
|     } | ||||
| } | ||||
| */ | ||||
|  | ||||
| @ -1,18 +1,3 @@ | ||||
| /* | ||||
|  * This is a WIP of implementing an alternative | ||||
|  * serialization strategy. It attempts to follow Vitalik's | ||||
|  * "simpleserialize" format here: | ||||
|  * https://github.com/ethereum/beacon_chain/blob/master/beacon_chain/utils/simpleserialize.py
 | ||||
|  * | ||||
|  * This implementation is not final and would almost certainly | ||||
|  * have issues. | ||||
|  */ | ||||
| /* | ||||
| extern crate bytes; | ||||
| extern crate ethereum_types; | ||||
| 
 | ||||
| pub mod decode; | ||||
| */ | ||||
| mod decode; | ||||
| mod encode; | ||||
| 
 | ||||
| @ -20,7 +5,7 @@ pub use decode::{Decodable, DecodeError, SszDecoderBuilder}; | ||||
| pub use encode::{Encodable, SszEncoder}; | ||||
| 
 | ||||
| pub const BYTES_PER_LENGTH_OFFSET: usize = 4; | ||||
| pub const MAX_LENGTH_VALUE: usize = 1 << (BYTES_PER_LENGTH_OFFSET * 8) - 1; | ||||
| pub const MAX_LENGTH_VALUE: usize = (1 << (BYTES_PER_LENGTH_OFFSET * 8)) - 1; | ||||
| 
 | ||||
| /// Convenience function to SSZ encode an object supporting ssz::Encode.
 | ||||
| ///
 | ||||
| @ -31,208 +16,3 @@ where | ||||
| { | ||||
|     val.as_ssz_bytes() | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| 
 | ||||
| mod impl_decode; | ||||
| mod impl_encode; | ||||
| 
 | ||||
| pub use crate::decode::{decode, decode_ssz_list, Decodable, DecodeError}; | ||||
| pub use crate::encode::{Encodable, SszStream}; | ||||
| 
 | ||||
| pub use hashing::hash; | ||||
| 
 | ||||
| pub const LENGTH_BYTES: usize = 4; | ||||
| pub const MAX_LIST_SIZE: usize = 1 << (4 * 8); | ||||
| 
 | ||||
| 
 | ||||
| #[cfg(test)] | ||||
| mod tests { | ||||
|     extern crate hex; | ||||
|     extern crate yaml_rust; | ||||
| 
 | ||||
|     use self::yaml_rust::yaml; | ||||
|     use super::*; | ||||
|     use std::{fs::File, io::prelude::*, path::PathBuf}; | ||||
| 
 | ||||
|     #[test] | ||||
|     pub fn test_vector_uint_bounds() { | ||||
|         let mut file = { | ||||
|             let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); | ||||
|             file_path_buf.push("src/test_vectors/uint_bounds.yaml"); | ||||
| 
 | ||||
|             File::open(file_path_buf).unwrap() | ||||
|         }; | ||||
|         let mut yaml_str = String::new(); | ||||
|         file.read_to_string(&mut yaml_str).unwrap(); | ||||
|         let docs = yaml::YamlLoader::load_from_str(&yaml_str).unwrap(); | ||||
|         let doc = &docs[0]; | ||||
| 
 | ||||
|         // Load test cases
 | ||||
|         let test_cases = doc["test_cases"].clone(); | ||||
| 
 | ||||
|         for test_case in test_cases { | ||||
|             // Only the valid cases are checked as parse::<uX>() will fail for all invalid cases
 | ||||
|             if test_case["valid"].as_bool().unwrap() { | ||||
|                 // Convert test vector 'ssz' encoded yaml to Vec<u8>
 | ||||
|                 let ssz = test_case["ssz"].as_str().unwrap().trim_start_matches("0x"); | ||||
|                 let test_vector_bytes = hex::decode(ssz).unwrap(); | ||||
| 
 | ||||
|                 // Convert test vector 'value' to ssz encoded bytes
 | ||||
|                 let mut bytes: Vec<u8>; | ||||
|                 match test_case["type"].as_str().unwrap() { | ||||
|                     "uint8" => { | ||||
|                         let value: u8 = test_case["value"].as_str().unwrap().parse::<u8>().unwrap(); | ||||
|                         bytes = ssz_encode::<u8>(&value); // check encoding
 | ||||
| 
 | ||||
|                         // Check decoding
 | ||||
|                         let decoded = decode::<u8>(&test_vector_bytes).unwrap(); | ||||
|                         assert_eq!(decoded, value); | ||||
|                     } | ||||
|                     "uint16" => { | ||||
|                         let value: u16 = | ||||
|                             test_case["value"].as_str().unwrap().parse::<u16>().unwrap(); | ||||
|                         bytes = ssz_encode::<u16>(&value); | ||||
| 
 | ||||
|                         // Check decoding
 | ||||
|                         let decoded = decode::<u16>(&test_vector_bytes).unwrap(); | ||||
|                         assert_eq!(decoded, value); | ||||
|                     } | ||||
|                     "uint32" => { | ||||
|                         let value: u32 = | ||||
|                             test_case["value"].as_str().unwrap().parse::<u32>().unwrap(); | ||||
|                         bytes = ssz_encode::<u32>(&value); | ||||
| 
 | ||||
|                         // Check decoding
 | ||||
|                         let decoded = decode::<u32>(&test_vector_bytes).unwrap(); | ||||
|                         assert_eq!(decoded, value); | ||||
|                     } | ||||
|                     "uint64" => { | ||||
|                         let value: u64 = | ||||
|                             test_case["value"].as_str().unwrap().parse::<u64>().unwrap(); | ||||
|                         bytes = ssz_encode::<u64>(&value); | ||||
| 
 | ||||
|                         // Check decoding
 | ||||
|                         let decoded = decode::<u64>(&test_vector_bytes).unwrap(); | ||||
|                         assert_eq!(decoded, value); | ||||
|                     } | ||||
|                     _ => continue, | ||||
|                 }; | ||||
|                 assert_eq!(test_vector_bytes, bytes); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     pub fn test_vector_uint_random() { | ||||
|         let mut file = { | ||||
|             let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); | ||||
|             file_path_buf.push("src/test_vectors/uint_random.yaml"); | ||||
| 
 | ||||
|             File::open(file_path_buf).unwrap() | ||||
|         }; | ||||
|         let mut yaml_str = String::new(); | ||||
|         file.read_to_string(&mut yaml_str).unwrap(); | ||||
|         let docs = yaml::YamlLoader::load_from_str(&yaml_str).unwrap(); | ||||
|         let doc = &docs[0]; | ||||
| 
 | ||||
|         // Load test cases
 | ||||
|         let test_cases = doc["test_cases"].clone(); | ||||
| 
 | ||||
|         for test_case in test_cases { | ||||
|             // Only the valid cases are checked as parse::<uX>() will fail for all invalid cases
 | ||||
|             if test_case["valid"].as_bool().unwrap() { | ||||
|                 // Convert test vector 'ssz' encoded yaml to Vec<u8>
 | ||||
|                 let ssz = test_case["ssz"].as_str().unwrap().trim_start_matches("0x"); | ||||
|                 let test_vector_bytes = hex::decode(ssz).unwrap(); | ||||
| 
 | ||||
|                 // Convert test vector 'value' to ssz encoded bytes
 | ||||
|                 let mut bytes: Vec<u8>; | ||||
|                 match test_case["type"].as_str().unwrap() { | ||||
|                     "uint8" => { | ||||
|                         let value: u8 = test_case["value"].as_str().unwrap().parse::<u8>().unwrap(); | ||||
|                         bytes = ssz_encode::<u8>(&value); // check encoding
 | ||||
| 
 | ||||
|                         // Check decoding
 | ||||
|                         let decoded = decode::<u8>(&test_vector_bytes).unwrap(); | ||||
|                         assert_eq!(decoded, value); | ||||
|                     } | ||||
|                     "uint16" => { | ||||
|                         let value: u16 = | ||||
|                             test_case["value"].as_str().unwrap().parse::<u16>().unwrap(); | ||||
|                         bytes = ssz_encode::<u16>(&value); | ||||
| 
 | ||||
|                         // Check decoding
 | ||||
|                         let decoded = decode::<u16>(&test_vector_bytes).unwrap(); | ||||
|                         assert_eq!(decoded, value); | ||||
|                     } | ||||
|                     "uint32" => { | ||||
|                         let value: u32 = | ||||
|                             test_case["value"].as_str().unwrap().parse::<u32>().unwrap(); | ||||
|                         bytes = ssz_encode::<u32>(&value); | ||||
| 
 | ||||
|                         // Check decoding
 | ||||
|                         let decoded = decode::<u32>(&test_vector_bytes).unwrap(); | ||||
|                         assert_eq!(decoded, value); | ||||
|                     } | ||||
|                     "uint64" => { | ||||
|                         let value: u64 = | ||||
|                             test_case["value"].as_str().unwrap().parse::<u64>().unwrap(); | ||||
|                         bytes = ssz_encode::<u64>(&value); | ||||
| 
 | ||||
|                         // Check decoding
 | ||||
|                         let decoded = decode::<u64>(&test_vector_bytes).unwrap(); | ||||
|                         assert_eq!(decoded, value); | ||||
|                     } | ||||
|                     _ => continue, | ||||
|                 }; | ||||
|                 assert_eq!(test_vector_bytes, bytes); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[test] | ||||
|     pub fn test_vector_uint_wrong_length() { | ||||
|         let mut file = { | ||||
|             let mut file_path_buf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); | ||||
|             file_path_buf.push("src/test_vectors/uint_wrong_length.yaml"); | ||||
| 
 | ||||
|             File::open(file_path_buf).unwrap() | ||||
|         }; | ||||
|         let mut yaml_str = String::new(); | ||||
|         file.read_to_string(&mut yaml_str).unwrap(); | ||||
|         let docs = yaml::YamlLoader::load_from_str(&yaml_str).unwrap(); | ||||
|         let doc = &docs[0]; | ||||
| 
 | ||||
|         // Load test cases
 | ||||
|         let test_cases = doc["test_cases"].clone(); | ||||
| 
 | ||||
|         for test_case in test_cases { | ||||
|             // Convert test vector 'ssz' encoded yaml to Vec<u8>
 | ||||
|             let ssz = test_case["ssz"].as_str().unwrap().trim_start_matches("0x"); | ||||
|             let test_vector_bytes = hex::decode(ssz).unwrap(); | ||||
| 
 | ||||
|             // Attempt to decode invalid ssz bytes
 | ||||
|             match test_case["type"].as_str().unwrap() { | ||||
|                 "uint8" => { | ||||
|                     let decoded = decode::<u8>(&test_vector_bytes); | ||||
|                     assert!(decoded.is_err()); | ||||
|                 } | ||||
|                 "uint16" => { | ||||
|                     let decoded = decode::<u16>(&test_vector_bytes); | ||||
|                     assert!(decoded.is_err()); | ||||
|                 } | ||||
|                 "uint32" => { | ||||
|                     let decoded = decode::<u32>(&test_vector_bytes); | ||||
|                     assert!(decoded.is_err()); | ||||
|                 } | ||||
|                 "uint64" => { | ||||
|                     let decoded = decode::<u64>(&test_vector_bytes); | ||||
|                     assert!(decoded.is_err()); | ||||
|                 } | ||||
|                 _ => continue, | ||||
|             }; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user