git.delta.rocks / unique-network / refs/commits / 626610cdfa29

difftreelog

feat Add write support for vectors with simple types.

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

1 file changed

modifiedcrates/evm-coder/src/abi.rsdiffbeforeafterboth
32const ABI_ALIGNMENT: usize = 32;32const ABI_ALIGNMENT: usize = 32;
3333
34trait TypeHelper {34trait TypeHelper {
35 /// Is type dynamic sized.
35 fn is_dynamic() -> bool;36 fn is_dynamic() -> bool;
37
38 /// Size for type aligned to [`ABI_ALIGNMENT`].
39 fn size() -> usize;
36}40}
3741
38/// View into RLP data, which provides method to read typed items from it42/// View into RLP data, which provides method to read typed items from it
316 let part_offset = self.static_part.len() - if self.had_call { 4 } else { 0 };320 let part_offset = self.static_part.len() - if self.had_call { 4 } else { 0 };
317321
318 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);322 let encoded_dynamic_offset = usize::to_be_bytes(part_offset);
323 let start = static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len();
324 let stop = static_offset + ABI_ALIGNMENT;
319 self.static_part[static_offset + ABI_ALIGNMENT - encoded_dynamic_offset.len()325 self.static_part[start..stop].copy_from_slice(&encoded_dynamic_offset);
320 ..static_offset + ABI_ALIGNMENT]
321 .copy_from_slice(&encoded_dynamic_offset);
322 self.static_part.extend(part.finish())326 self.static_part.extend(part.finish())
323 }327 }
334 /// Read item from current position, advanding decoder338 /// Read item from current position, advanding decoder
335 fn abi_read(&mut self) -> Result<T>;339 fn abi_read(&mut self) -> Result<T>;
336
337 /// Size for type aligned to [`ABI_ALIGNMENT`].
338 fn size() -> usize;
339}340}
340341
341macro_rules! impl_abi_readable {342macro_rules! impl_abi_readable {
345 $dynamic346 $dynamic
346 }347 }
348
349 fn size() -> usize {
350 ABI_ALIGNMENT
351 }
347 }352 }
348 impl AbiRead<$ty> for AbiReader<'_> {353 impl AbiRead<$ty> for AbiReader<'_> {
349 fn abi_read(&mut self) -> Result<$ty> {354 fn abi_read(&mut self) -> Result<$ty> {
350 self.$method()355 self.$method()
351 }356 }
352
353 fn size() -> usize {
354 ABI_ALIGNMENT
355 }
356 }357 }
357 };358 };
358}359}
392 Ok(out)393 Ok(out)
393 }394 }
394
395 fn size() -> usize {
396 ABI_ALIGNMENT
397 }
398}395}
399396
400macro_rules! impl_tuples {397macro_rules! impl_tuples {
401 ($($ident:ident)+) => {398 ($($ident:ident)+) => {
402 impl<$($ident: TypeHelper,)+> TypeHelper for ($($ident,)+) {399 impl<$($ident: TypeHelper,)+> TypeHelper for ($($ident,)+)
400 where
401 $(
402 $ident: TypeHelper,
403 )+
404 {
403 fn is_dynamic() -> bool {405 fn is_dynamic() -> bool {
404 false406 false
407 )*409 )*
408 }410 }
411
412 fn size() -> usize {
413 0 $(+ <$ident>::size())+
414 }
409 }415 }
410 impl<$($ident),+> sealed::CanBePlacedInVec for ($($ident,)+) {}416 impl<$($ident),+> sealed::CanBePlacedInVec for ($($ident,)+) {}
411 impl<$($ident),+> AbiRead<($($ident,)+)> for AbiReader<'_>417 impl<$($ident),+> AbiRead<($($ident,)+)> for AbiReader<'_>
416 ($($ident,)+): TypeHelper,422 ($($ident,)+): TypeHelper,
417 {423 {
418 fn abi_read(&mut self) -> Result<($($ident,)+)> {424 fn abi_read(&mut self) -> Result<($($ident,)+)> {
419 let size = if !<($($ident,)+)>::is_dynamic() { Some(<Self as AbiRead<($($ident,)+)>>::size()) } else { None };425 let size = if !<($($ident,)+)>::is_dynamic() { Some(<($($ident,)+)>::size()) } else { None };
420 let mut subresult = self.subresult(size)?;426 let mut subresult = self.subresult(size)?;
421 Ok((427 Ok((
422 $(<Self as AbiRead<$ident>>::abi_read(&mut subresult)?,)+428 $(<Self as AbiRead<$ident>>::abi_read(&mut subresult)?,)+
423 ))429 ))
424 }430 }
425
426 fn size() -> usize {
427 0 $(+ <AbiReader<'_> as AbiRead<$ident>>::size())+
428 }
429 }431 }
430 #[allow(non_snake_case)]432 #[allow(non_snake_case)]
431 impl<$($ident),+> AbiWrite for &($($ident,)+)433 impl<$($ident),+> AbiWrite for ($($ident,)+)
432 where434 where
433 $($ident: AbiWrite,)+435 $($ident: AbiWrite,)+
434 {436 {
505impl_abi_writeable!(H160, address);507impl_abi_writeable!(H160, address);
506impl_abi_writeable!(bool, bool);508impl_abi_writeable!(bool, bool);
507impl_abi_writeable!(&str, string);509impl_abi_writeable!(&str, string);
508impl AbiWrite for &string {510impl AbiWrite for string {
509 fn abi_write(&self, writer: &mut AbiWriter) {511 fn abi_write(&self, writer: &mut AbiWriter) {
510 writer.string(self)512 writer.string(self)
511 }513 }
512}514}
515// impl AbiWrite for Vec<u8> {
516// fn abi_write(&self, writer: &mut AbiWriter) {
517// writer.bytes(self)
518// }
519// }
520
513impl AbiWrite for &Vec<u8> {521impl<T: AbiWrite> AbiWrite for Vec<T> {
514 fn abi_write(&self, writer: &mut AbiWriter) {522 fn abi_write(&self, writer: &mut AbiWriter) {
523 let mut sub = AbiWriter::new();
524 (self.len() as u32).abi_write(&mut sub);
525 for item in self {
526 item.abi_write(&mut sub);
527 }
515 writer.bytes(self)528 writer.write_subresult(sub);
516 }529 }
517}530}
518531
556#[cfg(test)]569#[cfg(test)]
557pub mod test {570pub mod test {
558 use crate::{571 use crate::{
559 abi::AbiRead,572 abi::{AbiRead, AbiWrite},
560 types::{string, uint256},573 types::{string, uint256, address},
561 };574 };
562575
563 use super::{AbiReader, AbiWriter};576 use super::{AbiReader, AbiWriter};
564 use hex_literal::hex;577 use hex_literal::hex;
578 use primitive_types::{H160, U256};
565579
566 #[test]580 #[test]
567 fn dynamic_after_static() {581 fn dynamic_after_static() {
609 }623 }
610624
611 #[test]625 #[test]
612 fn mint_bulk() {626 fn parse_vec_with_dynamic_type() {
627 let decoded_data = (
628 0x36543006,
629 vec![
630 (1.into(), "Test URI 0".to_string()),
631 (11.into(), "Test URI 1".to_string()),
632 (12.into(), "Test URI 2".to_string()),
633 ],
634 );
635
636 let encoded_data = &hex!(
637 "
638 36543006
639 00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address
640 0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]
641 0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]
642
643 0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem
644 00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem
645 0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem
646
647 0000000000000000000000000000000000000000000000000000000000000001 // first token id? #60
648 0000000000000000000000000000000000000000000000000000000000000040 // offset of string
649 000000000000000000000000000000000000000000000000000000000000000a // size of string
650 5465737420555249203000000000000000000000000000000000000000000000 // string
651
652 000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11? #e0
653 0000000000000000000000000000000000000000000000000000000000000040 // offset of string
654 000000000000000000000000000000000000000000000000000000000000000a // size of string
655 5465737420555249203100000000000000000000000000000000000000000000 // string
656
657 000000000000000000000000000000000000000000000000000000000000000c // third token id? Why ==12? #160
658 0000000000000000000000000000000000000000000000000000000000000040 // offset of string
659 000000000000000000000000000000000000000000000000000000000000000a // size of string
660 5465737420555249203200000000000000000000000000000000000000000000 // string
661 "
662 );
663
613 let (call, mut decoder) = AbiReader::new_call(&hex!(664 let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();
614 "
615 36543006
616 00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address
617 0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]
618 0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]
619
620 0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem
621 00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem
622 0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem
623
624 0000000000000000000000000000000000000000000000000000000000000001 // first token id? #60
625 0000000000000000000000000000000000000000000000000000000000000040 // offset of string
626 000000000000000000000000000000000000000000000000000000000000000a // size of string
627 5465737420555249203000000000000000000000000000000000000000000000 // string
628
629 000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11? #e0
630 0000000000000000000000000000000000000000000000000000000000000040 // offset of string
631 000000000000000000000000000000000000000000000000000000000000000a // size of string
632 5465737420555249203100000000000000000000000000000000000000000000 // string
633
634 000000000000000000000000000000000000000000000000000000000000000c // third token id? Why ==12? #160
635 0000000000000000000000000000000000000000000000000000000000000040 // offset of string
636 000000000000000000000000000000000000000000000000000000000000000a // size of string
637 5465737420555249203200000000000000000000000000000000000000000000 // string
638 "
639 ))
640 .unwrap();
641 assert_eq!(call, u32::to_be_bytes(0x36543006));665 assert_eq!(call, u32::to_be_bytes(decoded_data.0));
642 let _ = decoder.address().unwrap();666 let _ = decoder.address().unwrap();
643 let data =667 let data =
644 <AbiReader<'_> as AbiRead<Vec<(uint256, string)>>>::abi_read(&mut decoder).unwrap();668 <AbiReader<'_> as AbiRead<Vec<(uint256, string)>>>::abi_read(&mut decoder).unwrap();
645 assert_eq!(669 assert_eq!(data, decoded_data.1);
646 data,670
647 vec![671 let mut writer = AbiWriter::new_call(decoded_data.0);
648 (1.into(), "Test URI 0".to_string()),672 decoded_data.1.abi_write(&mut writer);
649 (11.into(), "Test URI 1".to_string()),673 let ed = writer.finish();
650 (12.into(), "Test URI 2".to_string())674 assert_eq!(encoded_data, ed.as_slice());
651 ]
652 );
653 }675 }
654676
655 #[test]677 #[test]
656 fn parse_vec_with_simple_type() {678 fn parse_vec_with_simple_type() {
657 use crate::types::address;679 let decoded_data = (
680 0x1ACF2D55,
681 vec![
682 (
658 use primitive_types::{H160, U256};683 H160(hex!("2D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC")),
684 U256([10, 0, 0, 0]),
685 ),
686 (
687 H160(hex!("AB8E3D9134955566483B11E6825C9223B6737B10")),
688 U256([20, 0, 0, 0]),
689 ),
690 (
691 H160(hex!("8C582BDF2953046705FC56F189385255EFC1BE18")),
692 U256([30, 0, 0, 0]),
693 ),
694 ],
695 );
696
697 let encoded_data = &hex!(
698 "
699 1ACF2D55
700 0000000000000000000000000000000000000000000000000000000000000020 // offset of (address, uint256)[]
701 0000000000000000000000000000000000000000000000000000000000000003 // length of (address, uint256)[]
702
703 0000000000000000000000002D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC // address
704 000000000000000000000000000000000000000000000000000000000000000A // uint256
705
706 000000000000000000000000AB8E3D9134955566483B11E6825C9223B6737B10 // address
707 0000000000000000000000000000000000000000000000000000000000000014 // uint256
708
709 0000000000000000000000008C582BDF2953046705FC56F189385255EFC1BE18 // address
710 000000000000000000000000000000000000000000000000000000000000001E // uint256
711 "
712 );
659713
660 let (call, mut decoder) = AbiReader::new_call(&hex!(714 let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();
661 "
662 1ACF2D55
663 0000000000000000000000000000000000000000000000000000000000000020 // offset of (address, uint256)[]
664 0000000000000000000000000000000000000000000000000000000000000003 // length of (address, uint256)[]
665
666 0000000000000000000000002D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC // address
667 000000000000000000000000000000000000000000000000000000000000000A // uint256
668
669 000000000000000000000000AB8E3D9134955566483B11E6825C9223B6737B10 // address
670 0000000000000000000000000000000000000000000000000000000000000014 // uint256
671
672 0000000000000000000000008C582BDF2953046705FC56F189385255EFC1BE18 // address
673 000000000000000000000000000000000000000000000000000000000000001E // uint256
674 "
675 ))
676 .unwrap();
677 assert_eq!(call, u32::to_be_bytes(0x1ACF2D55));715 assert_eq!(call, u32::to_be_bytes(decoded_data.0));
678 let data =716 let data =
679 <AbiReader<'_> as AbiRead<Vec<(address, uint256)>>>::abi_read(&mut decoder).unwrap();717 <AbiReader<'_> as AbiRead<Vec<(address, uint256)>>>::abi_read(&mut decoder).unwrap();
680 assert_eq!(data.len(), 3);718 assert_eq!(data.len(), 3);
681 assert_eq!(719 assert_eq!(data, decoded_data.1);
682 data,720
683 vec![721 let mut writer = AbiWriter::new_call(decoded_data.0);
684 (722 decoded_data.1.abi_write(&mut writer);
685 H160(hex!("2D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC")),723 let ed = writer.finish();
686 U256([10, 0, 0, 0])724 assert_eq!(encoded_data, ed.as_slice());
687 ),
688 (
689 H160(hex!("AB8E3D9134955566483B11E6825C9223B6737B10")),
690 U256([20, 0, 0, 0])
691 ),
692 (
693 H160(hex!("8C582BDF2953046705FC56F189385255EFC1BE18")),
694 U256([30, 0, 0, 0])
695 ),
696 ]
697 );
698 }725 }
699}726}