difftreelog
feat Add AbiWrite support for vec with dynamic type
in: master
6 files changed
crates/evm-coder/Cargo.tomldiffbeforeafterboth22# We want to assert some large binary blobs equality in tests22# We want to assert some large binary blobs equality in tests23hex = "0.4.3"23hex = "0.4.3"24hex-literal = "0.3.4"24hex-literal = "0.3.4"25similar-asserts = "1.4.2"252626[features]27[features]27default = ["std"]28default = ["std"]crates/evm-coder/src/abi.rsdiffbeforeafterboth252526use crate::{26use crate::{27 execution::{Error, ResultWithPostInfo, WithPostDispatchInfo},27 execution::{Error, ResultWithPostInfo, WithPostDispatchInfo},28 types::{string, self},28 types::*,29};29};30use crate::execution::Result;30use crate::execution::Result;313156 }56 }57 }57 }58 /// Start reading RLP buffer, parsing first 4 bytes as selector58 /// Start reading RLP buffer, parsing first 4 bytes as selector59 pub fn new_call(buf: &'i [u8]) -> Result<(types::bytes4, Self)> {59 pub fn new_call(buf: &'i [u8]) -> Result<(bytes4, Self)> {60 if buf.len() < 4 {60 if buf.len() < 4 {61 return Err(Error::Error(ExitError::OutOfOffset));61 return Err(Error::Error(ExitError::OutOfOffset));62 }62 }252 self.static_part.extend(block);252 self.static_part.extend(block);253 }253 }254254255 fn write_padright(&mut self, bytes: &[u8]) {255 fn write_padright(&mut self, block: &[u8]) {256 assert!(bytes.len() <= ABI_ALIGNMENT);256 assert!(block.len() <= ABI_ALIGNMENT);257 self.static_part.extend(bytes);257 self.static_part.extend(block);258 self.static_part258 self.static_part259 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - bytes.len()]);259 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);260 }260 }261261262 /// Write [`H160`] to end of buffer262 /// Write [`H160`] to end of buffer369 };369 };370}370}371371372impl_abi_readable!(bool, bool, false);372impl_abi_readable!(u8, uint8, false);373impl_abi_readable!(uint8, uint8, false);373impl_abi_readable!(u32, uint32, false);374impl_abi_readable!(uint32, uint32, false);374impl_abi_readable!(u64, uint64, false);375impl_abi_readable!(uint64, uint64, false);375impl_abi_readable!(u128, uint128, false);376impl_abi_readable!(uint128, uint128, false);376impl_abi_readable!(U256, uint256, false);377impl_abi_readable!(uint256, uint256, false);377impl_abi_readable!([u8; 4], bytes4, false);378impl_abi_readable!(bytes4, bytes4, false);378impl_abi_readable!(H160, address, false);379impl_abi_readable!(address, address, false);379impl_abi_readable!(Vec<u8>, bytes, true);380impl_abi_readable!(bool, bool, true);381impl_abi_readable!(string, string, true);380impl_abi_readable!(string, string, true);381// impl_abi_readable!(bytes, bytes, true);382383impl TypeHelper for bytes {384 fn is_dynamic() -> bool {385 true386 }387 fn size() -> usize {388 ABI_ALIGNMENT389 }390}391impl AbiRead<bytes> for AbiReader<'_> {392 fn abi_read(&mut self) -> Result<bytes> {393 Ok(bytes(self.bytes()?))394 }395}382396383mod sealed {397mod sealed {384 /// Not all types can be placed in vec, i.e `Vec<u8>` is restricted, `bytes` should be used instead398 /// Not all types can be placed in vec, i.e `Vec<u8>` is restricted, `bytes` should be used instead529 writer.string(self)544 writer.string(self)530 }545 }531}546}532// impl AbiWrite for Vec<u8> {547533// fn abi_write(&self, writer: &mut AbiWriter) {548impl AbiWrite for bytes {534// writer.bytes(self)549 fn abi_write(&self, writer: &mut AbiWriter) {535// }550 writer.bytes(self.0.as_slice())536// }551 }552}537553538impl<T: AbiWrite + TypeHelper> AbiWrite for Vec<T> {554impl<T: AbiWrite + TypeHelper> AbiWrite for Vec<T> {539 fn abi_write(&self, writer: &mut AbiWriter) {555 fn abi_write(&self, writer: &mut AbiWriter) {crates/evm-coder/src/lib.rsdiffbeforeafterboth134 #[cfg(feature = "std")]134 #[cfg(feature = "std")]135 pub type string = ::std::string::String;135 pub type string = ::std::string::String;136137 #[derive(Default, Debug)]136 pub type bytes = Vec<u8>;138 pub struct bytes(pub Vec<u8>);137139138 /// Solidity doesn't have `void` type, however we have special implementation140 /// Solidity doesn't have `void` type, however we have special implementation139 /// for empty tuple return type141 /// for empty tuple return type158 pub value: U256,160 pub value: U256,159 }161 }162163 impl From<Vec<u8>> for bytes {164 fn from(src: Vec<u8>) -> Self {165 Self(src)166 }167 }168169 impl Into<Vec<u8>> for bytes {170 fn into(self) -> Vec<u8> {171 self.0172 }173 }174175 impl bytes {176 #[must_use]177 pub fn len(&self) -> usize {178 self.0.len()179 }180181 #[must_use]182 pub fn is_empty(&self) -> bool {183 self.len() == 0184 }185 }160}186}161187162/// Parseable EVM call, this trait should be implemented with [`solidity_interface`] macro188/// Parseable EVM call, this trait should be implemented with [`solidity_interface`] macropallets/common/src/erc.rsdiffbeforeafterboth85 let key = <Vec<u8>>::from(key)85 let key = <Vec<u8>>::from(key)86 .try_into()86 .try_into()87 .map_err(|_| "key too large")?;87 .map_err(|_| "key too large")?;88 let value = value.try_into().map_err(|_| "value too large")?;88 let value = value.0.try_into().map_err(|_| "value too large")?;898990 <Pallet<T>>::set_collection_property(self, &caller, Property { key, value })90 <Pallet<T>>::set_collection_property(self, &caller, Property { key, value })91 .map_err(dispatch_to_evm::<T>)91 .map_err(dispatch_to_evm::<T>)120 let props = <CollectionProperties<T>>::get(self.id);120 let props = <CollectionProperties<T>>::get(self.id);121 let prop = props.get(&key).ok_or("key not found")?;121 let prop = props.get(&key).ok_or("key not found")?;122122123 Ok(prop.to_vec())123 Ok(bytes(prop.to_vec()))124 }124 }125125126 /// Set the sponsor of the collection.126 /// Set the sponsor of the collection.pallets/nonfungible/src/erc.rsdiffbeforeafterboth97 let key = <Vec<u8>>::from(key)97 let key = <Vec<u8>>::from(key)98 .try_into()98 .try_into()99 .map_err(|_| "key too long")?;99 .map_err(|_| "key too long")?;100 let value = value.try_into().map_err(|_| "value too long")?;100 let value = value.0.try_into().map_err(|_| "value too long")?;101101102 let nesting_budget = self102 let nesting_budget = self103 .recorder103 .recorder146 let props = <TokenProperties<T>>::get((self.id, token_id));146 let props = <TokenProperties<T>>::get((self.id, token_id));147 let prop = props.get(&key).ok_or("key not found")?;147 let prop = props.get(&key).ok_or("key not found")?;148148149 Ok(prop.to_vec())149 Ok(prop.to_vec().into())150 }150 }151}151}152152pallets/refungible/src/erc.rsdiffbeforeafterboth100 let key = <Vec<u8>>::from(key)100 let key = <Vec<u8>>::from(key)101 .try_into()101 .try_into()102 .map_err(|_| "key too long")?;102 .map_err(|_| "key too long")?;103 let value = value.try_into().map_err(|_| "value too long")?;103 let value = value.0.try_into().map_err(|_| "value too long")?;104104105 let nesting_budget = self105 let nesting_budget = self106 .recorder106 .recorder149 let props = <TokenProperties<T>>::get((self.id, token_id));149 let props = <TokenProperties<T>>::get((self.id, token_id));150 let prop = props.get(&key).ok_or("key not found")?;150 let prop = props.get(&key).ok_or("key not found")?;151151152 Ok(prop.to_vec())152 Ok(prop.to_vec().into())153 }153 }154}154}155155