git.delta.rocks / unique-network / refs/commits / b9165a7bd396

difftreelog

feat Add AbiWrite support for vec with dynamic type

Trubnikov Sergey2022-10-24parent: #88bc48d.patch.diff
in: master

6 files changed

modifiedcrates/evm-coder/Cargo.tomldiffbeforeafterboth
--- a/crates/evm-coder/Cargo.toml
+++ b/crates/evm-coder/Cargo.toml
@@ -22,6 +22,7 @@
 # We want to assert some large binary blobs equality in tests
 hex = "0.4.3"
 hex-literal = "0.3.4"
+similar-asserts = "1.4.2"
 
 [features]
 default = ["std"]
modifiedcrates/evm-coder/src/abi.rsdiffbeforeafterboth
2525
26use 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;
3131
56 }56 }
57 }57 }
58 /// Start reading RLP buffer, parsing first 4 bytes as selector58 /// Start reading RLP buffer, parsing first 4 bytes as selector
59 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 }
254254
255 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_part
259 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - bytes.len()]);259 .extend(&[0; ABI_ALIGNMENT][0..ABI_ALIGNMENT - block.len()]);
260 }260 }
261261
262 /// Write [`H160`] to end of buffer262 /// Write [`H160`] to end of buffer
369 };369 };
370}370}
371371
372impl_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);
382
383impl TypeHelper for bytes {
384 fn is_dynamic() -> bool {
385 true
386 }
387 fn size() -> usize {
388 ABI_ALIGNMENT
389 }
390}
391impl AbiRead<bytes> for AbiReader<'_> {
392 fn abi_read(&mut self) -> Result<bytes> {
393 Ok(bytes(self.bytes()?))
394 }
395}
382396
383mod 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 instead
529 writer.string(self)544 writer.string(self)
530 }545 }
531}546}
532// impl AbiWrite for Vec<u8> {547
533// 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}
537553
538impl<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) {
modifiedcrates/evm-coder/src/lib.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/lib.rs
+++ b/crates/evm-coder/src/lib.rs
@@ -133,8 +133,10 @@
 	pub type string = ::alloc::string::String;
 	#[cfg(feature = "std")]
 	pub type string = ::std::string::String;
-	pub type bytes = Vec<u8>;
 
+	#[derive(Default, Debug)]
+	pub struct bytes(pub Vec<u8>);
+
 	/// Solidity doesn't have `void` type, however we have special implementation
 	/// for empty tuple return type
 	pub type void = ();
@@ -157,6 +159,30 @@
 		/// and there is no `receiver()` function defined.
 		pub value: U256,
 	}
+
+	impl From<Vec<u8>> for bytes {
+		fn from(src: Vec<u8>) -> Self {
+			Self(src)
+		}
+	}
+
+	impl Into<Vec<u8>> for bytes {
+		fn into(self) -> Vec<u8> {
+			self.0
+		}
+	}
+
+	impl bytes {
+		#[must_use]
+		pub fn len(&self) -> usize {
+			self.0.len()
+		}
+
+		#[must_use]
+		pub fn is_empty(&self) -> bool {
+			self.len() == 0
+		}
+	}
 }
 
 /// Parseable EVM call, this trait should be implemented with [`solidity_interface`] macro
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -85,7 +85,7 @@
 		let key = <Vec<u8>>::from(key)
 			.try_into()
 			.map_err(|_| "key too large")?;
-		let value = value.try_into().map_err(|_| "value too large")?;
+		let value = value.0.try_into().map_err(|_| "value too large")?;
 
 		<Pallet<T>>::set_collection_property(self, &caller, Property { key, value })
 			.map_err(dispatch_to_evm::<T>)
@@ -120,7 +120,7 @@
 		let props = <CollectionProperties<T>>::get(self.id);
 		let prop = props.get(&key).ok_or("key not found")?;
 
-		Ok(prop.to_vec())
+		Ok(bytes(prop.to_vec()))
 	}
 
 	/// Set the sponsor of the collection.
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -97,7 +97,7 @@
 		let key = <Vec<u8>>::from(key)
 			.try_into()
 			.map_err(|_| "key too long")?;
-		let value = value.try_into().map_err(|_| "value too long")?;
+		let value = value.0.try_into().map_err(|_| "value too long")?;
 
 		let nesting_budget = self
 			.recorder
@@ -146,7 +146,7 @@
 		let props = <TokenProperties<T>>::get((self.id, token_id));
 		let prop = props.get(&key).ok_or("key not found")?;
 
-		Ok(prop.to_vec())
+		Ok(prop.to_vec().into())
 	}
 }
 
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -100,7 +100,7 @@
 		let key = <Vec<u8>>::from(key)
 			.try_into()
 			.map_err(|_| "key too long")?;
-		let value = value.try_into().map_err(|_| "value too long")?;
+		let value = value.0.try_into().map_err(|_| "value too long")?;
 
 		let nesting_budget = self
 			.recorder
@@ -149,7 +149,7 @@
 		let props = <TokenProperties<T>>::get((self.id, token_id));
 		let prop = props.get(&key).ok_or("key not found")?;
 
-		Ok(prop.to_vec())
+		Ok(prop.to_vec().into())
 	}
 }