difftreelog
feat Add write support for vectors with simple types.
in: master
1 file changed
crates/evm-coder/src/abi.rsdiffbeforeafterboth32const ABI_ALIGNMENT: usize = 32;32const ABI_ALIGNMENT: usize = 32;333334trait TypeHelper {34trait TypeHelper {35 /// Is type dynamic sized.35 fn is_dynamic() -> bool;36 fn is_dynamic() -> bool;3738 /// Size for type aligned to [`ABI_ALIGNMENT`].39 fn size() -> usize;36}40}374138/// View into RLP data, which provides method to read typed items from it42/// View into RLP data, which provides method to read typed items from it316 let part_offset = self.static_part.len() - if self.had_call { 4 } else { 0 };320 let part_offset = self.static_part.len() - if self.had_call { 4 } else { 0 };317321318 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);322 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);323 let start = static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len();324 let stop = static_offset + ABI_ALIGNMENT;319 self.static_part[static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len()325 self.static_part[start..stop].copy_from_slice(&encoded_dynamic_offset);320 ..static_offset + ABI_ALIGNMENT]321 .copy_from_slice(&encoded_dynamic_offset);322 self.static_part.extend(part.finish())326 self.static_part.extend(part.finish())323 }327 }334 /// Read item from current position, advanding decoder338 /// Read item from current position, advanding decoder335 fn abi_read(&mut self) -> Result<T>;339 fn abi_read(&mut self) -> Result<T>;336337 /// Size for type aligned to [`ABI_ALIGNMENT`].338 fn size() -> usize;339}340}340341341macro_rules! impl_abi_readable {342macro_rules! impl_abi_readable {345 $dynamic346 $dynamic346 }347 }348349 fn size() -> usize {350 ABI_ALIGNMENT351 }347 }352 }348 impl AbiRead<$ty> for AbiReader<'_> {353 impl AbiRead<$ty> for AbiReader<'_> {349 fn abi_read(&mut self) -> Result<$ty> {354 fn abi_read(&mut self) -> Result<$ty> {350 self.$method()355 self.$method()351 }356 }352353 fn size() -> usize {354 ABI_ALIGNMENT355 }356 }357 }357 };358 };358}359}392 Ok(out)393 Ok(out)393 }394 }394395 fn size() -> usize {396 ABI_ALIGNMENT397 }398}395}399396400macro_rules! impl_tuples {397macro_rules! impl_tuples {401 ($($ident:ident)+) => {398 ($($ident:ident)+) => {402 impl<$($ident: TypeHelper,)+> TypeHelper for ($($ident,)+) {399 impl<$($ident: TypeHelper,)+> TypeHelper for ($($ident,)+)400 where401 $(402 $ident: TypeHelper,403 )+404 {403 fn is_dynamic() -> bool {405 fn is_dynamic() -> bool {404 false406 false407 )*409 )*408 }410 }411412 fn size() -> usize {413 0 $(+ <$ident>::size())+414 }409 }415 }410 impl<$($ident),+> sealed::CanBePlacedInVec for ($($ident,)+) {}416 impl<$($ident),+> sealed::CanBePlacedInVec for ($($ident,)+) {}411 impl<$($ident),+> AbiRead<($($ident,)+)> for AbiReader<'_>417 impl<$($ident),+> AbiRead<($($ident,)+)> for AbiReader<'_>416 ($($ident,)+): TypeHelper,422 ($($ident,)+): TypeHelper,417 {423 {418 fn abi_read(&mut self) -> Result<($($ident,)+)> {424 fn abi_read(&mut self) -> Result<($($ident,)+)> {419 let size = if !<($($ident,)+)>::is_dynamic() { Some(<Self as AbiRead<($($ident,)+)>>::size()) } else { None };425 let size = if !<($($ident,)+)>::is_dynamic() { Some(<($($ident,)+)>::size()) } else { None };420 let mut subresult = self.subresult(size)?;426 let mut subresult = self.subresult(size)?;421 Ok((427 Ok((422 $(<Self as AbiRead<$ident>>::abi_read(&mut subresult)?,)+428 $(<Self as AbiRead<$ident>>::abi_read(&mut subresult)?,)+423 ))429 ))424 }430 }425426 fn size() -> usize {427 0 $(+ <AbiReader<'_> as AbiRead<$ident>>::size())+428 }429 }431 }430 #[allow(non_snake_case)]432 #[allow(non_snake_case)]431 impl<$($ident),+> AbiWrite for &($($ident,)+)433 impl<$($ident),+> AbiWrite for ($($ident,)+)432 where434 where433 $($ident: AbiWrite,)+435 $($ident: AbiWrite,)+434 {436 {505impl_abi_writeable!(H160, address);507impl_abi_writeable!(H160, address);506impl_abi_writeable!(bool, bool);508impl_abi_writeable!(bool, bool);507impl_abi_writeable!(&str, string);509impl_abi_writeable!(&str, string);508impl AbiWrite for &string {510impl AbiWrite for string {509 fn abi_write(&self, writer: &mut AbiWriter) {511 fn abi_write(&self, writer: &mut AbiWriter) {510 writer.string(self)512 writer.string(self)511 }513 }512}514}515// impl AbiWrite for Vec<u8> {516// fn abi_write(&self, writer: &mut AbiWriter) {517// writer.bytes(self)518// }519// }520513impl AbiWrite for &Vec<u8> {521impl<T: AbiWrite> AbiWrite for Vec<T> {514 fn abi_write(&self, writer: &mut AbiWriter) {522 fn abi_write(&self, writer: &mut AbiWriter) {523 let mut sub = AbiWriter::new();524 (self.len() as u32).abi_write(&mut sub);525 for item in self {526 item.abi_write(&mut sub);527 }515 writer.bytes(self)528 writer.write_subresult(sub);516 }529 }517}530}518531556#[cfg(test)]569#[cfg(test)]557pub mod test {570pub mod test {558 use crate::{571 use crate::{559 abi::AbiRead,572 abi::{AbiRead, AbiWrite},560 types::{string, uint256},573 types::{string, uint256, address},561 };574 };562575563 use super::{AbiReader, AbiWriter};576 use super::{AbiReader, AbiWriter};564 use hex_literal::hex;577 use hex_literal::hex;578 use primitive_types::{H160, U256};565579566 #[test]580 #[test]567 fn dynamic_after_static() {581 fn dynamic_after_static() {609 }623 }610624611 #[test]625 #[test]612 fn mint_bulk() {626 fn parse_vec_with_dynamic_type() {627 let decoded_data = (628 0x36543006,629 vec![630 (1.into(), "Test URI 0".to_string()),631 (11.into(), "Test URI 1".to_string()),632 (12.into(), "Test URI 2".to_string()),633 ],634 );635636 let encoded_data = &hex!(637 "638 36543006639 00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address640 0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]641 0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]642643 0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem644 00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem645 0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem646647 0000000000000000000000000000000000000000000000000000000000000001 // first token id? #60648 0000000000000000000000000000000000000000000000000000000000000040 // offset of string649 000000000000000000000000000000000000000000000000000000000000000a // size of string650 5465737420555249203000000000000000000000000000000000000000000000 // string651652 000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11? #e0653 0000000000000000000000000000000000000000000000000000000000000040 // offset of string654 000000000000000000000000000000000000000000000000000000000000000a // size of string655 5465737420555249203100000000000000000000000000000000000000000000 // string656657 000000000000000000000000000000000000000000000000000000000000000c // third token id? Why ==12? #160658 0000000000000000000000000000000000000000000000000000000000000040 // offset of string659 000000000000000000000000000000000000000000000000000000000000000a // size of string660 5465737420555249203200000000000000000000000000000000000000000000 // string661 "662 );663613 let (call, mut decoder) = AbiReader::new_call(&hex!(664 let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();614 "615 36543006616 00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address617 0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]618 0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]619620 0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem621 00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem622 0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem623624 0000000000000000000000000000000000000000000000000000000000000001 // first token id? #60625 0000000000000000000000000000000000000000000000000000000000000040 // offset of string626 000000000000000000000000000000000000000000000000000000000000000a // size of string627 5465737420555249203000000000000000000000000000000000000000000000 // string628629 000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11? #e0630 0000000000000000000000000000000000000000000000000000000000000040 // offset of string631 000000000000000000000000000000000000000000000000000000000000000a // size of string632 5465737420555249203100000000000000000000000000000000000000000000 // string633634 000000000000000000000000000000000000000000000000000000000000000c // third token id? Why ==12? #160635 0000000000000000000000000000000000000000000000000000000000000040 // offset of string636 000000000000000000000000000000000000000000000000000000000000000a // size of string637 5465737420555249203200000000000000000000000000000000000000000000 // string638 "639 ))640 .unwrap();641 assert_eq!(call, u32::to_be_bytes(0x36543006));665 assert_eq!(call, u32::to_be_bytes(decoded_data.0));642 let _ = decoder.address().unwrap();666 let _ = decoder.address().unwrap();643 let data =667 let data =644 <AbiReader<'_> as AbiRead<Vec<(uint256, string)>>>::abi_read(&mut decoder).unwrap();668 <AbiReader<'_> as AbiRead<Vec<(uint256, string)>>>::abi_read(&mut decoder).unwrap();645 assert_eq!(669 assert_eq!(data, decoded_data.1);646 data,670647 vec![671 let mut writer = AbiWriter::new_call(decoded_data.0);648 (1.into(), "Test URI 0".to_string()),672 decoded_data.1.abi_write(&mut writer);649 (11.into(), "Test URI 1".to_string()),673 let ed = writer.finish();650 (12.into(), "Test URI 2".to_string())674 assert_eq!(encoded_data, ed.as_slice());651 ]652 );653 }675 }654676655 #[test]677 #[test]656 fn parse_vec_with_simple_type() {678 fn parse_vec_with_simple_type() {657 use crate::types::address;679 let decoded_data = (680 0x1ACF2D55,681 vec![682 (658 use primitive_types::{H160, U256};683 H160(hex!("2D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC")),684 U256([10, 0, 0, 0]),685 ),686 (687 H160(hex!("AB8E3D9134955566483B11E6825C9223B6737B10")),688 U256([20, 0, 0, 0]),689 ),690 (691 H160(hex!("8C582BDF2953046705FC56F189385255EFC1BE18")),692 U256([30, 0, 0, 0]),693 ),694 ],695 );696697 let encoded_data = &hex!(698 "699 1ACF2D55700 0000000000000000000000000000000000000000000000000000000000000020 // offset of (address, uint256)[]701 0000000000000000000000000000000000000000000000000000000000000003 // length of (address, uint256)[]702703 0000000000000000000000002D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC // address704 000000000000000000000000000000000000000000000000000000000000000A // uint256705706 000000000000000000000000AB8E3D9134955566483B11E6825C9223B6737B10 // address707 0000000000000000000000000000000000000000000000000000000000000014 // uint256708709 0000000000000000000000008C582BDF2953046705FC56F189385255EFC1BE18 // address710 000000000000000000000000000000000000000000000000000000000000001E // uint256711 "712 );659713660 let (call, mut decoder) = AbiReader::new_call(&hex!(714 let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();661 "662 1ACF2D55663 0000000000000000000000000000000000000000000000000000000000000020 // offset of (address, uint256)[]664 0000000000000000000000000000000000000000000000000000000000000003 // length of (address, uint256)[]665666 0000000000000000000000002D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC // address667 000000000000000000000000000000000000000000000000000000000000000A // uint256668669 000000000000000000000000AB8E3D9134955566483B11E6825C9223B6737B10 // address670 0000000000000000000000000000000000000000000000000000000000000014 // uint256671672 0000000000000000000000008C582BDF2953046705FC56F189385255EFC1BE18 // address673 000000000000000000000000000000000000000000000000000000000000001E // uint256674 "675 ))676 .unwrap();677 assert_eq!(call, u32::to_be_bytes(0x1ACF2D55));715 assert_eq!(call, u32::to_be_bytes(decoded_data.0));678 let data =716 let data =679 <AbiReader<'_> as AbiRead<Vec<(address, uint256)>>>::abi_read(&mut decoder).unwrap();717 <AbiReader<'_> as AbiRead<Vec<(address, uint256)>>>::abi_read(&mut decoder).unwrap();680 assert_eq!(data.len(), 3);718 assert_eq!(data.len(), 3);681 assert_eq!(719 assert_eq!(data, decoded_data.1);682 data,720683 vec![721 let mut writer = AbiWriter::new_call(decoded_data.0);684 (722 decoded_data.1.abi_write(&mut writer);685 H160(hex!("2D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC")),723 let ed = writer.finish();686 U256([10, 0, 0, 0])724 assert_eq!(encoded_data, ed.as_slice());687 ),688 (689 H160(hex!("AB8E3D9134955566483B11E6825C9223B6737B10")),690 U256([20, 0, 0, 0])691 ),692 (693 H160(hex!("8C582BDF2953046705FC56F189385255EFC1BE18")),694 U256([30, 0, 0, 0])695 ),696 ]697 );698 }725 }699}726}