difftreelog
fix AbiRead implementations
in: master
5 files changed
crates/evm-coder/procedural/src/abi_derive.rsdiffbeforeafterboth1use quote::quote;1use quote::quote;223pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {3pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {4 // dbg!(ast);5 let name = &ast.ident;4 let name = &ast.ident;6 let (is_named_fields, field_names, field_types, params_count) = match &ast.data {5 let (is_named_fields, field_names, field_types, params_count) = match &ast.data {7 syn::Data::Struct(ds) => match ds.fields {6 syn::Data::Struct(ds) => match ds.fields {31 let abi_type = impl_abi_type(name, field_types.clone());30 let abi_type = impl_abi_type(name, field_types.clone());32 let abi_read = impl_abi_read(name, is_named_fields, field_names.clone(), field_types);31 let abi_read = impl_abi_read(name, is_named_fields, field_names.clone(), field_types);33 let abi_write = impl_abi_write(name, is_named_fields, params_count, field_names);32 let abi_write = impl_abi_write(name, is_named_fields, params_count, field_names);34 println!("{}", abi_write);3335 Ok(quote! {34 Ok(quote! {36 #can_be_plcaed_in_vec35 #can_be_plcaed_in_vec37 #abi_type36 #abi_type112 quote!(111 quote!(113 impl ::evm_coder::abi::AbiRead for #name {112 impl ::evm_coder::abi::AbiRead for #name {114 fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {113 fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {115 let size = if !<Self as ::evm_coder::abi::AbiType>::is_dynamic() {114 let is_dynamic = <Self as ::evm_coder::abi::AbiType>::is_dynamic();115 let size = if !is_dynamic {116 Some(<Self as ::evm_coder::abi::AbiType>::size())116 Some(<Self as ::evm_coder::abi::AbiType>::size())117 } else {117 } else {118 None118 None119 };119 };120 let mut subresult = reader.subresult(size)?;120 let mut subresult = reader.subresult(size)?;121 #(121 #(122 let #field_names = <#field_types as ::evm_coder::abi::AbiRead>::abi_read(&mut subresult)?;122 let #field_names = {123 let value = <#field_types as ::evm_coder::abi::AbiRead>::abi_read(&mut subresult)?;124 if !is_dynamic {subresult.seek(<#field_types as ::evm_coder::abi::AbiType>::size())};125 value126 };123 )*127 )*124128125 #struct_constructor129 #struct_constructorcrates/evm-coder/src/abi/impls.rsdiffbeforeafterboth92 }92 }93}93}949495impl<R: AbiRead + sealed::CanBePlacedInVec> AbiRead for Vec<R> {95impl<R: AbiType + AbiRead + sealed::CanBePlacedInVec> AbiRead for Vec<R> {96 fn abi_read(reader: &mut AbiReader) -> Result<Vec<R>> {96 fn abi_read(reader: &mut AbiReader) -> Result<Vec<R>> {97 let mut sub = reader.subresult(None)?;97 let mut sub = reader.subresult(None)?;98 let size = sub.uint32()? as usize;98 let size = sub.uint32()? as usize;99 sub.subresult_offset = sub.offset;99 sub.subresult_offset = sub.offset;100 let mut out = Vec::with_capacity(size);100 let mut out = Vec::with_capacity(size);101 for _ in 0..size {101 for _ in 0..size {102 out.push(<R>::abi_read(&mut sub)?);102 out.push(<R>::abi_read(&mut sub)?);103 if !<R>::is_dynamic() {104 sub.subresult_offset += <R>::size()105 };103 }106 }104 Ok(out)107 Ok(out)105 }108 }295298296 impl<$($ident),+> AbiRead for ($($ident,)+)299 impl<$($ident),+> AbiRead for ($($ident,)+)297 where300 where298 $($ident: AbiRead,)+301 $($ident: AbiRead + AbiType,)+299 ($($ident,)+): AbiType,302 ($($ident,)+): AbiType,300 {303 {301 fn abi_read(reader: &mut AbiReader) -> Result<($($ident,)+)> {304 fn abi_read(reader: &mut AbiReader) -> Result<($($ident,)+)> {302 let size = if !<($($ident,)+)>::is_dynamic() { Some(<($($ident,)+)>::size()) } else { None };305 let is_dynamic = <($($ident,)+)>::is_dynamic();306 let size = if !is_dynamic { Some(<($($ident,)+)>::size()) } else { None };303 let mut subresult = reader.subresult(size)?;307 let mut subresult = reader.subresult(size)?;304 Ok((308 Ok((305 $(<$ident>::abi_read(&mut subresult)?,)+309 $({310 let value = <$ident>::abi_read(&mut subresult)?;311 if !is_dynamic {subresult.seek(<$ident as AbiType>::size())};312 value313 },)+306 ))314 ))307 }315 }308 }316 }crates/evm-coder/src/abi/mod.rsdiffbeforeafterboth75 buf: &[u8],75 buf: &[u8],76 offset: usize,76 offset: usize,77 pad_start: usize,77 pad_start: usize,78 pad_size: usize,78 pad_end: usize,79 block_start: usize,79 block_start: usize,80 block_size: usize,80 block_end: usize,81 ) -> Result<[u8; S]> {81 ) -> Result<[u8; S]> {82 if buf.len() - offset < ABI_ALIGNMENT {82 if buf.len() - offset < ABI_ALIGNMENT {83 return Err(Error::Error(ExitError::OutOfOffset));83 return Err(Error::Error(ExitError::OutOfOffset));84 }84 }85 let mut block = [0; S];85 let mut block = [0; S];86 let is_pad_zeroed = buf[pad_start..pad_size].iter().all(|&v| v == 0);86 let is_pad_zeroed = buf[pad_start..pad_end].iter().all(|&v| v == 0);87 if !is_pad_zeroed {87 if !is_pad_zeroed {88 return Err(Error::Error(ExitError::InvalidRange));88 return Err(Error::Error(ExitError::InvalidRange));89 }89 }90 block.copy_from_slice(&buf[block_start..block_size]);90 block.copy_from_slice(&buf[block_start..block_end]);91 Ok(block)91 Ok(block)92 }92 }9393190 let subresult_offset = self.subresult_offset;190 let subresult_offset = self.subresult_offset;191 let offset = if let Some(size) = size {191 let offset = if let Some(size) = size {192 self.offset += size;192 self.offset += size;193 self.subresult_offset += size;194 0193 0195 } else {194 } else {196 self.uint32()? as usize195 self.uint32()? as usize208 })207 })209 }208 }209210 /// Notify about readed data portion.211 pub fn seek(&mut self, size: usize) {212 self.subresult_offset += size;213 }210214211 /// Is this parser reached end of buffer?215 /// Is this parser reached end of buffer?212 pub fn is_finished(&self) -> bool {216 pub fn is_finished(&self) -> bool {crates/evm-coder/src/abi/test.rsdiffbeforeafterboth136 );136 );137}137}138139#[test]140fn encode_decode_vec_tuple_uint8_uint8() {141 test_impl::<Vec<(u8, u8)>>(142 0xdeadbeef,143 vec![(0x0A, 0x0B), (0x0C, 0x0D), (0x0E, 0x0F)],144 &hex!(145 "146 deadbeef147 0000000000000000000000000000000000000000000000000000000000000020148 0000000000000000000000000000000000000000000000000000000000000003149 000000000000000000000000000000000000000000000000000000000000000a150 000000000000000000000000000000000000000000000000000000000000000b151 000000000000000000000000000000000000000000000000000000000000000c152 000000000000000000000000000000000000000000000000000000000000000d153 000000000000000000000000000000000000000000000000000000000000000e154 000000000000000000000000000000000000000000000000000000000000000f155 "156 ),157 );158}138159139#[test]160#[test]140fn encode_decode_vec_tuple_uint256_string() {161fn encode_decode_vec_tuple_uint256_string() {333 );354 );334}355}356357#[test]358// #[ignore = "reason"]359fn encode_decode_tuple0_tuple1_uint8_tuple1_string_bytes_tuple1_uint8_bytes() {360 let int = 0xff;361 let by = bytes(vec![0x11, 0x22, 0x33]);362 let string = "some string".to_string();363364 test_impl::<((u8,), (String, bytes), (u8, bytes))>(365 0xdeadbeef,366 ((int,), (string.clone(), by.clone()), (int, by)),367 &hex!(368 "369 deadbeef370 0000000000000000000000000000000000000000000000000000000000000020371 00000000000000000000000000000000000000000000000000000000000000ff372 0000000000000000000000000000000000000000000000000000000000000060373 0000000000000000000000000000000000000000000000000000000000000120374 0000000000000000000000000000000000000000000000000000000000000040375 0000000000000000000000000000000000000000000000000000000000000080376 000000000000000000000000000000000000000000000000000000000000000b377 736f6d6520737472696e67000000000000000000000000000000000000000000378 0000000000000000000000000000000000000000000000000000000000000003379 1122330000000000000000000000000000000000000000000000000000000000380 00000000000000000000000000000000000000000000000000000000000000ff381 0000000000000000000000000000000000000000000000000000000000000040382 0000000000000000000000000000000000000000000000000000000000000003383 1122330000000000000000000000000000000000000000000000000000000000384 "385 ),386 );387}388389#[test]390fn encode_decode_tuple0_tuple1_uint8_tuple1_uint8_uint8_tuple1_uint8_uint8() {391 test_impl::<((u8,), (u8, u8), (u8, u8))>(392 0xdeadbeef,393 ((43,), (44, 45), (46, 47)),394 &hex!(395 "396 deadbeef397 000000000000000000000000000000000000000000000000000000000000002b398 000000000000000000000000000000000000000000000000000000000000002c399 000000000000000000000000000000000000000000000000000000000000002d400 000000000000000000000000000000000000000000000000000000000000002e401 000000000000000000000000000000000000000000000000000000000000002f402 "403 ),404 );405}406407#[test]408fn encode_decode_tuple0_tuple1_uint8_tuple1_uint8() {409 test_impl::<((u8,), (u8,))>(410 0xdeadbeef,411 ((43,), (44,)),412 &hex!(413 "414 deadbeef415 000000000000000000000000000000000000000000000000000000000000002b416 000000000000000000000000000000000000000000000000000000000000002c417 "418 ),419 );420}421422#[test]423fn encode_decode_tuple0_tuple1_uint8_uint8() {424 test_impl::<((u8, u8),)>(425 0xdeadbeef,426 ((43, 44),),427 &hex!(428 "429 deadbeef430 000000000000000000000000000000000000000000000000000000000000002b431 000000000000000000000000000000000000000000000000000000000000002c432 "433 ),434 );435}436437#[test]438fn encode_decode_tuple_uint8_uint8() {439 test_impl::<(u8, u8)>(440 0xdeadbeef,441 (43, 44),442 &hex!(443 "444 deadbeef445 000000000000000000000000000000000000000000000000000000000000002b446 000000000000000000000000000000000000000000000000000000000000002c447 "448 ),449 );450}451452#[test]453fn encode_decode_tuple0_tuple1_string() {454 test_impl::<((String,),)>(455 0xdeadbeef,456 (("some string".to_string(),),),457 &hex!(458 "459 deadbeef460 0000000000000000000000000000000000000000000000000000000000000020461 0000000000000000000000000000000000000000000000000000000000000020462 0000000000000000000000000000000000000000000000000000000000000020463 000000000000000000000000000000000000000000000000000000000000000b464 736f6d6520737472696e67000000000000000000000000000000000000000000465 "466 ),467 );468}469470#[test]471fn encode_decode_tuple0_tuple1_uint8_string() {472 test_impl::<((u8, String),)>(473 0xdeadbeef,474 ((0xff, "some string".to_string()),),475 &hex!(476 "477 deadbeef478 0000000000000000000000000000000000000000000000000000000000000020479 0000000000000000000000000000000000000000000000000000000000000020480 00000000000000000000000000000000000000000000000000000000000000ff481 0000000000000000000000000000000000000000000000000000000000000040482 000000000000000000000000000000000000000000000000000000000000000b483 736f6d6520737472696e67000000000000000000000000000000000000000000484 "485 ),486 );487}488489#[test]490fn encode_decode_tuple0_tuple1_string_bytes() {491 test_impl::<((String, bytes),)>(492 0xdeadbeef,493 (("some string".to_string(), bytes(vec![1, 2, 3])),),494 &hex!(495 "496 deadbeef497 0000000000000000000000000000000000000000000000000000000000000020498 0000000000000000000000000000000000000000000000000000000000000020499 0000000000000000000000000000000000000000000000000000000000000040500 0000000000000000000000000000000000000000000000000000000000000080501 000000000000000000000000000000000000000000000000000000000000000b502 736f6d6520737472696e67000000000000000000000000000000000000000000503 0000000000000000000000000000000000000000000000000000000000000003504 0102030000000000000000000000000000000000000000000000000000000000505 "506 ),507 );508}509510#[test]511fn encode_decode_tuple0_tuple1_uint8_tuple1_string() {512 test_impl::<((u8,), (String,))>(513 0xdeadbeef,514 ((0xff,), ("some string".to_string(),)),515 &hex!(516 "517 deadbeef518 0000000000000000000000000000000000000000000000000000000000000020519 00000000000000000000000000000000000000000000000000000000000000ff520 0000000000000000000000000000000000000000000000000000000000000040521 0000000000000000000000000000000000000000000000000000000000000020522 000000000000000000000000000000000000000000000000000000000000000b523 736f6d6520737472696e67000000000000000000000000000000000000000000524 "525 ),526 );527}335528crates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth1use 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};667// TODO: move to build_failed tests7// TODO: move to build_failed tests406 );406 );407}407}408409const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;408410409fn 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) where414 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);423417 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);419426427 // dbg!(&encoded_tuple);428 // dbg!(&encoded_tuple_struct);429 // dbg!(&encoded_type_struct);430431 {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 }441442 {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);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}452}453454fn test_abi_write_impl<A>(data: &A) -> Vec<u8>455where456 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_tuple462}438463439#[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}448473449#[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}483484#[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}495496#[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}507508#[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}458518459#[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}529530#[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}540541#[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}557558#[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}578579#[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