@@ -1354,7 +1354,7 @@ impl Readable for InvoiceRequestFields {
13541354
13551355#[ cfg( test) ]
13561356mod tests {
1357- use super :: { ExperimentalInvoiceRequestTlvStreamRef , INVOICE_REQUEST_TYPES , InvoiceRequest , InvoiceRequestFields , InvoiceRequestTlvStreamRef , PAYER_NOTE_LIMIT , SIGNATURE_TAG , UnsignedInvoiceRequest } ;
1357+ use super :: { EXPERIMENTAL_INVOICE_REQUEST_TYPES , ExperimentalInvoiceRequestTlvStreamRef , INVOICE_REQUEST_TYPES , InvoiceRequest , InvoiceRequestFields , InvoiceRequestTlvStreamRef , PAYER_NOTE_LIMIT , SIGNATURE_TAG , UnsignedInvoiceRequest } ;
13581358
13591359 use bitcoin:: constants:: ChainHash ;
13601360 use bitcoin:: network:: Network ;
@@ -1368,7 +1368,7 @@ mod tests {
13681368 use crate :: ln:: inbound_payment:: ExpandedKey ;
13691369 use crate :: ln:: msgs:: { DecodeError , MAX_VALUE_MSAT } ;
13701370 use crate :: offers:: invoice:: { Bolt12Invoice , SIGNATURE_TAG as INVOICE_SIGNATURE_TAG } ;
1371- use crate :: offers:: merkle:: { SignError , SignatureTlvStreamRef , TaggedHash , self } ;
1371+ use crate :: offers:: merkle:: { SignError , SignatureTlvStreamRef , TaggedHash , TlvStream , self } ;
13721372 use crate :: offers:: nonce:: Nonce ;
13731373 use crate :: offers:: offer:: { Amount , ExperimentalOfferTlvStreamRef , OfferTlvStreamRef , Quantity } ;
13741374 #[ cfg( not( c_bindings) ) ]
@@ -2504,10 +2504,102 @@ mod tests {
25042504 }
25052505 }
25062506
2507+ #[ test]
2508+ fn parses_invoice_request_with_experimental_tlv_records ( ) {
2509+ const UNKNOWN_ODD_TYPE : u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES . start + 1 ;
2510+ assert ! ( UNKNOWN_ODD_TYPE % 2 == 1 ) ;
2511+
2512+ let secp_ctx = Secp256k1 :: new ( ) ;
2513+ let keys = Keypair :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
2514+ let mut unsigned_invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
2515+ . amount_msats ( 1000 )
2516+ . build ( ) . unwrap ( )
2517+ . request_invoice ( vec ! [ 1 ; 32 ] , keys. public_key ( ) ) . unwrap ( )
2518+ . build ( ) . unwrap ( ) ;
2519+
2520+ BigSize ( UNKNOWN_ODD_TYPE ) . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2521+ BigSize ( 32 ) . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2522+ [ 42u8 ; 32 ] . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2523+
2524+ let tlv_stream = TlvStream :: new ( & unsigned_invoice_request. bytes )
2525+ . chain ( TlvStream :: new ( & unsigned_invoice_request. experimental_bytes ) ) ;
2526+ unsigned_invoice_request. tagged_hash =
2527+ TaggedHash :: from_tlv_stream ( SIGNATURE_TAG , tlv_stream) ;
2528+
2529+ let invoice_request = unsigned_invoice_request
2530+ . sign ( |message : & UnsignedInvoiceRequest |
2531+ Ok ( secp_ctx. sign_schnorr_no_aux_rand ( message. as_ref ( ) . as_digest ( ) , & keys) )
2532+ )
2533+ . unwrap ( ) ;
2534+
2535+ let mut encoded_invoice_request = Vec :: new ( ) ;
2536+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2537+
2538+ match InvoiceRequest :: try_from ( encoded_invoice_request. clone ( ) ) {
2539+ Ok ( invoice_request) => assert_eq ! ( invoice_request. bytes, encoded_invoice_request) ,
2540+ Err ( e) => panic ! ( "error parsing invoice_request: {:?}" , e) ,
2541+ }
2542+
2543+ const UNKNOWN_EVEN_TYPE : u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES . start ;
2544+ assert ! ( UNKNOWN_EVEN_TYPE % 2 == 0 ) ;
2545+
2546+ let mut unsigned_invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
2547+ . amount_msats ( 1000 )
2548+ . build ( ) . unwrap ( )
2549+ . request_invoice ( vec ! [ 1 ; 32 ] , keys. public_key ( ) ) . unwrap ( )
2550+ . build ( ) . unwrap ( ) ;
2551+
2552+ BigSize ( UNKNOWN_EVEN_TYPE ) . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2553+ BigSize ( 32 ) . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2554+ [ 42u8 ; 32 ] . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2555+
2556+ let tlv_stream = TlvStream :: new ( & unsigned_invoice_request. bytes )
2557+ . chain ( TlvStream :: new ( & unsigned_invoice_request. experimental_bytes ) ) ;
2558+ unsigned_invoice_request. tagged_hash =
2559+ TaggedHash :: from_tlv_stream ( SIGNATURE_TAG , tlv_stream) ;
2560+
2561+ let invoice_request = unsigned_invoice_request
2562+ . sign ( |message : & UnsignedInvoiceRequest |
2563+ Ok ( secp_ctx. sign_schnorr_no_aux_rand ( message. as_ref ( ) . as_digest ( ) , & keys) )
2564+ )
2565+ . unwrap ( ) ;
2566+
2567+ let mut encoded_invoice_request = Vec :: new ( ) ;
2568+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2569+
2570+ match InvoiceRequest :: try_from ( encoded_invoice_request) {
2571+ Ok ( _) => panic ! ( "expected error" ) ,
2572+ Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: UnknownRequiredFeature ) ) ,
2573+ }
2574+
2575+ let invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
2576+ . amount_msats ( 1000 )
2577+ . build ( ) . unwrap ( )
2578+ . request_invoice ( vec ! [ 1 ; 32 ] , keys. public_key ( ) ) . unwrap ( )
2579+ . build ( ) . unwrap ( )
2580+ . sign ( |message : & UnsignedInvoiceRequest |
2581+ Ok ( secp_ctx. sign_schnorr_no_aux_rand ( message. as_ref ( ) . as_digest ( ) , & keys) )
2582+ )
2583+ . unwrap ( ) ;
2584+
2585+ let mut encoded_invoice_request = Vec :: new ( ) ;
2586+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2587+
2588+ BigSize ( UNKNOWN_ODD_TYPE ) . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2589+ BigSize ( 32 ) . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2590+ [ 42u8 ; 32 ] . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2591+
2592+ match InvoiceRequest :: try_from ( encoded_invoice_request) {
2593+ Ok ( _) => panic ! ( "expected error" ) ,
2594+ Err ( e) => assert_eq ! ( e, Bolt12ParseError :: InvalidSignature ( secp256k1:: Error :: IncorrectSignature ) ) ,
2595+ }
2596+ }
2597+
25072598 #[ test]
25082599 fn fails_parsing_invoice_request_with_out_of_range_tlv_records ( ) {
25092600 let secp_ctx = Secp256k1 :: new ( ) ;
25102601 let keys = Keypair :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
2602+
25112603 let invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
25122604 . amount_msats ( 1000 )
25132605 . build ( ) . unwrap ( )
@@ -2528,6 +2620,17 @@ mod tests {
25282620 Ok ( _) => panic ! ( "expected error" ) ,
25292621 Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
25302622 }
2623+
2624+ let mut encoded_invoice_request = Vec :: new ( ) ;
2625+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2626+ BigSize ( EXPERIMENTAL_INVOICE_REQUEST_TYPES . end ) . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2627+ BigSize ( 32 ) . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2628+ [ 42u8 ; 32 ] . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2629+
2630+ match InvoiceRequest :: try_from ( encoded_invoice_request) {
2631+ Ok ( _) => panic ! ( "expected error" ) ,
2632+ Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
2633+ }
25312634 }
25322635
25332636 #[ test]
0 commit comments