diff --git a/crates/cargo-contract/src/cmd/extrinsics/call.rs b/crates/cargo-contract/src/cmd/extrinsics/call.rs index 4555f1aa1..0e680c8e6 100644 --- a/crates/cargo-contract/src/cmd/extrinsics/call.rs +++ b/crates/cargo-contract/src/cmd/extrinsics/call.rs @@ -44,6 +44,7 @@ use contract_build::name_value_println; use anyhow::{ anyhow, + Context, Result, }; @@ -112,7 +113,11 @@ impl CallCommand { match result.result { Ok(ref ret_val) => { let value = transcoder - .decode_return(&self.message, &mut &ret_val.data[..])?; + .decode_return(&self.message, &mut &ret_val.data[..]) + .context(format!( + "Failed to decode return value {:?}", + &ret_val + ))?; let dry_run_result = CallDryRunResult { result: String::from("Success!"), reverted: ret_val.did_revert(), diff --git a/crates/transcode/src/decode.rs b/crates/transcode/src/decode.rs index 1fc9593f7..592a791d4 100644 --- a/crates/transcode/src/decode.rs +++ b/crates/transcode/src/decode.rs @@ -180,7 +180,8 @@ impl<'a> Decoder<'a> { let discriminant = input.read_byte()?; let variant = variant_type .variants() - .get(discriminant as usize) + .iter() + .find(|v| v.index == discriminant) .ok_or_else(|| { anyhow::anyhow!("No variant found with discriminant {}", discriminant) })?; diff --git a/crates/transcode/src/lib.rs b/crates/transcode/src/lib.rs index 05b70f880..e93d73488 100644 --- a/crates/transcode/src/lib.rs +++ b/crates/transcode/src/lib.rs @@ -629,6 +629,30 @@ mod tests { assert_eq!(expected, decoded); } + #[test] + fn decode_lang_error() { + use ink::primitives::LangError; + + let metadata = generate_metadata(); + let transcoder = ContractMessageTranscoder::new(metadata); + + let encoded = + Result::::Err(LangError::CouldNotReadInput).encode(); + let decoded = transcoder + .decode_return("get", &mut &encoded[..]) + .unwrap_or_else(|e| panic!("Error decoding return value {}", e)); + + let expected = Value::Tuple(Tuple::new( + "Err".into(), + [Value::Tuple(Tuple::new( + Some("CouldNotReadInput"), + Vec::new(), + ))] + .to_vec(), + )); + assert_eq!(expected, decoded); + } + #[test] fn decode_contract_event() -> Result<()> { let metadata = generate_metadata();