@@ -22,6 +22,8 @@ use core::cmp;
2222use core:: convert:: TryFrom ;
2323use core:: ops:: Deref ;
2424
25+ use alloc:: collections:: BTreeMap ;
26+
2527use bitcoin:: secp256k1:: { PublicKey , SecretKey } ;
2628use bitcoin:: secp256k1:: constants:: { PUBLIC_KEY_SIZE , SECRET_KEY_SIZE , COMPACT_SIGNATURE_SIZE , SCHNORR_SIGNATURE_SIZE } ;
2729use bitcoin:: secp256k1:: ecdsa;
@@ -381,6 +383,40 @@ impl Readable for BigSize {
381383 }
382384}
383385
386+ /// The lightning protocol uses u16s for lengths in most cases. As our serialization framework
387+ /// primarily targets that, we must as well. However, because we may serialize objects that have
388+ /// more than 65K entries, we need to be able to store larger values. Thus, we define a variable
389+ /// length integer here that is backwards-compatible for values < 0xffff. We treat 0xffff as
390+ /// "read eight more bytes".
391+ ///
392+ /// To ensure we only have one valid encoding per value, we add 0xffff to values written as eight
393+ /// bytes. Thus, 0xfffe is serialized as 0xfffe, whereas 0xffff is serialized as
394+ /// 0xffff0000000000000000 (i.e. read-eight-bytes then zero).
395+ struct CollectionLength ( pub u64 ) ;
396+ impl Writeable for CollectionLength {
397+ #[ inline]
398+ fn write < W : Writer > ( & self , writer : & mut W ) -> Result < ( ) , io:: Error > {
399+ if self . 0 < 0xffff {
400+ ( self . 0 as u16 ) . write ( writer)
401+ } else {
402+ 0xffffu16 . write ( writer) ?;
403+ ( self . 0 - 0xffff ) . write ( writer)
404+ }
405+ }
406+ }
407+
408+ impl Readable for CollectionLength {
409+ #[ inline]
410+ fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
411+ let mut val: u64 = <u16 as Readable >:: read ( r) ? as u64 ;
412+ if val == 0xffff {
413+ val = <u64 as Readable >:: read ( r) ?
414+ . checked_add ( 0xffff ) . ok_or ( DecodeError :: InvalidValue ) ?;
415+ }
416+ Ok ( CollectionLength ( val) )
417+ }
418+ }
419+
384420/// In TLV we occasionally send fields which only consist of, or potentially end with, a
385421/// variable-length integer which is simply truncated by skipping high zero bytes. This type
386422/// encapsulates such integers implementing [`Readable`]/[`Writeable`] for them.
@@ -588,50 +624,54 @@ impl<'a, T> From<&'a Vec<T>> for WithoutLength<&'a Vec<T>> {
588624 fn from ( v : & ' a Vec < T > ) -> Self { Self ( v) }
589625}
590626
591- // HashMap
592- impl < K , V > Writeable for HashMap < K , V >
593- where K : Writeable + Eq + Hash ,
594- V : Writeable
595- {
596- #[ inline]
597- fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
598- ( self . len ( ) as u16 ) . write ( w) ?;
599- for ( key, value) in self . iter ( ) {
600- key. write ( w) ?;
601- value. write ( w) ?;
627+ macro_rules! impl_for_map {
628+ ( $ty: ident, $keybound: ident, $constr: expr) => {
629+ impl <K , V > Writeable for $ty<K , V >
630+ where K : Writeable + Eq + $keybound, V : Writeable
631+ {
632+ #[ inline]
633+ fn write<W : Writer >( & self , w: & mut W ) -> Result <( ) , io:: Error > {
634+ CollectionLength ( self . len( ) as u64 ) . write( w) ?;
635+ for ( key, value) in self . iter( ) {
636+ key. write( w) ?;
637+ value. write( w) ?;
638+ }
639+ Ok ( ( ) )
640+ }
602641 }
603- Ok ( ( ) )
604- }
605- }
606642
607- impl < K , V > Readable for HashMap < K , V >
608- where K : Readable + Eq + Hash ,
609- V : MaybeReadable
610- {
611- #[ inline]
612- fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
613- let len: u16 = Readable :: read ( r) ?;
614- let mut ret = HashMap :: with_capacity ( len as usize ) ;
615- for _ in 0 ..len {
616- let k = K :: read ( r) ?;
617- let v_opt = V :: read ( r) ?;
618- if let Some ( v) = v_opt {
619- if ret. insert ( k, v) . is_some ( ) {
620- return Err ( DecodeError :: InvalidValue ) ;
643+ impl <K , V > Readable for $ty<K , V >
644+ where K : Readable + Eq + $keybound, V : MaybeReadable
645+ {
646+ #[ inline]
647+ fn read<R : Read >( r: & mut R ) -> Result <Self , DecodeError > {
648+ let len: CollectionLength = Readable :: read( r) ?;
649+ let mut ret = $constr( len. 0 as usize ) ;
650+ for _ in 0 ..len. 0 {
651+ let k = K :: read( r) ?;
652+ let v_opt = V :: read( r) ?;
653+ if let Some ( v) = v_opt {
654+ if ret. insert( k, v) . is_some( ) {
655+ return Err ( DecodeError :: InvalidValue ) ;
656+ }
657+ }
621658 }
659+ Ok ( ret)
622660 }
623661 }
624- Ok ( ret)
625662 }
626663}
627664
665+ impl_for_map ! ( BTreeMap , Ord , |_| BTreeMap :: new( ) ) ;
666+ impl_for_map ! ( HashMap , Hash , |len| HashMap :: with_capacity( len) ) ;
667+
628668// HashSet
629669impl < T > Writeable for HashSet < T >
630670where T : Writeable + Eq + Hash
631671{
632672 #[ inline]
633673 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
634- ( self . len ( ) as u16 ) . write ( w) ?;
674+ CollectionLength ( self . len ( ) as u64 ) . write ( w) ?;
635675 for item in self . iter ( ) {
636676 item. write ( w) ?;
637677 }
@@ -644,9 +684,9 @@ where T: Readable + Eq + Hash
644684{
645685 #[ inline]
646686 fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
647- let len: u16 = Readable :: read ( r) ?;
648- let mut ret = HashSet :: with_capacity ( len as usize ) ;
649- for _ in 0 ..len {
687+ let len: CollectionLength = Readable :: read ( r) ?;
688+ let mut ret = HashSet :: with_capacity ( cmp :: min ( len. 0 as usize , MAX_BUF_SIZE / core :: mem :: size_of :: < T > ( ) ) ) ;
689+ for _ in 0 ..len. 0 {
650690 if !ret. insert ( T :: read ( r) ?) {
651691 return Err ( DecodeError :: InvalidValue )
652692 }
@@ -656,51 +696,62 @@ where T: Readable + Eq + Hash
656696}
657697
658698// Vectors
659- impl Writeable for Vec < u8 > {
660- #[ inline]
661- fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
662- ( self . len ( ) as u16 ) . write ( w) ?;
663- w. write_all ( & self )
664- }
665- }
699+ macro_rules! impl_for_vec {
700+ ( $ty: ty $( , $name: ident) * ) => {
701+ impl <$( $name : Writeable ) ,* > Writeable for Vec <$ty> {
702+ #[ inline]
703+ fn write<W : Writer >( & self , w: & mut W ) -> Result <( ) , io:: Error > {
704+ CollectionLength ( self . len( ) as u64 ) . write( w) ?;
705+ for elem in self . iter( ) {
706+ elem. write( w) ?;
707+ }
708+ Ok ( ( ) )
709+ }
710+ }
666711
667- impl Readable for Vec < u8 > {
668- #[ inline]
669- fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
670- let len: u16 = Readable :: read ( r) ?;
671- let mut ret = Vec :: with_capacity ( len as usize ) ;
672- ret. resize ( len as usize , 0 ) ;
673- r. read_exact ( & mut ret) ?;
674- Ok ( ret)
712+ impl <$( $name : Readable ) ,* > Readable for Vec <$ty> {
713+ #[ inline]
714+ fn read<R : Read >( r: & mut R ) -> Result <Self , DecodeError > {
715+ let len: CollectionLength = Readable :: read( r) ?;
716+ let mut ret = Vec :: with_capacity( cmp:: min( len. 0 as usize , MAX_BUF_SIZE / core:: mem:: size_of:: <$ty>( ) ) ) ;
717+ for _ in 0 ..len. 0 {
718+ if let Some ( val) = MaybeReadable :: read( r) ? {
719+ ret. push( val) ;
720+ }
721+ }
722+ Ok ( ret)
723+ }
724+ }
675725 }
676726}
677- impl Writeable for Vec < ecdsa:: Signature > {
727+
728+ impl Writeable for Vec < u8 > {
678729 #[ inline]
679730 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
680- ( self . len ( ) as u16 ) . write ( w) ?;
681- for e in self . iter ( ) {
682- e. write ( w) ?;
683- }
684- Ok ( ( ) )
731+ CollectionLength ( self . len ( ) as u64 ) . write ( w) ?;
732+ w. write_all ( & self )
685733 }
686734}
687735
688- impl Readable for Vec < ecdsa :: Signature > {
736+ impl Readable for Vec < u8 > {
689737 #[ inline]
690738 fn read < R : Read > ( r : & mut R ) -> Result < Self , DecodeError > {
691- let len: u16 = Readable :: read ( r) ?;
692- let byte_size = ( len as usize )
693- . checked_mul ( COMPACT_SIGNATURE_SIZE )
694- . ok_or ( DecodeError :: BadLengthDescriptor ) ?;
695- if byte_size > MAX_BUF_SIZE {
696- return Err ( DecodeError :: BadLengthDescriptor ) ;
739+ let mut len: CollectionLength = Readable :: read ( r) ?;
740+ let mut ret = Vec :: new ( ) ;
741+ while len. 0 > 0 {
742+ let readamt = cmp:: min ( len. 0 as usize , MAX_BUF_SIZE ) ;
743+ let readstart = ret. len ( ) ;
744+ ret. resize ( readstart + readamt, 0 ) ;
745+ r. read_exact ( & mut ret[ readstart..] ) ?;
746+ len. 0 -= readamt as u64 ;
697747 }
698- let mut ret = Vec :: with_capacity ( len as usize ) ;
699- for _ in 0 ..len { ret. push ( Readable :: read ( r) ?) ; }
700748 Ok ( ret)
701749 }
702750}
703751
752+ impl_for_vec ! ( ecdsa:: Signature ) ;
753+ impl_for_vec ! ( ( A , B ) , A , B ) ;
754+
704755impl Writeable for Script {
705756 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
706757 ( self . len ( ) as u16 ) . write ( w) ?;
@@ -1028,7 +1079,7 @@ impl Readable for () {
10281079impl Writeable for String {
10291080 #[ inline]
10301081 fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
1031- ( self . len ( ) as u16 ) . write ( w) ?;
1082+ CollectionLength ( self . len ( ) as u64 ) . write ( w) ?;
10321083 w. write_all ( self . as_bytes ( ) )
10331084 }
10341085}
0 commit comments