11//! Decode data using [`RuntimeMetadataV14`].
2- use bitvec:: prelude:: { BitVec , Lsb0 , Msb0 } ;
2+ use bitvec:: prelude:: { BitStore , BitVec , Lsb0 , Msb0 } ;
33use frame_metadata:: v14:: RuntimeMetadataV14 ;
44use num_bigint:: { BigInt , BigUint } ;
5- use parity_scale_codec:: { Decode , OptionBool } ;
5+ use parity_scale_codec:: { Decode , DecodeAll , OptionBool } ;
66use scale_info:: {
77 form:: PortableForm , interner:: UntrackedSymbol , Field , PortableRegistry , Type , TypeDef ,
88 TypeDefBitSequence , TypeDefPrimitive , Variant ,
99} ;
1010use sp_arithmetic:: { PerU16 , Perbill , Percent , Permill , Perquintill } ;
1111use sp_core:: { crypto:: AccountId32 , H160 , H512 } ;
12+ use std:: mem:: size_of;
1213
1314use crate :: cards:: {
1415 Call , Documented , Event , ExtendedData , FieldData , Info , PalletSpecificData , ParsedData ,
@@ -690,29 +691,7 @@ fn decode_type_def_bit_sequence(
690691 position : & mut usize ,
691692 registry : & PortableRegistry ,
692693) -> Result < ParsedData , ParserError > {
693- let found_compact = find_compact :: < u32 > ( data, * position) ?;
694- let bit_length_found = found_compact. compact ;
695- let byte_length = match bit_length_found % 8 {
696- 0 => bit_length_found / 8 ,
697- _ => ( bit_length_found / 8 ) + 1 ,
698- } as usize ;
699-
700694 let bitvec_start = * position;
701- let bitvec_end = found_compact. start_next_unit + byte_length;
702-
703- let into_decode = match data. get ( bitvec_start..bitvec_end) {
704- Some ( a) => {
705- let into_decode = a. to_vec ( ) ;
706- * position = bitvec_end;
707- into_decode
708- }
709- None => {
710- return Err ( ParserError :: DataTooShort {
711- position : bitvec_start,
712- minimal_length : bitvec_end - bitvec_start,
713- } )
714- }
715- } ;
716695
717696 // BitOrder
718697 let bitorder_type = resolve_ty ( registry, bit_ty. bit_order_type ( ) . id ( ) ) ?;
@@ -732,44 +711,147 @@ fn decode_type_def_bit_sequence(
732711 let bitstore_type = resolve_ty ( registry, bit_ty. bit_store_type ( ) . id ( ) ) ?;
733712
734713 match bitstore_type. type_def ( ) {
735- TypeDef :: Primitive ( TypeDefPrimitive :: U8 ) => match bitorder {
736- FoundBitOrder :: Lsb0 => {
737- <BitVec < u8 , Lsb0 > >:: decode ( & mut & into_decode[ ..] ) . map ( ParsedData :: BitVecU8Lsb0 )
738- }
739- FoundBitOrder :: Msb0 => {
740- <BitVec < u8 , Msb0 > >:: decode ( & mut & into_decode[ ..] ) . map ( ParsedData :: BitVecU8Msb0 )
714+ TypeDef :: Primitive ( TypeDefPrimitive :: U8 ) => {
715+ let into_decode = into_bitvec_decode :: < u8 > ( data, position) ?;
716+ match bitorder {
717+ FoundBitOrder :: Lsb0 => <BitVec < u8 , Lsb0 > >:: decode_all ( & mut & into_decode[ ..] )
718+ . map ( ParsedData :: BitVecU8Lsb0 )
719+ . map_err ( |_| ParserError :: TypeFailure {
720+ position : bitvec_start,
721+ ty : "BitVec<u8, Lsb0>" ,
722+ } ) ,
723+ FoundBitOrder :: Msb0 => <BitVec < u8 , Msb0 > >:: decode_all ( & mut & into_decode[ ..] )
724+ . map ( ParsedData :: BitVecU8Msb0 )
725+ . map_err ( |_| ParserError :: TypeFailure {
726+ position : bitvec_start,
727+ ty : "BitVec<u8, Msb0>" ,
728+ } ) ,
741729 }
742- } ,
730+ }
743731 TypeDef :: Primitive ( TypeDefPrimitive :: U16 ) => {
732+ let into_decode = into_bitvec_decode :: < u16 > ( data, position) ?;
744733 match bitorder {
745- FoundBitOrder :: Lsb0 => <BitVec < u16 , Lsb0 > >:: decode ( & mut & into_decode[ ..] )
746- . map ( ParsedData :: BitVecU16Lsb0 ) ,
747- FoundBitOrder :: Msb0 => <BitVec < u16 , Msb0 > >:: decode ( & mut & into_decode[ ..] )
748- . map ( ParsedData :: BitVecU16Msb0 ) ,
734+ FoundBitOrder :: Lsb0 => <BitVec < u16 , Lsb0 > >:: decode_all ( & mut & into_decode[ ..] )
735+ . map ( ParsedData :: BitVecU16Lsb0 )
736+ . map_err ( |_| ParserError :: TypeFailure {
737+ position : bitvec_start,
738+ ty : "BitVec<u16, Lsb0>" ,
739+ } ) ,
740+ FoundBitOrder :: Msb0 => <BitVec < u16 , Msb0 > >:: decode_all ( & mut & into_decode[ ..] )
741+ . map ( ParsedData :: BitVecU16Msb0 )
742+ . map_err ( |_| ParserError :: TypeFailure {
743+ position : bitvec_start,
744+ ty : "BitVec<u16, Msb0>" ,
745+ } ) ,
749746 }
750747 }
751748 TypeDef :: Primitive ( TypeDefPrimitive :: U32 ) => {
749+ let into_decode = into_bitvec_decode :: < u32 > ( data, position) ?;
752750 match bitorder {
753- FoundBitOrder :: Lsb0 => <BitVec < u32 , Lsb0 > >:: decode ( & mut & into_decode[ ..] )
754- . map ( ParsedData :: BitVecU32Lsb0 ) ,
755- FoundBitOrder :: Msb0 => <BitVec < u32 , Msb0 > >:: decode ( & mut & into_decode[ ..] )
756- . map ( ParsedData :: BitVecU32Msb0 ) ,
751+ FoundBitOrder :: Lsb0 => <BitVec < u32 , Lsb0 > >:: decode_all ( & mut & into_decode[ ..] )
752+ . map ( ParsedData :: BitVecU32Lsb0 )
753+ . map_err ( |_| ParserError :: TypeFailure {
754+ position : bitvec_start,
755+ ty : "BitVec<u32, Lsb0>" ,
756+ } ) ,
757+ FoundBitOrder :: Msb0 => <BitVec < u32 , Msb0 > >:: decode_all ( & mut & into_decode[ ..] )
758+ . map ( ParsedData :: BitVecU32Msb0 )
759+ . map_err ( |_| ParserError :: TypeFailure {
760+ position : bitvec_start,
761+ ty : "BitVec<u32, Msb0>" ,
762+ } ) ,
757763 }
758764 }
759765 TypeDef :: Primitive ( TypeDefPrimitive :: U64 ) => {
766+ let into_decode = into_bitvec_decode :: < u64 > ( data, position) ?;
760767 match bitorder {
761- FoundBitOrder :: Lsb0 => <BitVec < u64 , Lsb0 > >:: decode ( & mut & into_decode[ ..] )
762- . map ( ParsedData :: BitVecU64Lsb0 ) ,
763- FoundBitOrder :: Msb0 => <BitVec < u64 , Msb0 > >:: decode ( & mut & into_decode[ ..] )
764- . map ( ParsedData :: BitVecU64Msb0 ) ,
768+ FoundBitOrder :: Lsb0 => <BitVec < u64 , Lsb0 > >:: decode_all ( & mut & into_decode[ ..] )
769+ . map ( ParsedData :: BitVecU64Lsb0 )
770+ . map_err ( |_| ParserError :: TypeFailure {
771+ position : bitvec_start,
772+ ty : "BitVec<u64, Lsb0>" ,
773+ } ) ,
774+ FoundBitOrder :: Msb0 => <BitVec < u64 , Msb0 > >:: decode_all ( & mut & into_decode[ ..] )
775+ . map ( ParsedData :: BitVecU64Msb0 )
776+ . map_err ( |_| ParserError :: TypeFailure {
777+ position : bitvec_start,
778+ ty : "BitVec<u64, Msb0>" ,
779+ } ) ,
765780 }
766781 }
767- _ => return Err ( ParserError :: NotBitStoreType { id } ) ,
782+ _ => Err ( ParserError :: NotBitStoreType { id } ) ,
783+ }
784+ }
785+
786+ /// Positions and related values for decoding `BitVec`.
787+ struct BitVecPositions {
788+ /// Encoded `BitVec` start position, includes bit length compact.
789+ bitvec_start : usize ,
790+
791+ /// Encoded `BitVec` end position.
792+ bitvec_end : usize ,
793+
794+ /// Minimal encoded data length.
795+ minimal_length : usize ,
796+ }
797+
798+ impl BitVecPositions {
799+ /// New `BitVecPositions` for given input data and position.
800+ ///
801+ /// `T` is corresponding `BitStore`.
802+ fn new < T : BitStore > ( data : & [ u8 ] , position : usize ) -> Result < Self , ParserError > {
803+ let found_compact = find_compact :: < u32 > ( data, position) ?;
804+
805+ let bitvec_start = position;
806+ let data_start = found_compact. start_next_unit ;
807+
808+ let bit_length = found_compact. compact as usize ;
809+
810+ const BITS_IN_BYTE : usize = 8 ;
811+ let byte_length = match bit_length % BITS_IN_BYTE {
812+ 0 => bit_length / BITS_IN_BYTE ,
813+ _ => ( bit_length / BITS_IN_BYTE ) + 1usize ,
814+ } ;
815+
816+ let bytes_per_element = size_of :: < T > ( ) ;
817+ let number_of_elements = match byte_length % bytes_per_element {
818+ 0 => byte_length / bytes_per_element,
819+ _ => ( byte_length / bytes_per_element) + 1usize ,
820+ } ;
821+
822+ let slice_length = number_of_elements * bytes_per_element;
823+
824+ let bitvec_end = data_start + slice_length;
825+
826+ let minimal_length = bitvec_end - bitvec_start;
827+
828+ Ok ( Self {
829+ bitvec_start,
830+ bitvec_end,
831+ minimal_length,
832+ } )
833+ }
834+ }
835+
836+ /// Select the slice to decode as a `BitVec`.
837+ ///
838+ /// Current parser position gets changed.
839+ fn into_bitvec_decode < ' a , T : BitStore > (
840+ data : & ' a [ u8 ] ,
841+ position : & ' a mut usize ,
842+ ) -> Result < & ' a [ u8 ] , ParserError > {
843+ let bitvec_positions = BitVecPositions :: new :: < T > ( data, * position) ?;
844+
845+ match data. get ( bitvec_positions. bitvec_start ..bitvec_positions. bitvec_end ) {
846+ Some ( into_bitvec_decode) => {
847+ * position = bitvec_positions. bitvec_end ;
848+ Ok ( into_bitvec_decode)
849+ }
850+ None => Err ( ParserError :: DataTooShort {
851+ position : bitvec_positions. bitvec_start ,
852+ minimal_length : bitvec_positions. minimal_length ,
853+ } ) ,
768854 }
769- . map_err ( |_| ParserError :: TypeFailure {
770- position : bitvec_start,
771- ty : "BitVec" ,
772- } )
773855}
774856
775857/// Type of set element, resolved as completely as possible.
0 commit comments