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
22# We want to assert some large binary blobs equality in tests22# We want to assert some large binary blobs equality in tests
23hex = "0.4.3"23hex = "0.4.3"
24hex-literal = "0.3.4"24hex-literal = "0.3.4"
25similar-asserts = "1.4.2"
2526
26[features]27[features]
27default = ["std"]28default = ["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
134 #[cfg(feature = "std")]134 #[cfg(feature = "std")]
135 pub type string = ::std::string::String;135 pub type string = ::std::string::String;
136
137 #[derive(Default, Debug)]
136 pub type bytes = Vec<u8>;138 pub struct bytes(pub Vec<u8>);
137139
138 /// Solidity doesn't have `void` type, however we have special implementation140 /// Solidity doesn't have `void` type, however we have special implementation
139 /// for empty tuple return type141 /// for empty tuple return type
158 pub value: U256,160 pub value: U256,
159 }161 }
162
163 impl From<Vec<u8>> for bytes {
164 fn from(src: Vec<u8>) -> Self {
165 Self(src)
166 }
167 }
168
169 impl Into<Vec<u8>> for bytes {
170 fn into(self) -> Vec<u8> {
171 self.0
172 }
173 }
174
175 impl bytes {
176 #[must_use]
177 pub fn len(&self) -> usize {
178 self.0.len()
179 }
180
181 #[must_use]
182 pub fn is_empty(&self) -> bool {
183 self.len() == 0
184 }
185 }
160}186}
161187
162/// Parseable EVM call, this trait should be implemented with [`solidity_interface`] macro188/// Parseable EVM call, this trait should be implemented with [`solidity_interface`] macro
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
85 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")?;
8989
90 <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")?;
122122
123 Ok(prop.to_vec())123 Ok(bytes(prop.to_vec()))
124 }124 }
125125
126 /// Set the sponsor of the collection.126 /// Set the sponsor of the collection.
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
97 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")?;
101101
102 let nesting_budget = self102 let nesting_budget = self
103 .recorder103 .recorder
146 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")?;
148148
149 Ok(prop.to_vec())149 Ok(prop.to_vec().into())
150 }150 }
151}151}
152152
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
100 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")?;
104104
105 let nesting_budget = self105 let nesting_budget = self
106 .recorder106 .recorder
149 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")?;
151151
152 Ok(prop.to_vec())152 Ok(prop.to_vec().into())
153 }153 }
154}154}
155155