git.delta.rocks / unique-network / refs/commits / 7eec33a3cc63

difftreelog

fix AbiRead implementations

Trubnikov Sergey2022-11-16parent: #b3e1096.patch.diff
in: master

5 files changed

modifiedcrates/evm-coder/procedural/src/abi_derive.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive.rs
+++ b/crates/evm-coder/procedural/src/abi_derive.rs
@@ -1,7 +1,6 @@
 use quote::quote;
 
 pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
-	// dbg!(ast);
 	let name = &ast.ident;
 	let (is_named_fields, field_names, field_types, params_count) = match &ast.data {
 		syn::Data::Struct(ds) => match ds.fields {
@@ -31,7 +30,7 @@
 	let abi_type = impl_abi_type(name, field_types.clone());
 	let abi_read = impl_abi_read(name, is_named_fields, field_names.clone(), field_types);
 	let abi_write = impl_abi_write(name, is_named_fields, params_count, field_names);
-	println!("{}", abi_write);
+
 	Ok(quote! {
 		#can_be_plcaed_in_vec
 		#abi_type
@@ -112,14 +111,19 @@
 	quote!(
 		impl ::evm_coder::abi::AbiRead for #name {
 			fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {
-				let size = if !<Self as ::evm_coder::abi::AbiType>::is_dynamic() {
+				let is_dynamic = <Self as ::evm_coder::abi::AbiType>::is_dynamic();
+				let size = if !is_dynamic {
 					Some(<Self as ::evm_coder::abi::AbiType>::size())
 				} else {
 					None
 				};
 				let mut subresult = reader.subresult(size)?;
 				#(
-					let #field_names = <#field_types as ::evm_coder::abi::AbiRead>::abi_read(&mut subresult)?;
+					let #field_names = {
+						let value = <#field_types as ::evm_coder::abi::AbiRead>::abi_read(&mut subresult)?;
+						if !is_dynamic {subresult.seek(<#field_types as ::evm_coder::abi::AbiType>::size())};
+						value
+					};
 				)*
 
 				#struct_constructor
modifiedcrates/evm-coder/src/abi/impls.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/impls.rs
+++ b/crates/evm-coder/src/abi/impls.rs
@@ -92,7 +92,7 @@
 	}
 }
 
-impl<R: AbiRead + sealed::CanBePlacedInVec> AbiRead for Vec<R> {
+impl<R: AbiType + AbiRead + sealed::CanBePlacedInVec> AbiRead for Vec<R> {
 	fn abi_read(reader: &mut AbiReader) -> Result<Vec<R>> {
 		let mut sub = reader.subresult(None)?;
 		let size = sub.uint32()? as usize;
@@ -100,6 +100,9 @@
 		let mut out = Vec::with_capacity(size);
 		for _ in 0..size {
 			out.push(<R>::abi_read(&mut sub)?);
+			if !<R>::is_dynamic() {
+				sub.subresult_offset += <R>::size()
+			};
 		}
 		Ok(out)
 	}
@@ -295,14 +298,19 @@
 
 		impl<$($ident),+> AbiRead for ($($ident,)+)
 		where
-			$($ident: AbiRead,)+
+			$($ident: AbiRead + AbiType,)+
 			($($ident,)+): AbiType,
 		{
 			fn abi_read(reader: &mut AbiReader) -> Result<($($ident,)+)> {
-				let size = if !<($($ident,)+)>::is_dynamic() { Some(<($($ident,)+)>::size()) } else { None };
+				let is_dynamic = <($($ident,)+)>::is_dynamic();
+				let size = if !is_dynamic { Some(<($($ident,)+)>::size()) } else { None };
 				let mut subresult = reader.subresult(size)?;
 				Ok((
-					$(<$ident>::abi_read(&mut subresult)?,)+
+					$({
+						let value = <$ident>::abi_read(&mut subresult)?;
+						if !is_dynamic {subresult.seek(<$ident as AbiType>::size())};
+						value
+					},)+
 				))
 			}
 		}
modifiedcrates/evm-coder/src/abi/mod.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/mod.rs
+++ b/crates/evm-coder/src/abi/mod.rs
@@ -75,19 +75,19 @@
 		buf: &[u8],
 		offset: usize,
 		pad_start: usize,
-		pad_size: usize,
+		pad_end: usize,
 		block_start: usize,
-		block_size: usize,
+		block_end: usize,
 	) -> Result<[u8; S]> {
 		if buf.len() - offset < ABI_ALIGNMENT {
 			return Err(Error::Error(ExitError::OutOfOffset));
 		}
 		let mut block = [0; S];
-		let is_pad_zeroed = buf[pad_start..pad_size].iter().all(|&v| v == 0);
+		let is_pad_zeroed = buf[pad_start..pad_end].iter().all(|&v| v == 0);
 		if !is_pad_zeroed {
 			return Err(Error::Error(ExitError::InvalidRange));
 		}
-		block.copy_from_slice(&buf[block_start..block_size]);
+		block.copy_from_slice(&buf[block_start..block_end]);
 		Ok(block)
 	}
 
@@ -190,7 +190,6 @@
 		let subresult_offset = self.subresult_offset;
 		let offset = if let Some(size) = size {
 			self.offset += size;
-			self.subresult_offset += size;
 			0
 		} else {
 			self.uint32()? as usize
@@ -208,6 +207,11 @@
 		})
 	}
 
+	/// Notify about readed data portion.
+	pub fn seek(&mut self, size: usize) {
+		self.subresult_offset += size;
+	}
+
 	/// Is this parser reached end of buffer?
 	pub fn is_finished(&self) -> bool {
 		self.buf.len() == self.offset
modifiedcrates/evm-coder/src/abi/test.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/test.rs
+++ b/crates/evm-coder/src/abi/test.rs
@@ -137,6 +137,27 @@
 }
 
 #[test]
+fn encode_decode_vec_tuple_uint8_uint8() {
+	test_impl::<Vec<(u8, u8)>>(
+		0xdeadbeef,
+		vec![(0x0A, 0x0B), (0x0C, 0x0D), (0x0E, 0x0F)],
+		&hex!(
+			"
+                deadbeef
+                0000000000000000000000000000000000000000000000000000000000000020
+                0000000000000000000000000000000000000000000000000000000000000003
+                000000000000000000000000000000000000000000000000000000000000000a
+                000000000000000000000000000000000000000000000000000000000000000b
+                000000000000000000000000000000000000000000000000000000000000000c
+                000000000000000000000000000000000000000000000000000000000000000d
+                000000000000000000000000000000000000000000000000000000000000000e
+                000000000000000000000000000000000000000000000000000000000000000f
+            "
+		),
+	);
+}
+
+#[test]
 fn encode_decode_vec_tuple_uint256_string() {
 	test_impl::<Vec<(uint256, string)>>(
         0xdeadbeef,
@@ -332,3 +353,175 @@
 		),
 	);
 }
+
+#[test]
+// #[ignore = "reason"]
+fn encode_decode_tuple0_tuple1_uint8_tuple1_string_bytes_tuple1_uint8_bytes() {
+	let int = 0xff;
+	let by = bytes(vec![0x11, 0x22, 0x33]);
+	let string = "some string".to_string();
+
+	test_impl::<((u8,), (String, bytes), (u8, bytes))>(
+		0xdeadbeef,
+		((int,), (string.clone(), by.clone()), (int, by)),
+		&hex!(
+			"
+                deadbeef
+                0000000000000000000000000000000000000000000000000000000000000020
+                00000000000000000000000000000000000000000000000000000000000000ff
+                0000000000000000000000000000000000000000000000000000000000000060
+                0000000000000000000000000000000000000000000000000000000000000120
+                0000000000000000000000000000000000000000000000000000000000000040
+                0000000000000000000000000000000000000000000000000000000000000080
+                000000000000000000000000000000000000000000000000000000000000000b
+                736f6d6520737472696e67000000000000000000000000000000000000000000
+                0000000000000000000000000000000000000000000000000000000000000003
+                1122330000000000000000000000000000000000000000000000000000000000
+                00000000000000000000000000000000000000000000000000000000000000ff
+                0000000000000000000000000000000000000000000000000000000000000040
+                0000000000000000000000000000000000000000000000000000000000000003
+                1122330000000000000000000000000000000000000000000000000000000000
+            "
+		),
+	);
+}
+
+#[test]
+fn encode_decode_tuple0_tuple1_uint8_tuple1_uint8_uint8_tuple1_uint8_uint8() {
+	test_impl::<((u8,), (u8, u8), (u8, u8))>(
+		0xdeadbeef,
+		((43,), (44, 45), (46, 47)),
+		&hex!(
+			"
+                deadbeef
+                000000000000000000000000000000000000000000000000000000000000002b
+                000000000000000000000000000000000000000000000000000000000000002c
+                000000000000000000000000000000000000000000000000000000000000002d
+                000000000000000000000000000000000000000000000000000000000000002e
+                000000000000000000000000000000000000000000000000000000000000002f
+            "
+		),
+	);
+}
+
+#[test]
+fn encode_decode_tuple0_tuple1_uint8_tuple1_uint8() {
+	test_impl::<((u8,), (u8,))>(
+		0xdeadbeef,
+		((43,), (44,)),
+		&hex!(
+			"
+                deadbeef
+                000000000000000000000000000000000000000000000000000000000000002b
+                000000000000000000000000000000000000000000000000000000000000002c
+            "
+		),
+	);
+}
+
+#[test]
+fn encode_decode_tuple0_tuple1_uint8_uint8() {
+	test_impl::<((u8, u8),)>(
+		0xdeadbeef,
+		((43, 44),),
+		&hex!(
+			"
+                deadbeef
+                000000000000000000000000000000000000000000000000000000000000002b
+                000000000000000000000000000000000000000000000000000000000000002c
+            "
+		),
+	);
+}
+
+#[test]
+fn encode_decode_tuple_uint8_uint8() {
+	test_impl::<(u8, u8)>(
+		0xdeadbeef,
+		(43, 44),
+		&hex!(
+			"
+                deadbeef
+                000000000000000000000000000000000000000000000000000000000000002b
+                000000000000000000000000000000000000000000000000000000000000002c
+            "
+		),
+	);
+}
+
+#[test]
+fn encode_decode_tuple0_tuple1_string() {
+	test_impl::<((String,),)>(
+		0xdeadbeef,
+		(("some string".to_string(),),),
+		&hex!(
+			"
+                deadbeef
+                0000000000000000000000000000000000000000000000000000000000000020
+                0000000000000000000000000000000000000000000000000000000000000020
+                0000000000000000000000000000000000000000000000000000000000000020
+                000000000000000000000000000000000000000000000000000000000000000b
+                736f6d6520737472696e67000000000000000000000000000000000000000000
+            "
+		),
+	);
+}
+
+#[test]
+fn encode_decode_tuple0_tuple1_uint8_string() {
+	test_impl::<((u8, String),)>(
+		0xdeadbeef,
+		((0xff, "some string".to_string()),),
+		&hex!(
+			"
+                deadbeef
+                0000000000000000000000000000000000000000000000000000000000000020
+                0000000000000000000000000000000000000000000000000000000000000020
+                00000000000000000000000000000000000000000000000000000000000000ff
+                0000000000000000000000000000000000000000000000000000000000000040
+                000000000000000000000000000000000000000000000000000000000000000b
+                736f6d6520737472696e67000000000000000000000000000000000000000000
+            "
+		),
+	);
+}
+
+#[test]
+fn encode_decode_tuple0_tuple1_string_bytes() {
+	test_impl::<((String, bytes),)>(
+		0xdeadbeef,
+		(("some string".to_string(), bytes(vec![1, 2, 3])),),
+		&hex!(
+			"
+                deadbeef
+                0000000000000000000000000000000000000000000000000000000000000020
+                0000000000000000000000000000000000000000000000000000000000000020
+                0000000000000000000000000000000000000000000000000000000000000040
+                0000000000000000000000000000000000000000000000000000000000000080
+                000000000000000000000000000000000000000000000000000000000000000b
+                736f6d6520737472696e67000000000000000000000000000000000000000000
+                0000000000000000000000000000000000000000000000000000000000000003
+                0102030000000000000000000000000000000000000000000000000000000000
+            "
+		),
+	);
+}
+
+#[test]
+fn encode_decode_tuple0_tuple1_uint8_tuple1_string() {
+	test_impl::<((u8,), (String,))>(
+		0xdeadbeef,
+		((0xff,), ("some string".to_string(),)),
+		&hex!(
+			"
+                deadbeef
+                0000000000000000000000000000000000000000000000000000000000000020
+                00000000000000000000000000000000000000000000000000000000000000ff
+                0000000000000000000000000000000000000000000000000000000000000040
+                0000000000000000000000000000000000000000000000000000000000000020
+                000000000000000000000000000000000000000000000000000000000000000b
+                736f6d6520737472696e67000000000000000000000000000000000000000000
+            "
+		),
+	);
+}
modifiedcrates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth
before · crates/evm-coder/tests/abi_derive_generation.rs
1use evm_coder_procedural::AbiCoder;2use evm_coder::{3	types::*,4	abi::{AbiType, AbiRead, AbiWrite},5};67// TODO: move to build_failed tests8// #[derive(AbiCoder, PartialEq, Debug)]9// struct TypeStructUnit {}1011#[derive(AbiCoder, PartialEq, Debug)]12struct TypeStruct1SimpleParam {13	_a: u8,14}1516#[derive(AbiCoder, PartialEq, Debug)]17struct TypeStruct1DynamicParam {18	_a: String,19}2021#[derive(AbiCoder, PartialEq, Debug)]22struct TypeStruct2SimpleParam {23	_a: u8,24	_b: u32,25}2627#[derive(AbiCoder, PartialEq, Debug)]28struct TypeStruct2DynamicParam {29	_a: String,30	_b: bytes,31}3233#[derive(AbiCoder, PartialEq, Debug)]34struct TypeStruct2MixedParam {35	_a: u8,36	_b: bytes,37}3839#[derive(AbiCoder, PartialEq, Debug)]40struct TypeStruct1DerivedSimpleParam {41	_a: TypeStruct1SimpleParam,42}4344#[derive(AbiCoder, PartialEq, Debug)]45struct TypeStruct2DerivedSimpleParam {46	_a: TypeStruct1SimpleParam,47	_b: TypeStruct2SimpleParam,48}4950#[derive(AbiCoder, PartialEq, Debug)]51struct TypeStruct1DerivedDynamicParam {52	_a: TypeStruct1DynamicParam,53}5455#[derive(AbiCoder, PartialEq, Debug)]56struct TypeStruct2DerivedDynamicParam {57	_a: TypeStruct1DynamicParam,58	_b: TypeStruct2DynamicParam,59}6061#[derive(AbiCoder, PartialEq, Debug)]62struct TypeStruct3DerivedMixedParam {63	_a: TypeStruct1SimpleParam,64	_b: TypeStruct2DynamicParam,65	_c: TypeStruct2MixedParam,66}6768#[test]69fn empty() {}7071#[test]72fn impl_abi_type_signature() {73	assert_eq!(74		<TypeStruct1SimpleParam as AbiType>::SIGNATURE75			.as_str()76			.unwrap(),77		"(uint8)"78	);79	assert_eq!(80		<TypeStruct1DynamicParam as AbiType>::SIGNATURE81			.as_str()82			.unwrap(),83		"(string)"84	);85	assert_eq!(86		<TypeStruct2SimpleParam as AbiType>::SIGNATURE87			.as_str()88			.unwrap(),89		"(uint8,uint32)"90	);91	assert_eq!(92		<TypeStruct2DynamicParam as AbiType>::SIGNATURE93			.as_str()94			.unwrap(),95		"(string,bytes)"96	);97	assert_eq!(98		<TypeStruct2MixedParam as AbiType>::SIGNATURE99			.as_str()100			.unwrap(),101		"(uint8,bytes)"102	);103	assert_eq!(104		<TypeStruct1DerivedSimpleParam as AbiType>::SIGNATURE105			.as_str()106			.unwrap(),107		"((uint8))"108	);109	assert_eq!(110		<TypeStruct2DerivedSimpleParam as AbiType>::SIGNATURE111			.as_str()112			.unwrap(),113		"((uint8),(uint8,uint32))"114	);115	assert_eq!(116		<TypeStruct1DerivedDynamicParam as AbiType>::SIGNATURE117			.as_str()118			.unwrap(),119		"((string))"120	);121	assert_eq!(122		<TypeStruct2DerivedDynamicParam as AbiType>::SIGNATURE123			.as_str()124			.unwrap(),125		"((string),(string,bytes))"126	);127	assert_eq!(128		<TypeStruct3DerivedMixedParam as AbiType>::SIGNATURE129			.as_str()130			.unwrap(),131		"((uint8),(string,bytes),(uint8,bytes))"132	);133}134135#[test]136fn impl_abi_type_is_dynamic() {137	assert_eq!(<TypeStruct1SimpleParam as AbiType>::is_dynamic(), false);138	assert_eq!(<TypeStruct1DynamicParam as AbiType>::is_dynamic(), true);139	assert_eq!(<TypeStruct2SimpleParam as AbiType>::is_dynamic(), false);140	assert_eq!(<TypeStruct2DynamicParam as AbiType>::is_dynamic(), true);141	assert_eq!(<TypeStruct2MixedParam as AbiType>::is_dynamic(), true);142	assert_eq!(143		<TypeStruct1DerivedSimpleParam as AbiType>::is_dynamic(),144		false145	);146	assert_eq!(147		<TypeStruct2DerivedSimpleParam as AbiType>::is_dynamic(),148		false149	);150	assert_eq!(151		<TypeStruct1DerivedDynamicParam as AbiType>::is_dynamic(),152		true153	);154	assert_eq!(155		<TypeStruct2DerivedDynamicParam as AbiType>::is_dynamic(),156		true157	);158	assert_eq!(159		<TypeStruct3DerivedMixedParam as AbiType>::is_dynamic(),160		true161	);162}163164#[test]165fn impl_abi_type_size() {166	const ABI_ALIGNMENT: usize = 32;167	assert_eq!(<TypeStruct1SimpleParam as AbiType>::size(), ABI_ALIGNMENT);168	assert_eq!(<TypeStruct1DynamicParam as AbiType>::size(), ABI_ALIGNMENT);169	assert_eq!(170		<TypeStruct2SimpleParam as AbiType>::size(),171		ABI_ALIGNMENT * 2172	);173	assert_eq!(174		<TypeStruct2DynamicParam as AbiType>::size(),175		ABI_ALIGNMENT * 2176	);177	assert_eq!(178		<TypeStruct2MixedParam as AbiType>::size(),179		ABI_ALIGNMENT * 2180	);181	assert_eq!(182		<TypeStruct1DerivedSimpleParam as AbiType>::size(),183		ABI_ALIGNMENT184	);185	assert_eq!(186		<TypeStruct2DerivedSimpleParam as AbiType>::size(),187		ABI_ALIGNMENT * 3188	);189	assert_eq!(190		<TypeStruct1DerivedDynamicParam as AbiType>::size(),191		ABI_ALIGNMENT192	);193	assert_eq!(194		<TypeStruct2DerivedDynamicParam as AbiType>::size(),195		ABI_ALIGNMENT * 3196	);197	assert_eq!(198		<TypeStruct3DerivedMixedParam as AbiType>::size(),199		ABI_ALIGNMENT * 5200	);201}202203#[derive(AbiCoder, PartialEq, Debug)]204struct TupleStruct1SimpleParam(u8);205206#[derive(AbiCoder, PartialEq, Debug)]207struct TupleStruct1DynamicParam(String);208209#[derive(AbiCoder, PartialEq, Debug)]210struct TupleStruct2SimpleParam(u8, u32);211212#[derive(AbiCoder, PartialEq, Debug)]213struct TupleStruct2DynamicParam(String, bytes);214215#[derive(AbiCoder, PartialEq, Debug)]216struct TupleStruct2MixedParam(u8, bytes);217218#[derive(AbiCoder, PartialEq, Debug)]219struct TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam);220221#[derive(AbiCoder, PartialEq, Debug)]222struct TupleStruct2DerivedSimpleParam(TupleStruct1SimpleParam, TupleStruct2SimpleParam);223224#[derive(AbiCoder, PartialEq, Debug)]225struct TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam);226227#[derive(AbiCoder, PartialEq, Debug)]228struct TupleStruct2DerivedDynamicParam(TupleStruct1DynamicParam, TupleStruct2DynamicParam);229230#[derive(AbiCoder, PartialEq, Debug)]231struct TupleStruct3DerivedMixedParam(232	TupleStruct1SimpleParam,233	TupleStruct2DynamicParam,234	TupleStruct2MixedParam,235);236237#[test]238fn impl_abi_type_signature_same_for_structs() {239	assert_eq!(240		<TypeStruct1SimpleParam as AbiType>::SIGNATURE241			.as_str()242			.unwrap(),243		<TupleStruct1SimpleParam as AbiType>::SIGNATURE244			.as_str()245			.unwrap()246	);247	assert_eq!(248		<TypeStruct1DynamicParam as AbiType>::SIGNATURE249			.as_str()250			.unwrap(),251		<TupleStruct1DynamicParam as AbiType>::SIGNATURE252			.as_str()253			.unwrap()254	);255	assert_eq!(256		<TypeStruct2SimpleParam as AbiType>::SIGNATURE257			.as_str()258			.unwrap(),259		<TupleStruct2SimpleParam as AbiType>::SIGNATURE260			.as_str()261			.unwrap()262	);263	assert_eq!(264		<TypeStruct2DynamicParam as AbiType>::SIGNATURE265			.as_str()266			.unwrap(),267		<TupleStruct2DynamicParam as AbiType>::SIGNATURE268			.as_str()269			.unwrap()270	);271	assert_eq!(272		<TypeStruct2MixedParam as AbiType>::SIGNATURE273			.as_str()274			.unwrap(),275		<TupleStruct2MixedParam as AbiType>::SIGNATURE276			.as_str()277			.unwrap(),278	);279	assert_eq!(280		<TypeStruct1DerivedSimpleParam as AbiType>::SIGNATURE281			.as_str()282			.unwrap(),283		<TupleStruct1DerivedSimpleParam as AbiType>::SIGNATURE284			.as_str()285			.unwrap(),286	);287	assert_eq!(288		<TypeStruct2DerivedSimpleParam as AbiType>::SIGNATURE289			.as_str()290			.unwrap(),291		<TupleStruct2DerivedSimpleParam as AbiType>::SIGNATURE292			.as_str()293			.unwrap(),294	);295	assert_eq!(296		<TypeStruct1DerivedDynamicParam as AbiType>::SIGNATURE297			.as_str()298			.unwrap(),299		<TupleStruct1DerivedDynamicParam as AbiType>::SIGNATURE300			.as_str()301			.unwrap(),302	);303	assert_eq!(304		<TypeStruct2DerivedDynamicParam as AbiType>::SIGNATURE305			.as_str()306			.unwrap(),307		<TupleStruct2DerivedDynamicParam as AbiType>::SIGNATURE308			.as_str()309			.unwrap(),310	);311	assert_eq!(312		<TypeStruct3DerivedMixedParam as AbiType>::SIGNATURE313			.as_str()314			.unwrap(),315		<TupleStruct3DerivedMixedParam as AbiType>::SIGNATURE316			.as_str()317			.unwrap(),318	);319}320321#[test]322fn impl_abi_type_is_dynamic_same_for_structs() {323	assert_eq!(324		<TypeStruct1SimpleParam as AbiType>::is_dynamic(),325		<TupleStruct1SimpleParam as AbiType>::is_dynamic()326	);327	assert_eq!(328		<TypeStruct1DynamicParam as AbiType>::is_dynamic(),329		<TupleStruct1DynamicParam as AbiType>::is_dynamic()330	);331	assert_eq!(332		<TypeStruct2SimpleParam as AbiType>::is_dynamic(),333		<TupleStruct2SimpleParam as AbiType>::is_dynamic()334	);335	assert_eq!(336		<TypeStruct2DynamicParam as AbiType>::is_dynamic(),337		<TupleStruct2DynamicParam as AbiType>::is_dynamic()338	);339	assert_eq!(340		<TypeStruct2MixedParam as AbiType>::is_dynamic(),341		<TupleStruct2MixedParam as AbiType>::is_dynamic()342	);343	assert_eq!(344		<TypeStruct1DerivedSimpleParam as AbiType>::is_dynamic(),345		<TupleStruct1DerivedSimpleParam as AbiType>::is_dynamic()346	);347	assert_eq!(348		<TypeStruct2DerivedSimpleParam as AbiType>::is_dynamic(),349		<TupleStruct2DerivedSimpleParam as AbiType>::is_dynamic()350	);351	assert_eq!(352		<TypeStruct1DerivedDynamicParam as AbiType>::is_dynamic(),353		<TupleStruct1DerivedDynamicParam as AbiType>::is_dynamic()354	);355	assert_eq!(356		<TypeStruct2DerivedDynamicParam as AbiType>::is_dynamic(),357		<TupleStruct2DerivedDynamicParam as AbiType>::is_dynamic()358	);359	assert_eq!(360		<TypeStruct3DerivedMixedParam as AbiType>::is_dynamic(),361		<TupleStruct3DerivedMixedParam as AbiType>::is_dynamic()362	);363}364365#[test]366fn impl_abi_type_size_same_for_structs() {367	assert_eq!(368		<TypeStruct1SimpleParam as AbiType>::size(),369		<TupleStruct1SimpleParam as AbiType>::size()370	);371	assert_eq!(372		<TypeStruct1DynamicParam as AbiType>::size(),373		<TupleStruct1DynamicParam as AbiType>::size()374	);375	assert_eq!(376		<TypeStruct2SimpleParam as AbiType>::size(),377		<TupleStruct2SimpleParam as AbiType>::size()378	);379	assert_eq!(380		<TypeStruct2DynamicParam as AbiType>::size(),381		<TupleStruct2DynamicParam as AbiType>::size()382	);383	assert_eq!(384		<TypeStruct2MixedParam as AbiType>::size(),385		<TupleStruct2MixedParam as AbiType>::size()386	);387	assert_eq!(388		<TypeStruct1DerivedSimpleParam as AbiType>::size(),389		<TupleStruct1DerivedSimpleParam as AbiType>::size()390	);391	assert_eq!(392		<TypeStruct2DerivedSimpleParam as AbiType>::size(),393		<TupleStruct2DerivedSimpleParam as AbiType>::size()394	);395	assert_eq!(396		<TypeStruct1DerivedDynamicParam as AbiType>::size(),397		<TupleStruct1DerivedDynamicParam as AbiType>::size()398	);399	assert_eq!(400		<TypeStruct2DerivedDynamicParam as AbiType>::size(),401		<TupleStruct2DerivedDynamicParam as AbiType>::size()402	);403	assert_eq!(404		<TypeStruct3DerivedMixedParam as AbiType>::size(),405		<TupleStruct3DerivedMixedParam as AbiType>::size()406	);407}408409fn test_impl<TypeStruct, TupleStruct, Tuple>(410	type_struct_data: TypeStruct,411	tuple_struct_data: TupleStruct,412	tuple_data: Tuple,413) where414	TypeStruct: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,415	Tuple: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,416{417	use evm_coder::abi::{AbiReader, AbiWriter};418	const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;419420	let mut writer = AbiWriter::new_call(FUNCTION_IDENTIFIER);421	tuple_data.abi_write(&mut writer);422	let encoded_tuple = writer.finish();423424	let mut writer = AbiWriter::new_call(FUNCTION_IDENTIFIER);425	type_struct_data.abi_write(&mut writer);426	let encoded_struct = writer.finish();427428	similar_asserts::assert_eq!(encoded_tuple, encoded_struct);429430	// let (_, mut decoder) = AbiReader::new_call(&encoded_tuple).unwrap();431	// let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();432	// assert_eq!(restored_struct_data, type_struct_data);433434	// let (_, mut decoder) = AbiReader::new_call(&encoded_struct).unwrap();435	// let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();436	// assert_eq!(restored_tuple_data, tuple_data);437}438439#[test]440fn codec_struct_1_simple() {441	let _a = 0xff;442	test_impl::<TypeStruct1SimpleParam, TupleStruct1SimpleParam, (uint8,)>(443		TypeStruct1SimpleParam { _a },444		TupleStruct1SimpleParam(_a),445		(_a,),446	);447}448449#[test]450fn codec_struct_1_dynamic() {451	let _a: String = "some string".into();452	test_impl::<TypeStruct1DynamicParam, TupleStruct1DynamicParam, (String,)>(453		TypeStruct1DynamicParam { _a: _a.clone() },454		TupleStruct1DynamicParam(_a.clone()),455		(_a,),456	);457}458459#[test]460fn codec_struct_2_dynamic() {461	let _a: String = "some string".into();462	let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);463	test_impl::<TypeStruct2DynamicParam, TupleStruct2DynamicParam, (String, bytes)>(464		TypeStruct2DynamicParam {465			_a: _a.clone(),466			_b: _b.clone(),467		},468		TupleStruct2DynamicParam(_a.clone(), _b.clone()),469		(_a, _b),470	);471}