diff --git a/src/cmd/extrinsics/instantiate.rs b/src/cmd/extrinsics/instantiate.rs index 969bb8c00a88208f2c03598c3b24525f2a3499e5..4330b83e2a9ed9495fb95b4407125d44aeed8a01 100644 --- a/src/cmd/extrinsics/instantiate.rs +++ b/src/cmd/extrinsics/instantiate.rs @@ -202,6 +202,7 @@ impl<'a> Exec<'a> { } async fn exec(&self, code: Code, dry_run: bool) -> Result<()> { + log::debug!("instantiate data {:?}", self.args.data); if dry_run { let result = self.instantiate_dry_run(code).await?; match result.result { @@ -335,8 +336,10 @@ impl<'a> Exec<'a> { salt: self.args.salt.clone(), }; let params = rpc_params![call_request]; - let result: ContractInstantiateResult = - cli.request("contracts_instantiate", params).await?; + let result: ContractInstantiateResult = cli + .request("contracts_instantiate", params) + .await + .context("contracts_instantiate RPC error")?; Ok(result) } } diff --git a/src/cmd/extrinsics/transcode/encode.rs b/src/cmd/extrinsics/transcode/encode.rs index 13e6782794a915caa39f2db5e339783aeb7c069f..aa7d5c22273b8e3bc30b50ddf4f280373f282f66 100644 --- a/src/cmd/extrinsics/transcode/encode.rs +++ b/src/cmd/extrinsics/transcode/encode.rs @@ -80,42 +80,32 @@ impl<'a> Encoder<'a> { ty.type_def(), ); if !self.env_types.try_encode(type_id, value, output)? { - self.encode_type(ty.type_def(), value, output) - .map_err(|e| { - anyhow::anyhow!("Error encoding value for {:?}: {}", ty, e) - })? + match ty.type_def() { + TypeDef::Composite(composite) => { + self.encode_composite(composite.fields(), value, output) + } + TypeDef::Variant(variant) => { + self.encode_variant_type(variant, value, output) + } + TypeDef::Array(array) => { + self.encode_seq(array.type_param(), value, false, output) + } + TypeDef::Tuple(tuple) => self.encode_tuple(tuple, value, output), + TypeDef::Sequence(sequence) => { + self.encode_seq(sequence.type_param(), value, true, output) + } + TypeDef::Primitive(primitive) => { + self.encode_primitive(primitive, value, output) + } + TypeDef::Compact(compact) => self.encode_compact(compact, value, output), + TypeDef::BitSequence(_) => { + Err(anyhow::anyhow!("bitvec encoding not yet supported")) + } + }?; } Ok(()) } - fn encode_type( - &self, - type_def: &TypeDef, - value: &Value, - output: &mut O, - ) -> Result<()> { - match type_def { - TypeDef::Composite(composite) => { - self.encode_composite(composite.fields(), value, output) - } - TypeDef::Variant(variant) => self.encode_variant_type(variant, value, output), - TypeDef::Array(array) => { - self.encode_seq(array.type_param(), value, false, output) - } - TypeDef::Tuple(tuple) => self.encode_tuple(tuple, value, output), - TypeDef::Sequence(sequence) => { - self.encode_seq(sequence.type_param(), value, true, output) - } - TypeDef::Primitive(primitive) => { - self.encode_primitive(primitive, value, output) - } - TypeDef::Compact(compact) => self.encode_compact(compact, value, output), - TypeDef::BitSequence(_) => { - Err(anyhow::anyhow!("bitvec encoding not yet supported")) - } - } - } - fn encode_composite( &self, fields: &[Field], @@ -249,16 +239,13 @@ impl<'a> Encoder<'a> { encode_len: bool, output: &mut O, ) -> Result<()> { - let ty = self.registry.resolve(ty.id()).ok_or_else(|| { - anyhow::anyhow!("Failed to find type with id '{}'", ty.id()) - })?; match value { Value::Seq(values) => { if encode_len { Compact(values.len() as u32).encode_to(output); } for value in values.elems() { - self.encode_type(ty.type_def(), value, output)?; + self.encode(ty.id(), value, output)?; } } Value::Bytes(bytes) => { diff --git a/src/cmd/extrinsics/transcode/env_types.rs b/src/cmd/extrinsics/transcode/env_types.rs index df4198c2620b069c4a4d51b9d86d0f1eb1c0e03e..7e526569246d8b1fd1f2fe9fc8c83983f4811d03 100644 --- a/src/cmd/extrinsics/transcode/env_types.rs +++ b/src/cmd/extrinsics/transcode/env_types.rs @@ -15,7 +15,10 @@ // along with cargo-contract. If not, see . use super::scon::Value; -use anyhow::Result; +use anyhow::{ + Context, + Result, +}; use scale::{ Decode, Encode, @@ -68,7 +71,9 @@ impl EnvTypesTranscoder { match self.transcoders.get(&type_id) { Some(transcoder) => { log::debug!("Encoding type {:?} with custom encoder", type_id); - let encoded_env_type = transcoder.encode_value(value)?; + let encoded_env_type = transcoder + .encode_value(value) + .context("Error encoding custom type")?; output.write(&encoded_env_type); Ok(true) } diff --git a/src/cmd/extrinsics/transcode/mod.rs b/src/cmd/extrinsics/transcode/mod.rs index 898575c2e595fc47cc67bb6e3cb07e25f3e53a67..daf95b16cc173511e1c030e20510aa34dacabce6 100644 --- a/src/cmd/extrinsics/transcode/mod.rs +++ b/src/cmd/extrinsics/transcode/mod.rs @@ -349,9 +349,9 @@ mod tests { use ink_lang as ink; #[ink::contract] - pub mod flipper { + pub mod transcode { #[ink(storage)] - pub struct Flipper { + pub struct Transcode { value: bool, } @@ -363,36 +363,41 @@ mod tests { from: AccountId, } - impl Flipper { - /// Creates a new flipper smart contract initialized with the given value. + impl Transcode { #[ink(constructor)] pub fn new(init_value: bool) -> Self { Self { value: init_value } } - /// Creates a new flipper smart contract initialized to `false`. #[ink(constructor)] pub fn default() -> Self { Self::new(Default::default()) } - /// Flips the current value of the Flipper's bool. #[ink(message)] pub fn flip(&mut self) { self.value = !self.value; } - /// Returns the current value of the Flipper's bool. #[ink(message)] pub fn get(&self) -> bool { self.value } - /// Dummy setter which receives the env type AccountId. #[ink(message)] pub fn set_account_id(&self, account_id: AccountId) { let _ = account_id; } + + #[ink(message)] + pub fn set_account_ids_vec(&self, account_ids: Vec) { + let _ = account_ids; + } + + #[ink(message)] + pub fn primitive_vec_args(&self, args: Vec) { + let _ = args; + } } } @@ -442,6 +447,48 @@ mod tests { Ok(()) } + #[test] + fn encode_account_ids_vec_args() -> Result<()> { + let metadata = generate_metadata(); + let transcoder = ContractMessageTranscoder::new(&metadata); + + let encoded = transcoder.encode( + "set_account_ids_vec", + &["[5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY, 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty]"], + )?; + + // encoded args follow the 4 byte selector + let encoded_args = &encoded[4..]; + + let expected = vec![ + sp_core::crypto::AccountId32::from_str( + "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + ) + .unwrap(), + sp_core::crypto::AccountId32::from_str( + "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", + ) + .unwrap(), + ]; + assert_eq!(expected.encode(), encoded_args); + Ok(()) + } + + #[test] + fn encode_primitive_vec_args() -> Result<()> { + let metadata = generate_metadata(); + let transcoder = ContractMessageTranscoder::new(&metadata); + + let encoded = transcoder.encode("primitive_vec_args", &["[1, 2]"])?; + + // encoded args follow the 4 byte selector + let encoded_args = &encoded[4..]; + + let expected = vec![1, 2]; + assert_eq!(expected.encode(), encoded_args); + Ok(()) + } + #[test] fn decode_primitive_return() -> Result<()> { let metadata = generate_metadata(); diff --git a/src/cmd/extrinsics/transcode/transcoder.rs b/src/cmd/extrinsics/transcode/transcoder.rs index 00e8d35c140255d02c64b1b63ab308fa0eba0481..591266de6542103bdb7c8de979ded1a3689e6d8f 100644 --- a/src/cmd/extrinsics/transcode/transcoder.rs +++ b/src/cmd/extrinsics/transcode/transcoder.rs @@ -134,12 +134,16 @@ mod tests { super::scon::{ self, Map, + Seq, Tuple, Value, }, *, }; - use crate::cmd::extrinsics::transcode; + use crate::cmd::extrinsics::{ + transcode, + transcode::scon::Bytes, + }; use scale::Encode; use scale_info::{ MetaType, @@ -605,6 +609,34 @@ mod tests { ) } + #[test] + fn transcode_account_id_custom_ss58_encoding_seq() -> Result<()> { + transcode_roundtrip::>( + r#"[ + 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY, + 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty, + ]"#, + Value::Seq(Seq::new( + vec![ + Value::Tuple( + Tuple::new( + Some("AccountId32"), + vec![Value::Bytes(Bytes::from_hex_string("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d").unwrap())] + ) + ), + Value::Tuple( + Tuple::new( + Some("AccountId32"), + vec![Value::Bytes(Bytes::from_hex_string("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48").unwrap())] + ) + ) + ] + .into_iter() + .collect(), + )), + ) + } + #[test] fn transcode_compact_primitives() -> Result<()> { transcode_roundtrip::>(r#"33"#, Value::UInt(33))?;