git.delta.rocks / unique-network / refs/commits / 88bc48d88c16

difftreelog

feat Add write support for vector of dynamic types

Trubnikov Sergey2022-10-24parent: #626610c.patch.diff
in: master

1 file changed

modifiedcrates/evm-coder/src/abi.rsdiffbeforeafterboth
222 static_part: Vec<u8>,222 static_part: Vec<u8>,
223 dynamic_part: Vec<(usize, AbiWriter)>,223 dynamic_part: Vec<(usize, AbiWriter)>,
224 had_call: bool,224 had_call: bool,
225 is_dynamic: bool,
225}226}
226impl AbiWriter {227impl AbiWriter {
227 /// Initialize internal buffers for output data, assuming no padding required228 /// Initialize internal buffers for output data, assuming no padding required
228 pub fn new() -> Self {229 pub fn new() -> Self {
229 Self::default()230 Self::default()
230 }231 }
232
233 /// Initialize internal buffers with data size
234 pub fn new_dynamic(is_dynamic: bool) -> Self {
235 Self {
236 is_dynamic,
237 ..Default::default()
238 }
239 }
231 /// Initialize internal buffers, inserting method selector at beginning240 /// Initialize internal buffers, inserting method selector at beginning
232 pub fn new_call(method_id: u32) -> Self {241 pub fn new_call(method_id: u32) -> Self {
233 let mut val = Self::new();242 let mut val = Self::new();
319 for (static_offset, part) in self.dynamic_part {328 for (static_offset, part) in self.dynamic_part {
320 let part_offset = self.static_part.len() - if self.had_call { 4 } else { 0 };329 let part_offset = self.static_part.len()
330 - if self.had_call { 4 } else { 0 }
331 - if self.is_dynamic { ABI_ALIGNMENT } else { 0 };
321332
322 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);333 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);
323 let start = static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len();334 let start = static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len();
436 {447 {
437 fn abi_write(&self, writer: &mut AbiWriter) {448 fn abi_write(&self, writer: &mut AbiWriter) {
438 let ($($ident,)+) = self;449 let ($($ident,)+) = self;
450 if writer.is_dynamic {
451 let mut sub = AbiWriter::new();
452 $($ident.abi_write(&mut sub);)+
453 writer.write_subresult(sub);
454 } else {
439 $($ident.abi_write(writer);)+455 $($ident.abi_write(writer);)+
456 }
440 }457 }
441 }458 }
442 };459 };
518// }535// }
519// }536// }
520537
521impl<T: AbiWrite> AbiWrite for Vec<T> {538impl<T: AbiWrite + TypeHelper> AbiWrite for Vec<T> {
522 fn abi_write(&self, writer: &mut AbiWriter) {539 fn abi_write(&self, writer: &mut AbiWriter) {
540 let is_dynamic = T::is_dynamic();
523 let mut sub = AbiWriter::new();541 let mut sub = if is_dynamic {
542 AbiWriter::new_dynamic(is_dynamic)
543 } else {
544 AbiWriter::new()
545 };
546
547 // Write items count
524 (self.len() as u32).abi_write(&mut sub);548 (self.len() as u32).abi_write(&mut sub);
549
525 for item in self {550 for item in self {
663688
664 let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();689 let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();
665 assert_eq!(call, u32::to_be_bytes(decoded_data.0));690 assert_eq!(call, u32::to_be_bytes(decoded_data.0));
666 let _ = decoder.address().unwrap();691 let address = decoder.address().unwrap();
667 let data =692 let data =
668 <AbiReader<'_> as AbiRead<Vec<(uint256, string)>>>::abi_read(&mut decoder).unwrap();693 <AbiReader<'_> as AbiRead<Vec<(uint256, string)>>>::abi_read(&mut decoder).unwrap();
669 assert_eq!(data, decoded_data.1);694 assert_eq!(data, decoded_data.1);
670695
671 let mut writer = AbiWriter::new_call(decoded_data.0);696 let mut writer = AbiWriter::new_call(decoded_data.0);
697 address.abi_write(&mut writer);
672 decoded_data.1.abi_write(&mut writer);698 decoded_data.1.abi_write(&mut writer);
673 let ed = writer.finish();699 let ed = writer.finish();
674 assert_eq!(encoded_data, ed.as_slice());700 similar_asserts::assert_eq!(encoded_data, ed.as_slice());
675 }701 }
676702
677 #[test]703 #[test]