@@ -22,6 +22,8 @@ use core::cmp;
22
22
use core:: convert:: TryFrom ;
23
23
use core:: ops:: Deref ;
24
24
25
+ use alloc:: collections:: BTreeMap ;
26
+
25
27
use bitcoin:: secp256k1:: { PublicKey , SecretKey } ;
26
28
use bitcoin:: secp256k1:: constants:: { PUBLIC_KEY_SIZE , SECRET_KEY_SIZE , COMPACT_SIGNATURE_SIZE , SCHNORR_SIGNATURE_SIZE } ;
27
29
use bitcoin:: secp256k1:: ecdsa;
@@ -381,6 +383,40 @@ impl Readable for BigSize {
381
383
}
382
384
}
383
385
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
+
384
420
/// In TLV we occasionally send fields which only consist of, or potentially end with, a
385
421
/// variable-length integer which is simply truncated by skipping high zero bytes. This type
386
422
/// encapsulates such integers implementing [`Readable`]/[`Writeable`] for them.
@@ -588,50 +624,54 @@ impl<'a, T> From<&'a Vec<T>> for WithoutLength<&'a Vec<T>> {
588
624
fn from ( v : & ' a Vec < T > ) -> Self { Self ( v) }
589
625
}
590
626
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
+ }
602
641
}
603
- Ok ( ( ) )
604
- }
605
- }
606
642
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
+ }
621
658
}
659
+ Ok ( ret)
622
660
}
623
661
}
624
- Ok ( ret)
625
662
}
626
663
}
627
664
665
+ impl_for_map ! ( BTreeMap , Ord , |_| BTreeMap :: new( ) ) ;
666
+ impl_for_map ! ( HashMap , Hash , |len| HashMap :: with_capacity( len) ) ;
667
+
628
668
// HashSet
629
669
impl < T > Writeable for HashSet < T >
630
670
where T : Writeable + Eq + Hash
631
671
{
632
672
#[ inline]
633
673
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) ?;
635
675
for item in self . iter ( ) {
636
676
item. write ( w) ?;
637
677
}
@@ -644,9 +684,9 @@ where T: Readable + Eq + Hash
644
684
{
645
685
#[ inline]
646
686
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 {
650
690
if !ret. insert ( T :: read ( r) ?) {
651
691
return Err ( DecodeError :: InvalidValue )
652
692
}
@@ -656,51 +696,62 @@ where T: Readable + Eq + Hash
656
696
}
657
697
658
698
// 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
+ }
666
711
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
+ }
675
725
}
676
726
}
677
- impl Writeable for Vec < ecdsa:: Signature > {
727
+
728
+ impl Writeable for Vec < u8 > {
678
729
#[ inline]
679
730
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 )
685
733
}
686
734
}
687
735
688
- impl Readable for Vec < ecdsa :: Signature > {
736
+ impl Readable for Vec < u8 > {
689
737
#[ inline]
690
738
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 ;
697
747
}
698
- let mut ret = Vec :: with_capacity ( len as usize ) ;
699
- for _ in 0 ..len { ret. push ( Readable :: read ( r) ?) ; }
700
748
Ok ( ret)
701
749
}
702
750
}
703
751
752
+ impl_for_vec ! ( ecdsa:: Signature ) ;
753
+ impl_for_vec ! ( ( A , B ) , A , B ) ;
754
+
704
755
impl Writeable for Script {
705
756
fn write < W : Writer > ( & self , w : & mut W ) -> Result < ( ) , io:: Error > {
706
757
( self . len ( ) as u16 ) . write ( w) ?;
@@ -1028,7 +1079,7 @@ impl Readable for () {
1028
1079
impl Writeable for String {
1029
1080
#[ inline]
1030
1081
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) ?;
1032
1083
w. write_all ( self . as_bytes ( ) )
1033
1084
}
1034
1085
}
0 commit comments