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
1use evm_coder_procedural::AbiCoder;1use evm_coder_procedural::AbiCoder;
2use evm_coder::{2use evm_coder::{
3 types::*,3 types::*,
4 abi::{AbiType, AbiRead, AbiWrite},4 abi::{AbiType, AbiRead, AbiWrite, AbiReader, AbiWriter},
5};5};
66
7// TODO: move to build_failed tests7// TODO: move to build_failed tests
406 );406 );
407}407}
408
409const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;
408410
409fn test_impl<TypeStruct, TupleStruct, Tuple>(411fn test_impl<Tuple, TupleStruct, TypeStruct>(
410 type_struct_data: TypeStruct,412 tuple_data: Tuple,
411 tuple_struct_data: TupleStruct,413 tuple_struct_data: TupleStruct,
412 tuple_data: Tuple,414 type_struct_data: TypeStruct,
413) where415) where
414 TypeStruct: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,416 TypeStruct: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
417 TupleStruct: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
415 Tuple: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,418 Tuple: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
416{419{
420 let encoded_type_struct = test_abi_write_impl(&type_struct_data);
421 let encoded_tuple_struct = test_abi_write_impl(&tuple_struct_data);
422 let encoded_tuple = test_abi_write_impl(&tuple_data);
423
417 use evm_coder::abi::{AbiReader, AbiWriter};424 similar_asserts::assert_eq!(encoded_tuple, encoded_type_struct);
418 const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;425 similar_asserts::assert_eq!(encoded_tuple, encoded_tuple_struct);
419426
427 // dbg!(&encoded_tuple);
428 // dbg!(&encoded_tuple_struct);
429 // dbg!(&encoded_type_struct);
430
431 {
420 let mut writer = AbiWriter::new_call(FUNCTION_IDENTIFIER);432 let (_, mut decoder) = AbiReader::new_call(&encoded_tuple).unwrap();
421 tuple_data.abi_write(&mut writer);433 let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();
434 assert_eq!(restored_struct_data, type_struct_data);
435 }
436 {
422 let encoded_tuple = writer.finish();437 let (_, mut decoder) = AbiReader::new_call(&encoded_tuple).unwrap();
423438 let restored_struct_data = <TupleStruct>::abi_read(&mut decoder).unwrap();
439 assert_eq!(restored_struct_data, tuple_struct_data);
440 }
441
442 {
424 let mut writer = AbiWriter::new_call(FUNCTION_IDENTIFIER);443 let (_, mut decoder) = AbiReader::new_call(&encoded_type_struct).unwrap();
425 type_struct_data.abi_write(&mut writer);444 let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();
445 assert_eq!(restored_tuple_data, tuple_data);
446 }
447 {
426 let encoded_struct = writer.finish();448 let (_, mut decoder) = AbiReader::new_call(&encoded_tuple_struct).unwrap();
427449 let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();
428 similar_asserts::assert_eq!(encoded_tuple, encoded_struct);450 assert_eq!(restored_tuple_data, tuple_data);
429451 }
430 // 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);
433
434 // 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}452}
453
454fn test_abi_write_impl<A>(data: &A) -> Vec<u8>
455where
456 A: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
457{
458 let mut writer = AbiWriter::new_call(FUNCTION_IDENTIFIER);
459 data.abi_write(&mut writer);
460 let encoded_tuple = writer.finish();
461 encoded_tuple
462}
438463
439#[test]464#[test]
440fn codec_struct_1_simple() {465fn codec_struct_1_simple() {
441 let _a = 0xff;466 let _a = 0xff;
442 test_impl::<TypeStruct1SimpleParam, TupleStruct1SimpleParam, (uint8,)>(467 test_impl::<(uint8,), TupleStruct1SimpleParam, TypeStruct1SimpleParam>(
443 TypeStruct1SimpleParam { _a },468 (_a,),
444 TupleStruct1SimpleParam(_a),469 TupleStruct1SimpleParam(_a),
445 (_a,),470 TypeStruct1SimpleParam { _a },
446 );471 );
447}472}
448473
449#[test]474#[test]
450fn codec_struct_1_dynamic() {475fn codec_struct_1_dynamic() {
451 let _a: String = "some string".into();476 let _a: String = "some string".into();
452 test_impl::<TypeStruct1DynamicParam, TupleStruct1DynamicParam, (String,)>(477 test_impl::<(String,), TupleStruct1DynamicParam, TypeStruct1DynamicParam>(
453 TypeStruct1DynamicParam { _a: _a.clone() },478 (_a.clone(),),
454 TupleStruct1DynamicParam(_a.clone()),479 TupleStruct1DynamicParam(_a.clone()),
455 (_a,),480 TypeStruct1DynamicParam { _a },
456 );481 );
457}482}
483
484#[test]
485fn codec_struct_1_derived_simple() {
486 let _a: u8 = 0xff;
487 test_impl::<((u8,),), TupleStruct1DerivedSimpleParam, TypeStruct1DerivedSimpleParam>(
488 ((_a,),),
489 TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam(_a)),
490 TypeStruct1DerivedSimpleParam {
491 _a: TypeStruct1SimpleParam { _a },
492 },
493 );
494}
495
496#[test]
497fn codec_struct_1_derived_dynamic() {
498 let _a: String = "some string".into();
499 test_impl::<((String,),), TupleStruct1DerivedDynamicParam, TypeStruct1DerivedDynamicParam>(
500 ((_a.clone(),),),
501 TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam(_a.clone())),
502 TypeStruct1DerivedDynamicParam {
503 _a: TypeStruct1DynamicParam { _a },
504 },
505 );
506}
507
508#[test]
509fn codec_struct_2_simple() {
510 let _a = 0xff;
511 let _b = 0xbeefbaba;
512 test_impl::<(u8, u32), TupleStruct2SimpleParam, TypeStruct2SimpleParam>(
513 (_a, _b),
514 TupleStruct2SimpleParam(_a, _b),
515 TypeStruct2SimpleParam { _a, _b },
516 );
517}
458518
459#[test]519#[test]
460fn codec_struct_2_dynamic() {520fn codec_struct_2_dynamic() {
461 let _a: String = "some string".into();521 let _a: String = "some string".into();
462 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);522 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);
463 test_impl::<TypeStruct2DynamicParam, TupleStruct2DynamicParam, (String, bytes)>(523 test_impl::<(String, bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(
464 TypeStruct2DynamicParam {
465 _a: _a.clone(),524 (_a.clone(), _b.clone()),
466 _b: _b.clone(),
467 },
468 TupleStruct2DynamicParam(_a.clone(), _b.clone()),525 TupleStruct2DynamicParam(_a.clone(), _b.clone()),
469 (_a, _b),526 TypeStruct2DynamicParam { _a, _b },
470 );527 );
471}528}
529
530#[test]
531fn codec_struct_2_mixed() {
532 let _a: u8 = 0xff;
533 let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);
534 test_impl::<(u8, bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(
535 (_a.clone(), _b.clone()),
536 TupleStruct2MixedParam(_a.clone(), _b.clone()),
537 TypeStruct2MixedParam { _a, _b },
538 );
539}
540
541#[test]
542fn codec_struct_2_derived_simple() {
543 let _a = 0xff;
544 let _b = 0xbeefbaba;
545 test_impl::<((u8,), (u8, u32)), TupleStruct2DerivedSimpleParam, TypeStruct2DerivedSimpleParam>(
546 ((_a,), (_a, _b)),
547 TupleStruct2DerivedSimpleParam(
548 TupleStruct1SimpleParam(_a),
549 TupleStruct2SimpleParam(_a, _b),
550 ),
551 TypeStruct2DerivedSimpleParam {
552 _a: TypeStruct1SimpleParam { _a },
553 _b: TypeStruct2SimpleParam { _a, _b },
554 },
555 );
556}
557
558#[test]
559fn codec_struct_2_derived_dynamic() {
560 let _a = "some string".to_string();
561 let _b = bytes(vec![0x11, 0x22, 0x33]);
562 test_impl::<
563 ((String,), (String, bytes)),
564 TupleStruct2DerivedDynamicParam,
565 TypeStruct2DerivedDynamicParam,
566 >(
567 ((_a.clone(),), (_a.clone(), _b.clone())),
568 TupleStruct2DerivedDynamicParam(
569 TupleStruct1DynamicParam(_a.clone()),
570 TupleStruct2DynamicParam(_a.clone(), _b.clone()),
571 ),
572 TypeStruct2DerivedDynamicParam {
573 _a: TypeStruct1DynamicParam { _a: _a.clone() },
574 _b: TypeStruct2DynamicParam { _a, _b },
575 },
576 );
577}
578
579#[test]
580fn codec_struct_3_derived_mixed() {
581 let int = 0xff;
582 let by = bytes(vec![0x11, 0x22, 0x33]);
583 let string = "some string".to_string();
584 test_impl::<
585 ((u8,), (String, bytes), (u8, bytes)),
586 TupleStruct3DerivedMixedParam,
587 TypeStruct3DerivedMixedParam,
588 >(
589 ((int,), (string.clone(), by.clone()), (int, by.clone())),
590 TupleStruct3DerivedMixedParam(
591 TupleStruct1SimpleParam(int),
592 TupleStruct2DynamicParam(string.clone(), by.clone()),
593 TupleStruct2MixedParam(int, by.clone()),
594 ),
595 TypeStruct3DerivedMixedParam {
596 _a: TypeStruct1SimpleParam { _a: int },
597 _b: TypeStruct2DynamicParam {
598 _a: string.clone(),
599 _b: by.clone(),
600 },
601 _c: TypeStruct2MixedParam { _a: int, _b: by },
602 },
603 );
604}
472605