From 068fc8208402ab7a179f5a3162432c92fb77eea8 Mon Sep 17 00:00:00 2001 From: Trubnikov Sergey Date: Fri, 18 Nov 2022 07:28:07 +0000 Subject: [PATCH] refactor: Abi impls --- --- a/crates/evm-coder/procedural/src/abi_derive.rs +++ b/crates/evm-coder/procedural/src/abi_derive.rs @@ -121,7 +121,7 @@ #( 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())}; + if !is_dynamic {subresult.bytes_read(<#field_types as ::evm_coder::abi::AbiType>::size())}; value }; )* --- a/crates/evm-coder/procedural/src/solidity_interface.rs +++ b/crates/evm-coder/procedural/src/solidity_interface.rs @@ -406,7 +406,7 @@ quote! { #name: { let value = <#ty as ::evm_coder::abi::AbiRead>::abi_read(reader)?; - if !is_dynamic {reader.seek(<#ty as ::evm_coder::abi::AbiType>::size())}; + if !is_dynamic {reader.bytes_read(<#ty as ::evm_coder::abi::AbiType>::size())}; value } } --- a/crates/evm-coder/src/abi/impls.rs +++ b/crates/evm-coder/src/abi/impls.rs @@ -10,12 +10,12 @@ #[cfg(not(feature = "std"))] use alloc::vec::Vec; -macro_rules! impl_abi_readable { - ($ty:ty, $method:ident, $dynamic:literal) => { +macro_rules! impl_abi_type { + ($ty:ty, $name:ident, $dynamic:literal) => { impl sealed::CanBePlacedInVec for $ty {} impl AbiType for $ty { - const SIGNATURE: SignatureUnit = make_signature!(new fixed(stringify!($ty))); + const SIGNATURE: SignatureUnit = make_signature!(new fixed(stringify!($name))); fn is_dynamic() -> bool { $dynamic @@ -25,7 +25,11 @@ ABI_ALIGNMENT } } + }; +} +macro_rules! impl_abi_readable { + ($ty:ty, $method:ident) => { impl AbiRead for $ty { fn abi_read(reader: &mut AbiReader) -> Result<$ty> { reader.$method() @@ -34,82 +38,75 @@ }; } -impl_abi_readable!(uint32, uint32, false); -impl_abi_readable!(uint64, uint64, false); -impl_abi_readable!(uint128, uint128, false); -impl_abi_readable!(uint256, uint256, false); -impl_abi_readable!(bytes4, bytes4, false); -impl_abi_readable!(address, address, false); -impl_abi_readable!(string, string, true); +macro_rules! impl_abi_writeable { + ($ty:ty, $method:ident) => { + impl AbiWrite for $ty { + fn abi_write(&self, writer: &mut AbiWriter) { + writer.$method(&self) + } + } + }; +} -impl sealed::CanBePlacedInVec for bool {} +macro_rules! impl_abi { + ($ty:ty, $method:ident, $dynamic:literal) => { + impl_abi_type!($ty, $method, $dynamic); + impl_abi_readable!($ty, $method); + impl_abi_writeable!($ty, $method); + }; +} -impl AbiType for bool { - const SIGNATURE: SignatureUnit = make_signature!(new fixed("bool")); +impl_abi!(bool, bool, false); +impl_abi!(u8, uint8, false); +impl_abi!(u32, uint32, false); +impl_abi!(u64, uint64, false); +impl_abi!(u128, uint128, false); +impl_abi!(U256, uint256, false); +impl_abi!(H160, address, false); +impl_abi!(string, string, true); - fn is_dynamic() -> bool { - false - } - fn size() -> usize { - ABI_ALIGNMENT - } -} -impl AbiRead for bool { - fn abi_read(reader: &mut AbiReader) -> Result { - reader.bool() - } -} +impl_abi_writeable!(&str, string); -impl AbiType for uint8 { - const SIGNATURE: SignatureUnit = make_signature!(new fixed("uint8")); +impl_abi_type!(bytes, bytes, true); - fn is_dynamic() -> bool { - false - } - fn size() -> usize { - ABI_ALIGNMENT - } -} -impl AbiRead for uint8 { - fn abi_read(reader: &mut AbiReader) -> Result { - reader.uint8() +impl AbiRead for bytes { + fn abi_read(reader: &mut AbiReader) -> Result { + Ok(bytes(reader.bytes()?)) } } -impl AbiType for bytes { - const SIGNATURE: SignatureUnit = make_signature!(new fixed("bytes")); - - fn is_dynamic() -> bool { - true - } - fn size() -> usize { - ABI_ALIGNMENT +impl AbiWrite for bytes { + fn abi_write(&self, writer: &mut AbiWriter) { + writer.bytes(self.0.as_slice()) } } -impl AbiRead for bytes { - fn abi_read(reader: &mut AbiReader) -> Result { - Ok(bytes(reader.bytes()?)) + +impl_abi_type!(bytes4, bytes4, false); +impl AbiRead for bytes4 { + fn abi_read(reader: &mut AbiReader) -> Result { + reader.bytes4() } } -impl AbiRead for Vec { - fn abi_read(reader: &mut AbiReader) -> Result> { +impl AbiRead for Vec { + fn abi_read(reader: &mut AbiReader) -> Result> { let mut sub = reader.subresult(None)?; let size = sub.uint32()? as usize; sub.subresult_offset = sub.offset; + let is_dynamic = ::is_dynamic(); let mut out = Vec::with_capacity(size); for _ in 0..size { - out.push(::abi_read(&mut sub)?); - if !::is_dynamic() { - sub.subresult_offset += ::size() + out.push(::abi_read(&mut sub)?); + if !is_dynamic { + sub.bytes_read(::size()); }; } Ok(out) } } -impl AbiType for Vec { - const SIGNATURE: SignatureUnit = make_signature!(new nameof(R::SIGNATURE) fixed("[]")); +impl AbiType for Vec { + const SIGNATURE: SignatureUnit = make_signature!(new nameof(T::SIGNATURE) fixed("[]")); fn is_dynamic() -> bool { true @@ -152,39 +149,9 @@ impl AbiWrite for Property { fn abi_write(&self, writer: &mut AbiWriter) { (&self.key, &self.value).abi_write(writer); - } -} - -macro_rules! impl_abi_writeable { - ($ty:ty, $method:ident) => { - impl AbiWrite for $ty { - fn abi_write(&self, writer: &mut AbiWriter) { - writer.$method(&self) - } - } - }; -} - -impl_abi_writeable!(u8, uint8); -impl_abi_writeable!(u32, uint32); -impl_abi_writeable!(u128, uint128); -impl_abi_writeable!(U256, uint256); -impl_abi_writeable!(H160, address); -impl_abi_writeable!(bool, bool); -impl_abi_writeable!(&str, string); - -impl AbiWrite for string { - fn abi_write(&self, writer: &mut AbiWriter) { - writer.string(self) } } -impl AbiWrite for bytes { - fn abi_write(&self, writer: &mut AbiWriter) { - writer.bytes(self.0.as_slice()) - } -} - impl AbiWrite for Vec { fn abi_write(&self, writer: &mut AbiWriter) { let is_dynamic = T::is_dynamic(); @@ -272,7 +239,7 @@ Ok(( $({ let value = <$ident>::abi_read(&mut subresult)?; - if !is_dynamic {subresult.seek(<$ident as AbiType>::size())}; + if !is_dynamic {subresult.bytes_read(<$ident as AbiType>::size())}; value },)+ )) --- a/crates/evm-coder/src/abi/mod.rs +++ b/crates/evm-coder/src/abi/mod.rs @@ -208,7 +208,7 @@ } /// Notify about readed data portion. - pub fn seek(&mut self, size: usize) { + pub fn bytes_read(&mut self, size: usize) { self.subresult_offset += size; } @@ -281,6 +281,11 @@ self.write_padleft(&u32::to_be_bytes(*value)) } + /// Write [`u64`] to end of buffer + pub fn uint64(&mut self, value: &u64) { + self.write_padleft(&u64::to_be_bytes(*value)) + } + /// Write [`u128`] to end of buffer pub fn uint128(&mut self, value: &u128) { self.write_padleft(&u128::to_be_bytes(*value)) --- a/crates/evm-coder/src/abi/test.rs +++ b/crates/evm-coder/src/abi/test.rs @@ -48,11 +48,44 @@ } #[test] +fn encode_decode_uint64() { + test_impl_uint!(uint64); +} + +#[test] fn encode_decode_uint128() { test_impl_uint!(uint128); } #[test] +fn encode_decode_bool_true() { + test_impl::( + 0xdeadbeef, + true, + &hex!( + " + deadbeef + 0000000000000000000000000000000000000000000000000000000000000001 + " + ), + ); +} + +#[test] +fn encode_decode_bool_false() { + test_impl::( + 0xdeadbeef, + false, + &hex!( + " + deadbeef + 0000000000000000000000000000000000000000000000000000000000000000 + " + ), + ); +} + +#[test] fn encode_decode_uint256() { test_impl::( 0xdeadbeef, -- gitstuff