paritytech/parity-scale-codec

Scale failed to decode field where empty `Vec` was encoded.

Closed this issue · 3 comments

It seems that if you encode struct with field of type Vec with empty vector as value decoding will fail:

stderr:
thread 'main' panicked at 'Failed to deserialize payload.: Error("Error decoding field CreateRole.permissions")', iroha/src/account.rs:273:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Failed test:

264     /// # let command_payload = &CreateRole {                                                                                        
265     /// #    role_name: "user".to_string(),                                                                                          
266     /// #    permissions: Vec::new(),                                                                                                
267     /// # };                                                                                                                         
268     /// # let result: Vec<u8> = command_payload.into();                                                                              
269     /// let command_payload: CreateRole  = result.into();                                                                            
270     /// ```                                                                                                                          
271     impl std::convert::From<Vec<u8>> for CreateRole {                                                                                
272         fn from(command_payload: Vec<u8>) -> Self {                                                                                  
273             <CreateRole>::decode(&mut command_payload.encode().as_slice())                                                           
274                 .expect("Failed to deserialize payload.")                                                                            
275         }                                                                                                                            
276     } 

Looks like a problem here:

impl<'a> Input for &'a [u8] {
	fn remaining_len(&mut self) -> Result<Option<usize>, Error> {
		Ok(Some(self.len()))
	}

My first thought was that there is no way of function to return None, so maybe 0 value of .len() is the reason. I tried to put string into vector:

   permissions: vec!["buy".to_string()],

Error stayed the same. Maybe the problem in Vec<String>?

Encoded struct in bytes: [40, 16, 117, 115, 101, 114, 4, 12, 98, 117, 121]
Struct definition:

218     #[derive(Clone, Debug, PartialEq, Encode, Decode)]
219     pub struct CreateRole {
220         pub role_name: String,
221         pub permissions: Vec<String>,
222     }
bkchr commented

Can you please provide the full test that uses encode and decode directly.

Hi @bkchr and thanks for a quick reply.
I paste full tests except import statements.
I also made a clean tests:

  1 #[cfg(test)]
  2 mod tests { 
  3     use parity_scale_codec::{Decode, Encode};
  4 
  5     #[derive(Encode, Decode)]
  6     struct TestStruct { 
  7         test_vec_string_field: Vec<String>,
  8     } 
  9 
 10     #[test]
 11     fn empty_vec() { 
 12         let empty_vec_test_struct = &TestStruct { 
 13             test_vec_string_field: Vec::new(),
 14         };
 15         let encoded = empty_vec_test_struct.encode();
 16         let _decoded = <TestStruct>::decode(&mut encoded.as_slice()).expect("Empty Vec Failed.");
 17     } 
 18 
 19     #[test]
 20     fn non_empty_vec() { 
 21         let non_empty_vec_test_struct = &TestStruct { 
 22             test_vec_string_field: vec!["раз".to_string()],
 23         };
 24         let encoded = non_empty_vec_test_struct.encode();
 25         let _decoded = 
 26             <TestStruct>::decode(&mut encoded.as_slice()).expect("Non Empty Vec Failed.");
 27     } 
 28 }

And they work fine.

I will close issue for now and will try to find difference between project case and clean case and return back with reproducible test or apologizes.

@bkchr my apologize.

I call .encode() twice in a row occasionally and it results in "loosing" first byte:

[52, 16, 116, 101, 115, 116, 4, 24, 209, 128, 208, 176, 208, 183]
[16, 116, 101, 115, 116, 4, 24, 209, 128, 208, 176, 208, 183]

Error message confused me a bit Error decoding field TestStruct.test_vec_string_field but really the problem was not with the field, but struct in general.