diff --git a/ssz/src/encode.rs b/ssz/src/encode.rs index 186c7582d..d5095af6b 100644 --- a/ssz/src/encode.rs +++ b/ssz/src/encode.rs @@ -1,4 +1,12 @@ -use super::LENGTH_BYTES; +use super::{ + LENGTH_BYTES, + MAX_LIST_SIZE, +}; + +#[derive(Debug)] +pub enum EncodeError { + ListTooLong, +} pub trait Encodable { fn ssz_append(&self, s: &mut SszStream); @@ -52,11 +60,19 @@ impl SszStream { /// The length of the list will be concatenated to the stream, then /// each item in the vector will be encoded and concatenated. pub fn append_vec(&mut self, vec: &Vec) + -> Result<(), EncodeError> where E: Encodable { - self.buffer.extend_from_slice(&encode_length(vec.len(), LENGTH_BYTES)); - for v in vec { - v.ssz_append(self); + let mut list_stream = SszStream::new(); + for item in vec { + item.ssz_append(&mut list_stream); + } + let list_ssz = list_stream.drain(); + if list_ssz.len() <= MAX_LIST_SIZE { + self.append_encoded_val(&list_ssz); + Ok(()) + } else { + Err(EncodeError::ListTooLong) } } @@ -121,4 +137,16 @@ mod tests { fn test_encode_length_4_bytes_panic() { encode_length(4294967296, LENGTH_BYTES); // 2^(3*8) } + + #[test] + fn test_encode_list() { + let test_vec: Vec = vec![256; 12]; + let mut stream = SszStream::new(); + stream.append_vec(&test_vec).unwrap(); + let ssz = stream.drain(); + + assert_eq!(ssz.len(), 4 + (12 * 2)); + assert_eq!(ssz[0..4], *vec![0, 0, 0, 24]); + assert_eq!(ssz[4..6], *vec![1, 0]); + } } diff --git a/ssz/src/lib.rs b/ssz/src/lib.rs index d75072801..0fcfb21db 100644 --- a/ssz/src/lib.rs +++ b/ssz/src/lib.rs @@ -27,3 +27,4 @@ pub use encode::{ }; pub const LENGTH_BYTES: usize = 4; +pub const MAX_LIST_SIZE : usize = 1 << (4 * 8);