From a3333cdb1fa572118fc2653b6ec2ee7764feba1a Mon Sep 17 00:00:00 2001 From: ascjones Date: Wed, 4 May 2022 12:50:31 +0100 Subject: [PATCH 1/8] WIP in hex literals --- src/cmd/extrinsics/transcode/decode.rs | 16 +++----- src/cmd/extrinsics/transcode/encode.rs | 32 +++++++++++++--- src/cmd/extrinsics/transcode/env_types.rs | 6 +-- src/cmd/extrinsics/transcode/mod.rs | 39 ++++++++++++++++++++ src/cmd/extrinsics/transcode/scon/display.rs | 8 ++-- src/cmd/extrinsics/transcode/scon/mod.rs | 23 +++++++----- src/cmd/extrinsics/transcode/scon/parse.rs | 11 +++--- src/cmd/extrinsics/transcode/transcoder.rs | 9 ++--- 8 files changed, 101 insertions(+), 43 deletions(-) diff --git a/src/cmd/extrinsics/transcode/decode.rs b/src/cmd/extrinsics/transcode/decode.rs index f22f061c..1654a744 100644 --- a/src/cmd/extrinsics/transcode/decode.rs +++ b/src/cmd/extrinsics/transcode/decode.rs @@ -91,18 +91,12 @@ impl<'a> Decoder<'a> { anyhow::anyhow!("Failed to find type with id '{}'", type_id) })?; - if *ty.type_def() == TypeDef::Primitive(TypeDefPrimitive::U8) { - let mut bytes = vec![0u8; len]; - input.read(&mut bytes)?; - Ok(Value::Bytes(bytes.into())) - } else { - let mut elems = Vec::new(); - while elems.len() < len as usize { - let elem = self.decode_type(type_id, ty, input)?; - elems.push(elem) - } - Ok(Value::Seq(elems.into())) + let mut elems = Vec::new(); + while elems.len() < len as usize { + let elem = self.decode_type(type_id, ty, input)?; + elems.push(elem) } + Ok(Value::Seq(elems.into())) } fn decode_type( diff --git a/src/cmd/extrinsics/transcode/encode.rs b/src/cmd/extrinsics/transcode/encode.rs index aa7d5c22..fdd50f18 100644 --- a/src/cmd/extrinsics/transcode/encode.rs +++ b/src/cmd/extrinsics/transcode/encode.rs @@ -248,11 +248,11 @@ impl<'a> Encoder<'a> { self.encode(ty.id(), value, output)?; } } - Value::Bytes(bytes) => { + Value::Hex(hex) => { if encode_len { - Compact(bytes.bytes().len() as u32).encode_to(output); + Compact(hex.bytes().len() as u32).encode_to(output); } - for byte in bytes.bytes() { + for byte in hex.bytes() { output.push_byte(*byte); } } @@ -410,7 +410,7 @@ impl<'a> Encoder<'a> { fn uint_from_value(value: &Value, expected: &str) -> Result where - T: TryFrom + FromStr, + T: TryFrom + TryFromHex + FromStr, >::Error: Error + Send + Sync + 'static, ::Err: Error + Send + Sync + 'static, { @@ -424,6 +424,10 @@ where let uint = T::from_str(&sanitized)?; Ok(uint) } + Value::Hex(hex) => { + let uint = T::try_from_hex(hex.as_str())?; + Ok(uint) + } _ => { Err(anyhow::anyhow!( "Expected a {} or a String value, got {}", @@ -436,7 +440,7 @@ where fn encode_uint(value: &Value, expected: &str, output: &mut O) -> Result<()> where - T: TryFrom + FromStr + Encode, + T: TryFrom + TryFromHex + FromStr + Encode, >::Error: Error + Send + Sync + 'static, ::Err: Error + Send + Sync + 'static, O: Output, @@ -479,3 +483,21 @@ where int.encode_to(output); Ok(()) } + +/// Attempt to instantiate a type from its little-endian bytes representation. +pub trait TryFromHex: Sized { + /// Create a new instance from the little-endian bytes representation. + fn try_from_hex(hex: &str) -> Result; +} + +macro_rules! impl_try_from_hex { + ( $($ty:ident),* ) => { $( + impl TryFromHex for $ty { + fn try_from_hex(hex: &str) -> Result { + $ty::from_str_radix(hex, 16).map_err(Into::into) + } + } + )* } +} + +impl_try_from_hex!(u8, u16, u32, u64, u128); \ No newline at end of file diff --git a/src/cmd/extrinsics/transcode/env_types.rs b/src/cmd/extrinsics/transcode/env_types.rs index 7e526569..5cb39ea7 100644 --- a/src/cmd/extrinsics/transcode/env_types.rs +++ b/src/cmd/extrinsics/transcode/env_types.rs @@ -161,9 +161,9 @@ impl CustomTypeTranscoder for AccountId { ) })? } - Value::Bytes(bytes) => { - AccountId32::try_from(bytes.bytes()).map_err(|_| { - anyhow::anyhow!("Error converting bytes `{:?}` to AccountId", bytes) + Value::Hex(hex) => { + AccountId32::try_from(hex.bytes()).map_err(|_| { + anyhow::anyhow!("Error converting hex bytes `{:?}` to AccountId", hex.bytes()) })? } _ => { diff --git a/src/cmd/extrinsics/transcode/mod.rs b/src/cmd/extrinsics/transcode/mod.rs index daf95b16..ce612ff6 100644 --- a/src/cmd/extrinsics/transcode/mod.rs +++ b/src/cmd/extrinsics/transcode/mod.rs @@ -398,6 +398,15 @@ mod tests { pub fn primitive_vec_args(&self, args: Vec) { let _ = args; } + + #[ink(message)] + pub fn uint_args(&self, _u8: u8, _u16: u16, _u32: u32, _u64: u64, _u128: u128) { + } + + #[ink(message)] + pub fn uint_array_args(&self, arr: [u8; 4]) { + let _ = arr; + } } } @@ -489,6 +498,36 @@ mod tests { Ok(()) } + #[test] + fn encode_uint_hex_literals() -> Result<()> { + let metadata = generate_metadata(); + let transcoder = ContractMessageTranscoder::new(&metadata); + + let encoded = transcoder.encode("uint_args", &["0x00", "0xDEAD"])?; // "0xDEADBEEF", "0xDEADBEEF12345678", "0xDEADBEEF0123456789ABCDEF01234567"])?; + + // encoded args follow the 4 byte selector + let encoded_args = &encoded[4..]; + + let expected = (0x00u8, 0xDEADu16); // 0xDEADBEEFu32, 0xDEADBEEF12345678u64, 0xDEADBEEF0123456789ABCDEF01234567u128); + assert_eq!(expected.encode(), encoded_args); + Ok(()) + } + + #[test] + fn encode_uint_arr_hex_literals() -> Result<()> { + let metadata = generate_metadata(); + let transcoder = ContractMessageTranscoder::new(&metadata); + + let encoded = transcoder.encode("uint_array_args", &["[0xDE, 0xAD, 0xBE, 0xEF]"])?; + + // encoded args follow the 4 byte selector + let encoded_args = &encoded[4..]; + + let expected: [u8; 4] = [0xDE, 0xAD, 0xBE, 0xEF]; + assert_eq!(expected.encode(), encoded_args); + Ok(()) + } + #[test] fn decode_primitive_return() -> Result<()> { let metadata = generate_metadata(); diff --git a/src/cmd/extrinsics/transcode/scon/display.rs b/src/cmd/extrinsics/transcode/scon/display.rs index 8ccaf8e3..499634bf 100644 --- a/src/cmd/extrinsics/transcode/scon/display.rs +++ b/src/cmd/extrinsics/transcode/scon/display.rs @@ -15,7 +15,7 @@ // along with cargo-contract. If not, see . use super::{ - Bytes, + Hex, Map, Seq, Tuple, @@ -43,7 +43,7 @@ impl<'a> Debug for DisplayValue<'a> { Value::Tuple(tuple) => ::fmt(&DisplayTuple(tuple), f), Value::String(string) => ::fmt(string, f), Value::Seq(seq) => ::fmt(&DisplaySeq(seq), f), - Value::Bytes(bytes) => ::fmt(bytes, f), + Value::Hex(hex) => ::fmt(hex, f), Value::Literal(literal) => ::fmt(literal, f), Value::Unit => write!(f, "()"), } @@ -107,13 +107,13 @@ impl<'a> Debug for DisplaySeq<'a> { } } -impl Debug for Bytes { +impl Debug for Hex { fn fmt(&self, f: &mut Formatter<'_>) -> Result { write!(f, "{:#x}", self) } } -impl LowerHex for Bytes { +impl LowerHex for Hex { fn fmt(&self, f: &mut Formatter<'_>) -> Result { if f.alternate() { write!(f, "0x{}", hex::encode(&self.bytes)) diff --git a/src/cmd/extrinsics/transcode/scon/mod.rs b/src/cmd/extrinsics/transcode/scon/mod.rs index 66b45ca2..e0c48aba 100644 --- a/src/cmd/extrinsics/transcode/scon/mod.rs +++ b/src/cmd/extrinsics/transcode/scon/mod.rs @@ -35,7 +35,9 @@ use std::{ Index, IndexMut, }, + str::FromStr, }; +use crate::util; pub use self::parse::parse_value; @@ -49,7 +51,7 @@ pub enum Value { Tuple(Tuple), String(String), Seq(Seq), - Bytes(Bytes), + Hex(Hex), Literal(String), Unit, } @@ -199,20 +201,23 @@ impl Seq { } #[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct Bytes { +pub struct Hex { + s: String, bytes: Vec, } -impl From> for Bytes { - fn from(bytes: Vec) -> Self { - Self { bytes } +impl FromStr for Hex { + type Err = hex::FromHexError; + + fn from_str(s: &str) -> Result { + let bytes = util::decode_hex(s)?; + Ok(Self { s: s.to_string(), bytes }) } } -impl Bytes { - pub fn from_hex_string(s: &str) -> Result { - let bytes = crate::util::decode_hex(s)?; - Ok(Self { bytes }) +impl Hex { + pub fn as_str(&self) -> &str { + &self.s } pub fn bytes(&self) -> &[u8] { diff --git a/src/cmd/extrinsics/transcode/scon/parse.rs b/src/cmd/extrinsics/transcode/scon/parse.rs index 2e6ae484..33468d74 100644 --- a/src/cmd/extrinsics/transcode/scon/parse.rs +++ b/src/cmd/extrinsics/transcode/scon/parse.rs @@ -15,11 +15,12 @@ // along with cargo-contract. If not, see . use super::{ - Bytes, + Hex, Map, Tuple, Value, }; +use std::str::FromStr as _; use escape8259::unescape; use nom::{ branch::alt, @@ -64,7 +65,7 @@ pub fn parse_value(input: &str) -> anyhow::Result { fn scon_value(input: &str) -> IResult<&str, Value, ErrorTree<&str>> { ws(alt(( scon_unit, - scon_bytes, + scon_hex, scon_seq, scon_tuple, scon_map, @@ -221,12 +222,12 @@ fn scon_map(input: &str) -> IResult<&str, Value, ErrorTree<&str>> { .parse(input) } -fn scon_bytes(input: &str) -> IResult<&str, Value, ErrorTree<&str>> { +fn scon_hex(input: &str) -> IResult<&str, Value, ErrorTree<&str>> { tag("0x") .precedes(hex_digit1) .map_res::<_, _, hex::FromHexError>(|byte_str| { - let bytes = Bytes::from_hex_string(byte_str)?; - Ok(Value::Bytes(bytes)) + let hex = Hex::from_str(byte_str)?; + Ok(Value::Hex(hex)) }) .parse(input) } diff --git a/src/cmd/extrinsics/transcode/transcoder.rs b/src/cmd/extrinsics/transcode/transcoder.rs index 591266de..cae8c51d 100644 --- a/src/cmd/extrinsics/transcode/transcoder.rs +++ b/src/cmd/extrinsics/transcode/transcoder.rs @@ -140,10 +140,7 @@ mod tests { }, *, }; - use crate::cmd::extrinsics::{ - transcode, - transcode::scon::Bytes, - }; + use crate::cmd::extrinsics::transcode; use scale::Encode; use scale_info::{ MetaType, @@ -621,13 +618,13 @@ mod tests { Value::Tuple( Tuple::new( Some("AccountId32"), - vec![Value::Bytes(Bytes::from_hex_string("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d").unwrap())] + vec![Value::Hex("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d".to_string())] ) ), Value::Tuple( Tuple::new( Some("AccountId32"), - vec![Value::Bytes(Bytes::from_hex_string("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48").unwrap())] + vec![Value::Hex("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48".unwrap())] ) ) ] -- GitLab From 0963092ef18fa44ba706b95de95786734943a9a4 Mon Sep 17 00:00:00 2001 From: ascjones Date: Wed, 4 May 2022 15:14:02 +0100 Subject: [PATCH 2/8] Convert bytes to seqs --- src/cmd/extrinsics/transcode/scon/parse.rs | 6 ++--- src/cmd/extrinsics/transcode/transcoder.rs | 27 +++++++++++----------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/cmd/extrinsics/transcode/scon/parse.rs b/src/cmd/extrinsics/transcode/scon/parse.rs index 33468d74..b8f98ae2 100644 --- a/src/cmd/extrinsics/transcode/scon/parse.rs +++ b/src/cmd/extrinsics/transcode/scon/parse.rs @@ -603,10 +603,10 @@ mod tests { #[test] fn test_bytes() { - assert_scon_value(r#"0x0000"#, Value::Bytes(vec![0u8; 2].into())); + assert_scon_value("0x0000", Value::Hex(Hex::from_str("0x0000").unwrap())); assert_scon_value( - r#"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"#, - Value::Bytes(vec![255u8; 23].into()), + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + Value::Hex(Hex::from_str("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF").unwrap()), ); } } diff --git a/src/cmd/extrinsics/transcode/transcoder.rs b/src/cmd/extrinsics/transcode/transcoder.rs index cae8c51d..6a9c60eb 100644 --- a/src/cmd/extrinsics/transcode/transcoder.rs +++ b/src/cmd/extrinsics/transcode/transcoder.rs @@ -23,7 +23,7 @@ use super::{ PathKey, TypesByPath, }, - scon::Value, + scon::{Value, Hex}, }; use anyhow::Result; @@ -35,6 +35,7 @@ use scale_info::{ use std::{ collections::HashMap, fmt::Debug, + str::FromStr, }; /// Encode strings to SCALE encoded output. @@ -261,15 +262,15 @@ mod tests { fn transcode_byte_array() -> Result<()> { transcode_roundtrip::<[u8; 2]>( r#"0x0000"#, - Value::Bytes(vec![0x00, 0x00].into()), + Value::Seq(vec![Value::UInt(0x00), Value::UInt(0x00)].into()), )?; transcode_roundtrip::<[u8; 4]>( r#"0xDEADBEEF"#, - Value::Bytes(vec![0xDE, 0xAD, 0xBE, 0xEF].into()), + Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), )?; transcode_roundtrip::<[u8; 4]>( r#"0xdeadbeef"#, - Value::Bytes(vec![0xDE, 0xAD, 0xBE, 0xEF].into()), + Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), ) } @@ -318,7 +319,7 @@ mod tests { vec![ Value::UInt(1), Value::String("ink!".to_string()), - Value::Bytes(vec![0xDE, 0xAD, 0xBE, 0xEF].into()), + Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), ], )), ) @@ -347,7 +348,7 @@ mod tests { ), ( Value::String("c".to_string()), - Value::Bytes(vec![0xDE, 0xAD, 0xBE, 0xEF].into()), + Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), ), ( Value::String("d".to_string()), @@ -361,7 +362,7 @@ mod tests { ), ( Value::String("c".to_string()), - Value::Bytes(vec![0xDE, 0xAD, 0xBE, 0xEF].into()), + Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), ), ( Value::String("d".to_string()), @@ -436,7 +437,7 @@ mod tests { ), ( Value::String("c".to_string()), - Value::Bytes(vec![0xDE, 0xAD, 0xBE, 0xEF].into()), + Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), ), ] .into_iter() @@ -458,7 +459,7 @@ mod tests { vec![ Value::UInt(1), Value::String("ink!".to_string()), - Value::Bytes(vec![0xDE, 0xAD, 0xBE, 0xEF].into()), + Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), ], )), ) @@ -474,7 +475,7 @@ mod tests { r#"0xDEADBEEF"#, Value::Tuple(Tuple::new( Some("S"), - vec![Value::Bytes(vec![0xDE, 0xAD, 0xBE, 0xEF].into())], + vec![Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into())], )), ) } @@ -485,7 +486,7 @@ mod tests { r#"0xDEADBEEF"#, Value::Tuple(Tuple::new( None, - vec![Value::Bytes(vec![0xDE, 0xAD, 0xBE, 0xEF].into())], + vec![Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into())], )), ) } @@ -618,13 +619,13 @@ mod tests { Value::Tuple( Tuple::new( Some("AccountId32"), - vec![Value::Hex("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d".to_string())] + vec![Value::Hex(Hex::from_str("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d")?)] ) ), Value::Tuple( Tuple::new( Some("AccountId32"), - vec![Value::Hex("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48".unwrap())] + vec![Value::Hex(Hex::from_str("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48")?)] ) ) ] -- GitLab From c72f103fae7e9fa5b9f5a7949f86bdfac0204d5b Mon Sep 17 00:00:00 2001 From: ascjones Date: Wed, 4 May 2022 15:14:22 +0100 Subject: [PATCH 3/8] Fmt --- src/cmd/extrinsics/transcode/encode.rs | 2 +- src/cmd/extrinsics/transcode/env_types.rs | 5 +- src/cmd/extrinsics/transcode/mod.rs | 12 ++- src/cmd/extrinsics/transcode/scon/mod.rs | 7 +- src/cmd/extrinsics/transcode/scon/parse.rs | 7 +- src/cmd/extrinsics/transcode/transcoder.rs | 95 +++++++++++++++++++--- 6 files changed, 110 insertions(+), 18 deletions(-) diff --git a/src/cmd/extrinsics/transcode/encode.rs b/src/cmd/extrinsics/transcode/encode.rs index fdd50f18..86fdc833 100644 --- a/src/cmd/extrinsics/transcode/encode.rs +++ b/src/cmd/extrinsics/transcode/encode.rs @@ -500,4 +500,4 @@ macro_rules! impl_try_from_hex { )* } } -impl_try_from_hex!(u8, u16, u32, u64, u128); \ No newline at end of file +impl_try_from_hex!(u8, u16, u32, u64, u128); diff --git a/src/cmd/extrinsics/transcode/env_types.rs b/src/cmd/extrinsics/transcode/env_types.rs index 5cb39ea7..7ecaad99 100644 --- a/src/cmd/extrinsics/transcode/env_types.rs +++ b/src/cmd/extrinsics/transcode/env_types.rs @@ -163,7 +163,10 @@ impl CustomTypeTranscoder for AccountId { } Value::Hex(hex) => { AccountId32::try_from(hex.bytes()).map_err(|_| { - anyhow::anyhow!("Error converting hex bytes `{:?}` to AccountId", hex.bytes()) + anyhow::anyhow!( + "Error converting hex bytes `{:?}` to AccountId", + hex.bytes() + ) })? } _ => { diff --git a/src/cmd/extrinsics/transcode/mod.rs b/src/cmd/extrinsics/transcode/mod.rs index ce612ff6..7a87a1cb 100644 --- a/src/cmd/extrinsics/transcode/mod.rs +++ b/src/cmd/extrinsics/transcode/mod.rs @@ -400,7 +400,14 @@ mod tests { } #[ink(message)] - pub fn uint_args(&self, _u8: u8, _u16: u16, _u32: u32, _u64: u64, _u128: u128) { + pub fn uint_args( + &self, + _u8: u8, + _u16: u16, + _u32: u32, + _u64: u64, + _u128: u128, + ) { } #[ink(message)] @@ -518,7 +525,8 @@ mod tests { let metadata = generate_metadata(); let transcoder = ContractMessageTranscoder::new(&metadata); - let encoded = transcoder.encode("uint_array_args", &["[0xDE, 0xAD, 0xBE, 0xEF]"])?; + let encoded = + transcoder.encode("uint_array_args", &["[0xDE, 0xAD, 0xBE, 0xEF]"])?; // encoded args follow the 4 byte selector let encoded_args = &encoded[4..]; diff --git a/src/cmd/extrinsics/transcode/scon/mod.rs b/src/cmd/extrinsics/transcode/scon/mod.rs index e0c48aba..4db6e1ff 100644 --- a/src/cmd/extrinsics/transcode/scon/mod.rs +++ b/src/cmd/extrinsics/transcode/scon/mod.rs @@ -21,6 +21,7 @@ mod parse; use indexmap::IndexMap; +use crate::util; use std::{ cmp::{ Eq, @@ -37,7 +38,6 @@ use std::{ }, str::FromStr, }; -use crate::util; pub use self::parse::parse_value; @@ -211,7 +211,10 @@ impl FromStr for Hex { fn from_str(s: &str) -> Result { let bytes = util::decode_hex(s)?; - Ok(Self { s: s.to_string(), bytes }) + Ok(Self { + s: s.to_string(), + bytes, + }) } } diff --git a/src/cmd/extrinsics/transcode/scon/parse.rs b/src/cmd/extrinsics/transcode/scon/parse.rs index b8f98ae2..1df83166 100644 --- a/src/cmd/extrinsics/transcode/scon/parse.rs +++ b/src/cmd/extrinsics/transcode/scon/parse.rs @@ -20,7 +20,6 @@ use super::{ Tuple, Value, }; -use std::str::FromStr as _; use escape8259::unescape; use nom::{ branch::alt, @@ -54,6 +53,7 @@ use nom_supreme::{ error::ErrorTree, ParserExt, }; +use std::str::FromStr as _; /// Attempt to parse a SCON value pub fn parse_value(input: &str) -> anyhow::Result { @@ -606,7 +606,10 @@ mod tests { assert_scon_value("0x0000", Value::Hex(Hex::from_str("0x0000").unwrap())); assert_scon_value( "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - Value::Hex(Hex::from_str("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF").unwrap()), + Value::Hex( + Hex::from_str("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") + .unwrap(), + ), ); } } diff --git a/src/cmd/extrinsics/transcode/transcoder.rs b/src/cmd/extrinsics/transcode/transcoder.rs index 6a9c60eb..85ef3a93 100644 --- a/src/cmd/extrinsics/transcode/transcoder.rs +++ b/src/cmd/extrinsics/transcode/transcoder.rs @@ -23,7 +23,10 @@ use super::{ PathKey, TypesByPath, }, - scon::{Value, Hex}, + scon::{ + Hex, + Value, + }, }; use anyhow::Result; @@ -266,11 +269,27 @@ mod tests { )?; transcode_roundtrip::<[u8; 4]>( r#"0xDEADBEEF"#, - Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), + Value::Seq( + vec![ + Value::UInt(0xDE), + Value::UInt(0xAD), + Value::UInt(0xBE), + Value::UInt(0xEF), + ] + .into(), + ), )?; transcode_roundtrip::<[u8; 4]>( r#"0xdeadbeef"#, - Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), + Value::Seq( + vec![ + Value::UInt(0xDE), + Value::UInt(0xAD), + Value::UInt(0xBE), + Value::UInt(0xEF), + ] + .into(), + ), ) } @@ -319,7 +338,15 @@ mod tests { vec![ Value::UInt(1), Value::String("ink!".to_string()), - Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), + Value::Seq( + vec![ + Value::UInt(0xDE), + Value::UInt(0xAD), + Value::UInt(0xBE), + Value::UInt(0xEF), + ] + .into(), + ), ], )), ) @@ -348,7 +375,15 @@ mod tests { ), ( Value::String("c".to_string()), - Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), + Value::Seq( + vec![ + Value::UInt(0xDE), + Value::UInt(0xAD), + Value::UInt(0xBE), + Value::UInt(0xEF), + ] + .into(), + ), ), ( Value::String("d".to_string()), @@ -362,7 +397,15 @@ mod tests { ), ( Value::String("c".to_string()), - Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), + Value::Seq( + vec![ + Value::UInt(0xDE), + Value::UInt(0xAD), + Value::UInt(0xBE), + Value::UInt(0xEF), + ] + .into(), + ), ), ( Value::String("d".to_string()), @@ -437,7 +480,15 @@ mod tests { ), ( Value::String("c".to_string()), - Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), + Value::Seq( + vec![ + Value::UInt(0xDE), + Value::UInt(0xAD), + Value::UInt(0xBE), + Value::UInt(0xEF), + ] + .into(), + ), ), ] .into_iter() @@ -459,7 +510,15 @@ mod tests { vec![ Value::UInt(1), Value::String("ink!".to_string()), - Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into()), + Value::Seq( + vec![ + Value::UInt(0xDE), + Value::UInt(0xAD), + Value::UInt(0xBE), + Value::UInt(0xEF), + ] + .into(), + ), ], )), ) @@ -475,7 +534,15 @@ mod tests { r#"0xDEADBEEF"#, Value::Tuple(Tuple::new( Some("S"), - vec![Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into())], + vec![Value::Seq( + vec![ + Value::UInt(0xDE), + Value::UInt(0xAD), + Value::UInt(0xBE), + Value::UInt(0xEF), + ] + .into(), + )], )), ) } @@ -486,7 +553,15 @@ mod tests { r#"0xDEADBEEF"#, Value::Tuple(Tuple::new( None, - vec![Value::Seq(vec![Value::UInt(0xDE), Value::UInt(0xAD), Value::UInt(0xBE), Value::UInt(0xEF)].into())], + vec![Value::Seq( + vec![ + Value::UInt(0xDE), + Value::UInt(0xAD), + Value::UInt(0xBE), + Value::UInt(0xEF), + ] + .into(), + )], )), ) } -- GitLab From 30c4b8b1fbb5213369d34a75e7301be397c5cd7b Mon Sep 17 00:00:00 2001 From: ascjones Date: Wed, 4 May 2022 15:23:12 +0100 Subject: [PATCH 4/8] Warnings --- src/cmd/extrinsics/transcode/transcoder.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/cmd/extrinsics/transcode/transcoder.rs b/src/cmd/extrinsics/transcode/transcoder.rs index 85ef3a93..dc0b84fa 100644 --- a/src/cmd/extrinsics/transcode/transcoder.rs +++ b/src/cmd/extrinsics/transcode/transcoder.rs @@ -23,10 +23,7 @@ use super::{ PathKey, TypesByPath, }, - scon::{ - Hex, - Value, - }, + scon::Value, }; use anyhow::Result; @@ -38,7 +35,6 @@ use scale_info::{ use std::{ collections::HashMap, fmt::Debug, - str::FromStr, }; /// Encode strings to SCALE encoded output. -- GitLab From 5cc84e9ab17ef024953c037c8adec802a6920cbd Mon Sep 17 00:00:00 2001 From: ascjones Date: Wed, 4 May 2022 15:37:55 +0100 Subject: [PATCH 5/8] Add transcode hex literal test --- src/cmd/extrinsics/transcode/mod.rs | 19 +++++++++++++++-- src/cmd/extrinsics/transcode/transcoder.rs | 24 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/cmd/extrinsics/transcode/mod.rs b/src/cmd/extrinsics/transcode/mod.rs index 7a87a1cb..bac8be42 100644 --- a/src/cmd/extrinsics/transcode/mod.rs +++ b/src/cmd/extrinsics/transcode/mod.rs @@ -510,12 +510,27 @@ mod tests { let metadata = generate_metadata(); let transcoder = ContractMessageTranscoder::new(&metadata); - let encoded = transcoder.encode("uint_args", &["0x00", "0xDEAD"])?; // "0xDEADBEEF", "0xDEADBEEF12345678", "0xDEADBEEF0123456789ABCDEF01234567"])?; + let encoded = transcoder.encode( + "uint_args", + &[ + "0x00", + "0xDEAD", + "0xDEADBEEF", + "0xDEADBEEF12345678", + "0xDEADBEEF0123456789ABCDEF01234567", + ], + )?; // encoded args follow the 4 byte selector let encoded_args = &encoded[4..]; - let expected = (0x00u8, 0xDEADu16); // 0xDEADBEEFu32, 0xDEADBEEF12345678u64, 0xDEADBEEF0123456789ABCDEF01234567u128); + let expected = ( + 0x00u8, + 0xDEADu16, + 0xDEADBEEFu32, + 0xDEADBEEF12345678u64, + 0xDEADBEEF0123456789ABCDEF01234567u128, + ); assert_eq!(expected.encode(), encoded_args); Ok(()) } diff --git a/src/cmd/extrinsics/transcode/transcoder.rs b/src/cmd/extrinsics/transcode/transcoder.rs index dc0b84fa..a9d8ccf8 100644 --- a/src/cmd/extrinsics/transcode/transcoder.rs +++ b/src/cmd/extrinsics/transcode/transcoder.rs @@ -133,6 +133,7 @@ mod tests { use super::{ super::scon::{ self, + Hex, Map, Seq, Tuple, @@ -147,6 +148,7 @@ mod tests { Registry, TypeInfo, }; + use std::str::FromStr; fn registry_with_type() -> Result<(PortableRegistry, u32)> where @@ -747,4 +749,26 @@ mod tests { )), ) } + + #[test] + fn transcode_hex_literal_uints() -> Result<()> { + #[derive(scale::Encode, TypeInfo)] + struct S(u8, u16, u32, u64, u128); + + transcode_roundtrip::( + r#"S (0xDEu8, 0xDEADu16, 0xDEADBEEFu32, 0xDEADBEEF12345678u64, 0xDEADBEEF0123456789ABCDEF01234567u128)"#, + Value::Tuple(Tuple::new( + Some("S"), + vec![ + Value::Hex(Hex::from_str("0xDE")?), + Value::Hex(Hex::from_str("0xDEAD")?), + Value::Hex(Hex::from_str("0xDEADBEEF")?), + Value::Hex(Hex::from_str("0xDEADBEEF12345678")?), + Value::Hex(Hex::from_str("0xDEADBEEF0123456789ABCDEF01234567")?), + ] + .into_iter() + .collect(), + )), + ) + } } -- GitLab From 5a5c1159a5fc14f21b9dc1efda9d171f87d3630b Mon Sep 17 00:00:00 2001 From: ascjones Date: Wed, 4 May 2022 15:59:22 +0100 Subject: [PATCH 6/8] Fix Hex construction trim leading 0x --- src/cmd/extrinsics/transcode/scon/mod.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/cmd/extrinsics/transcode/scon/mod.rs b/src/cmd/extrinsics/transcode/scon/mod.rs index 4db6e1ff..85882c52 100644 --- a/src/cmd/extrinsics/transcode/scon/mod.rs +++ b/src/cmd/extrinsics/transcode/scon/mod.rs @@ -210,11 +210,9 @@ impl FromStr for Hex { type Err = hex::FromHexError; fn from_str(s: &str) -> Result { - let bytes = util::decode_hex(s)?; - Ok(Self { - s: s.to_string(), - bytes, - }) + let s = s.trim_start_matches("0x").to_string(); + let bytes = util::decode_hex(&s)?; + Ok(Self { s, bytes }) } } -- GitLab From 2a26e1a29346c6491cd78048ec27d1b977eb2ad7 Mon Sep 17 00:00:00 2001 From: ascjones Date: Wed, 4 May 2022 16:07:38 +0100 Subject: [PATCH 7/8] Fix custom account id transcode test --- src/cmd/extrinsics/transcode/transcoder.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/cmd/extrinsics/transcode/transcoder.rs b/src/cmd/extrinsics/transcode/transcoder.rs index a9d8ccf8..7f2d5b18 100644 --- a/src/cmd/extrinsics/transcode/transcoder.rs +++ b/src/cmd/extrinsics/transcode/transcoder.rs @@ -682,6 +682,12 @@ mod tests { #[test] fn transcode_account_id_custom_ss58_encoding_seq() -> Result<()> { + let hex_to_bytes = |hex: &str| -> Result { + let hex = Hex::from_str(hex)?; + let values = hex.bytes().iter().map(|b| Value::UInt((*b).into())); + Ok(Value::Seq(Seq::new(values.collect()))) + }; + transcode_roundtrip::>( r#"[ 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY, @@ -692,13 +698,13 @@ mod tests { Value::Tuple( Tuple::new( Some("AccountId32"), - vec![Value::Hex(Hex::from_str("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d")?)] + vec![hex_to_bytes("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d")?] ) ), Value::Tuple( Tuple::new( Some("AccountId32"), - vec![Value::Hex(Hex::from_str("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48")?)] + vec![hex_to_bytes("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48")?] ) ) ] -- GitLab From e63cbe2e0bee269060218c0ea1512350df9bd4b4 Mon Sep 17 00:00:00 2001 From: ascjones Date: Wed, 4 May 2022 16:10:47 +0100 Subject: [PATCH 8/8] Fix uint hex literal transcoder test --- src/cmd/extrinsics/transcode/transcoder.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cmd/extrinsics/transcode/transcoder.rs b/src/cmd/extrinsics/transcode/transcoder.rs index 7f2d5b18..c575c442 100644 --- a/src/cmd/extrinsics/transcode/transcoder.rs +++ b/src/cmd/extrinsics/transcode/transcoder.rs @@ -762,15 +762,15 @@ mod tests { struct S(u8, u16, u32, u64, u128); transcode_roundtrip::( - r#"S (0xDEu8, 0xDEADu16, 0xDEADBEEFu32, 0xDEADBEEF12345678u64, 0xDEADBEEF0123456789ABCDEF01234567u128)"#, + r#"S (0xDE, 0xDEAD, 0xDEADBEEF, 0xDEADBEEF12345678, 0xDEADBEEF0123456789ABCDEF01234567)"#, Value::Tuple(Tuple::new( Some("S"), vec![ - Value::Hex(Hex::from_str("0xDE")?), - Value::Hex(Hex::from_str("0xDEAD")?), - Value::Hex(Hex::from_str("0xDEADBEEF")?), - Value::Hex(Hex::from_str("0xDEADBEEF12345678")?), - Value::Hex(Hex::from_str("0xDEADBEEF0123456789ABCDEF01234567")?), + Value::UInt(0xDE), + Value::UInt(0xDEAD), + Value::UInt(0xDEADBEEF), + Value::UInt(0xDEADBEEF12345678), + Value::UInt(0xDEADBEEF0123456789ABCDEF01234567), ] .into_iter() .collect(), -- GitLab