@@ -8,12 +8,14 @@ use core::num::ParseIntError;
8
8
use core:: str;
9
9
use core:: str:: FromStr ;
10
10
11
- use bech32:: { u5, FromBase32 } ;
11
+ use bech32:: Bech32 ;
12
+ use bech32:: primitives:: decode:: { CheckedHrpstring , CheckedHrpstringError } ;
12
13
13
14
use bitcoin:: { PubkeyHash , ScriptHash , WitnessVersion } ;
14
15
use bitcoin:: hashes:: Hash ;
15
16
use bitcoin:: hashes:: sha256;
16
17
use crate :: prelude:: * ;
18
+ use lightning:: util:: bech32:: { Bech32Error , FromBase32 , u5} ;
17
19
use lightning:: ln:: types:: PaymentSecret ;
18
20
use lightning:: routing:: gossip:: RoutingFees ;
19
21
use lightning:: routing:: router:: { RouteHint , RouteHintHop } ;
@@ -270,31 +272,32 @@ impl FromStr for SignedRawBolt11Invoice {
270
272
type Err = Bolt11ParseError ;
271
273
272
274
fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
273
- let ( hrp, data, var) = bech32:: decode ( s) ?;
274
275
275
- if var == bech32:: Variant :: Bech32m {
276
- // Consider Bech32m addresses to be "Invalid Checksum", since that is what we'd get if
277
- // we didn't support Bech32m (which lightning does not use).
278
- return Err ( Bolt11ParseError :: Bech32Error ( bech32:: Error :: InvalidChecksum ) ) ;
279
- }
276
+ let parsed = CheckedHrpstring :: new :: < Bech32 > ( s) ?;
277
+ let hrp = parsed. hrp ( ) ;
278
+ // access the parse data part as chars, covert to u5
279
+ let data: Vec < _ > = parsed. data_part_ascii_no_checksum ( ) . iter ( )
280
+ . map ( |ch| u5:: try_from_char ( char:: from ( * ch) ) . expect ( "value should be < 32" ) )
281
+ . collect ( ) ;
280
282
281
- if data. len ( ) < 104 {
283
+ const MIN_LEN : usize = 104 ;
284
+ if data. len ( ) < MIN_LEN {
282
285
return Err ( Bolt11ParseError :: TooShortDataPart ) ;
283
286
}
284
287
285
- let raw_hrp: RawHrp = hrp. parse ( ) ?;
286
- let data_part = RawDataPart :: from_base32 ( & data[ ..data. len ( ) -104 ] ) ?;
288
+ let raw_hrp: RawHrp = hrp. to_string ( ) . to_lowercase ( ) . parse ( ) ?;
289
+ let data_part = RawDataPart :: from_base32 ( & data[ ..data. len ( ) -MIN_LEN ] ) ?;
287
290
288
291
Ok ( SignedRawBolt11Invoice {
289
292
raw_invoice : RawBolt11Invoice {
290
293
hrp : raw_hrp,
291
294
data : data_part,
292
295
} ,
293
296
hash : RawBolt11Invoice :: hash_from_parts (
294
- hrp. as_bytes ( ) ,
295
- & data[ ..data. len ( ) -104 ]
297
+ hrp. to_string ( ) . as_bytes ( ) ,
298
+ & data[ ..data. len ( ) -MIN_LEN ]
296
299
) ,
297
- signature : Bolt11InvoiceSignature :: from_base32 ( & data[ data. len ( ) -104 ..] ) ?,
300
+ signature : Bolt11InvoiceSignature :: from_base32 ( & data[ data. len ( ) -MIN_LEN ..] ) ?,
298
301
} )
299
302
}
300
303
}
@@ -389,7 +392,7 @@ macro_rules! define_parse_int_be { ($name: ident, $ty: ty) => {
389
392
digits. iter( ) . fold( Some ( Default :: default ( ) ) , |acc, b|
390
393
acc
391
394
. and_then( |x| x. checked_mul( 32 ) )
392
- . and_then( |x| x. checked_add( ( Into :: < u8 > :: into ( * b) ) . into( ) ) )
395
+ . and_then( |x| x. checked_add( ( * b) . as_u8 ( ) . into( ) ) )
393
396
)
394
397
}
395
398
} }
@@ -424,7 +427,7 @@ fn parse_tagged_parts(data: &[u5]) -> Result<Vec<RawTaggedField>, Bolt11ParseErr
424
427
Ok ( field) => {
425
428
parts. push ( RawTaggedField :: KnownSemantics ( field) )
426
429
} ,
427
- Err ( Bolt11ParseError :: Skip ) |Err ( Bolt11ParseError :: Bech32Error ( bech32 :: Error :: InvalidLength ) ) => {
430
+ Err ( Bolt11ParseError :: Skip ) |Err ( Bolt11ParseError :: Bech32Error ( _ ) ) => {
428
431
parts. push ( RawTaggedField :: UnknownSemantics ( field. into ( ) ) )
429
432
} ,
430
433
Err ( e) => { return Err ( e) }
@@ -444,7 +447,7 @@ impl FromBase32 for TaggedField {
444
447
let tag = field[ 0 ] ;
445
448
let field_data = & field[ 3 ..] ;
446
449
447
- match tag. to_u8 ( ) {
450
+ match tag. as_u8 ( ) {
448
451
constants:: TAG_PAYMENT_HASH =>
449
452
Ok ( TaggedField :: PaymentHash ( Sha256 :: from_base32 ( field_data) ?) ) ,
450
453
constants:: TAG_DESCRIPTION =>
@@ -550,7 +553,7 @@ impl FromBase32 for Fallback {
550
553
return Err ( Bolt11ParseError :: UnexpectedEndOfTaggedFields ) ;
551
554
}
552
555
553
- let version = field_data[ 0 ] . to_u8 ( ) ;
556
+ let version = field_data[ 0 ] . as_u8 ( ) ;
554
557
let bytes = Vec :: < u8 > :: from_base32 ( & field_data[ 1 ..] ) ?;
555
558
556
559
match version {
@@ -629,6 +632,9 @@ impl Display for Bolt11ParseError {
629
632
Bolt11ParseError :: Bech32Error ( ref e) => {
630
633
write ! ( f, "Invalid bech32: {}" , e)
631
634
}
635
+ Bolt11ParseError :: Bech32ExternalError ( ref e) => {
636
+ write ! ( f, "Invalid bech32: {}" , e)
637
+ }
632
638
Bolt11ParseError :: ParseAmountError ( ref e) => {
633
639
write ! ( f, "Invalid amount in hrp ({})" , e)
634
640
}
@@ -703,10 +709,17 @@ from_error!(Bolt11ParseError::MalformedSignature, secp256k1::Error);
703
709
from_error ! ( Bolt11ParseError :: ParseAmountError , ParseIntError ) ;
704
710
from_error ! ( Bolt11ParseError :: DescriptionDecodeError , str :: Utf8Error ) ;
705
711
706
- impl From < bech32:: Error > for Bolt11ParseError {
707
- fn from ( e : bech32:: Error ) -> Self {
712
+ impl From < CheckedHrpstringError > for Bolt11ParseError {
713
+ fn from ( e : CheckedHrpstringError ) -> Self {
714
+ match e {
715
+ _ => Bolt11ParseError :: Bech32ExternalError ( e)
716
+ }
717
+ }
718
+ }
719
+
720
+ impl From < Bech32Error > for Bolt11ParseError {
721
+ fn from ( e : Bech32Error ) -> Self {
708
722
match e {
709
- bech32:: Error :: InvalidPadding => Bolt11ParseError :: PaddingError ,
710
723
_ => Bolt11ParseError :: Bech32Error ( e)
711
724
}
712
725
}
@@ -726,9 +739,9 @@ impl From<crate::Bolt11SemanticError> for ParseOrSemanticError {
726
739
727
740
#[ cfg( test) ]
728
741
mod test {
742
+ use super :: { u5, FromBase32 } ;
729
743
use crate :: de:: Bolt11ParseError ;
730
744
use secp256k1:: PublicKey ;
731
- use bech32:: u5;
732
745
use bitcoin:: hashes:: sha256;
733
746
use std:: str:: FromStr ;
734
747
@@ -779,7 +792,6 @@ mod test {
779
792
#[ test]
780
793
fn test_parse_sha256_hash ( ) {
781
794
use crate :: Sha256 ;
782
- use bech32:: FromBase32 ;
783
795
784
796
let input = from_bech32 (
785
797
"qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypq" . as_bytes ( )
@@ -802,7 +814,6 @@ mod test {
802
814
#[ test]
803
815
fn test_parse_description ( ) {
804
816
use crate :: Description ;
805
- use bech32:: FromBase32 ;
806
817
807
818
let input = from_bech32 ( "xysxxatsyp3k7enxv4js" . as_bytes ( ) ) ;
808
819
let expected = Ok ( Description :: new ( "1 cup coffee" . to_owned ( ) ) . unwrap ( ) ) ;
@@ -812,7 +823,6 @@ mod test {
812
823
#[ test]
813
824
fn test_parse_payee_pub_key ( ) {
814
825
use crate :: PayeePubKey ;
815
- use bech32:: FromBase32 ;
816
826
817
827
let input = from_bech32 ( "q0n326hr8v9zprg8gsvezcch06gfaqqhde2aj730yg0durunfhv66" . as_bytes ( ) ) ;
818
828
let pk_bytes = [
@@ -836,7 +846,6 @@ mod test {
836
846
#[ test]
837
847
fn test_parse_expiry_time ( ) {
838
848
use crate :: ExpiryTime ;
839
- use bech32:: FromBase32 ;
840
849
841
850
let input = from_bech32 ( "pu" . as_bytes ( ) ) ;
842
851
let expected = Ok ( ExpiryTime :: from_seconds ( 60 ) ) ;
@@ -849,7 +858,6 @@ mod test {
849
858
#[ test]
850
859
fn test_parse_min_final_cltv_expiry_delta ( ) {
851
860
use crate :: MinFinalCltvExpiryDelta ;
852
- use bech32:: FromBase32 ;
853
861
854
862
let input = from_bech32 ( "pr" . as_bytes ( ) ) ;
855
863
let expected = Ok ( MinFinalCltvExpiryDelta ( 35 ) ) ;
@@ -860,7 +868,6 @@ mod test {
860
868
#[ test]
861
869
fn test_parse_fallback ( ) {
862
870
use crate :: Fallback ;
863
- use bech32:: FromBase32 ;
864
871
use bitcoin:: { PubkeyHash , ScriptHash , WitnessVersion } ;
865
872
use bitcoin:: hashes:: Hash ;
866
873
@@ -921,7 +928,6 @@ mod test {
921
928
use lightning:: routing:: gossip:: RoutingFees ;
922
929
use lightning:: routing:: router:: { RouteHint , RouteHintHop } ;
923
930
use crate :: PrivateRoute ;
924
- use bech32:: FromBase32 ;
925
931
926
932
let input = from_bech32 (
927
933
"q20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqa\
@@ -967,7 +973,7 @@ mod test {
967
973
assert_eq ! ( PrivateRoute :: from_base32( & input) , Ok ( PrivateRoute ( RouteHint ( expected) ) ) ) ;
968
974
969
975
assert_eq ! (
970
- PrivateRoute :: from_base32( & [ u5:: try_from_u8 ( 0 ) . unwrap ( ) ; 40 ] [ ..] ) ,
976
+ PrivateRoute :: from_base32( & [ u5:: ZERO ; 40 ] [ ..] ) ,
971
977
Err ( Bolt11ParseError :: UnexpectedEndOfTaggedFields )
972
978
) ;
973
979
}
0 commit comments