Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extrinsics: fix Vec<AccountId> args #519

Merged
merged 4 commits into from
Apr 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/cmd/extrinsics/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
}
}
Expand Down
59 changes: 23 additions & 36 deletions src/cmd/extrinsics/transcode/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<O: Output + Debug>(
&self,
type_def: &TypeDef<PortableForm>,
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<O: Output + Debug>(
&self,
fields: &[Field<PortableForm>],
Expand Down Expand Up @@ -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) => {
Expand Down
9 changes: 7 additions & 2 deletions src/cmd/extrinsics/transcode/env_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
// along with cargo-contract. If not, see <http://www.gnu.org/licenses/>.

use super::scon::Value;
use anyhow::Result;
use anyhow::{
Context,
Result,
};
use scale::{
Decode,
Encode,
Expand Down Expand Up @@ -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)
}
Expand Down
63 changes: 55 additions & 8 deletions src/cmd/extrinsics/transcode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand All @@ -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<AccountId>) {
let _ = account_ids;
}

#[ink(message)]
pub fn primitive_vec_args(&self, args: Vec<u32>) {
let _ = args;
}
}
}

Expand Down Expand Up @@ -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();
Expand Down
34 changes: 33 additions & 1 deletion src/cmd/extrinsics/transcode/transcoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -605,6 +609,34 @@ mod tests {
)
}

#[test]
fn transcode_account_id_custom_ss58_encoding_seq() -> Result<()> {
transcode_roundtrip::<Vec<sp_runtime::AccountId32>>(
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::<scale::Compact<u8>>(r#"33"#, Value::UInt(33))?;
Expand Down