@@ -1323,7 +1323,7 @@ impl Readable for InvoiceRequestFields {
13231323
13241324#[ cfg( test) ]
13251325mod tests {
1326- use super :: { ExperimentalInvoiceRequestTlvStreamRef , INVOICE_REQUEST_TYPES , InvoiceRequest , InvoiceRequestFields , InvoiceRequestTlvStreamRef , PAYER_NOTE_LIMIT , SIGNATURE_TAG , UnsignedInvoiceRequest } ;
1326+ use super :: { EXPERIMENTAL_INVOICE_REQUEST_TYPES , ExperimentalInvoiceRequestTlvStreamRef , INVOICE_REQUEST_TYPES , InvoiceRequest , InvoiceRequestFields , InvoiceRequestTlvStreamRef , PAYER_NOTE_LIMIT , SIGNATURE_TAG , UnsignedInvoiceRequest } ;
13271327
13281328 use bitcoin:: constants:: ChainHash ;
13291329 use bitcoin:: network:: Network ;
@@ -1337,7 +1337,7 @@ mod tests {
13371337 use crate :: ln:: inbound_payment:: ExpandedKey ;
13381338 use crate :: ln:: msgs:: { DecodeError , MAX_VALUE_MSAT } ;
13391339 use crate :: offers:: invoice:: { Bolt12Invoice , SIGNATURE_TAG as INVOICE_SIGNATURE_TAG } ;
1340- use crate :: offers:: merkle:: { SignError , SignatureTlvStreamRef , TaggedHash , self } ;
1340+ use crate :: offers:: merkle:: { SignError , SignatureTlvStreamRef , TaggedHash , TlvStream , self } ;
13411341 use crate :: offers:: nonce:: Nonce ;
13421342 use crate :: offers:: offer:: { Amount , ExperimentalOfferTlvStreamRef , OfferTlvStreamRef , Quantity } ;
13431343 #[ cfg( not( c_bindings) ) ]
@@ -2472,10 +2472,79 @@ mod tests {
24722472 }
24732473 }
24742474
2475+ #[ test]
2476+ fn parses_invoice_request_with_experimental_tlv_records ( ) {
2477+ const UNKNOWN_ODD_TYPE : u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES . start + 1 ;
2478+ assert ! ( UNKNOWN_ODD_TYPE % 2 == 1 ) ;
2479+
2480+ let secp_ctx = Secp256k1 :: new ( ) ;
2481+ let keys = Keypair :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
2482+ let mut unsigned_invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
2483+ . amount_msats ( 1000 )
2484+ . build ( ) . unwrap ( )
2485+ . request_invoice ( vec ! [ 1 ; 32 ] , keys. public_key ( ) ) . unwrap ( )
2486+ . build ( ) . unwrap ( ) ;
2487+
2488+ BigSize ( UNKNOWN_ODD_TYPE ) . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2489+ BigSize ( 32 ) . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2490+ [ 42u8 ; 32 ] . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2491+
2492+ let tlv_stream = TlvStream :: new ( & unsigned_invoice_request. bytes )
2493+ . chain ( TlvStream :: new ( & unsigned_invoice_request. experimental_bytes ) ) ;
2494+ unsigned_invoice_request. tagged_hash =
2495+ TaggedHash :: from_tlv_stream ( SIGNATURE_TAG , tlv_stream) ;
2496+
2497+ let invoice_request = unsigned_invoice_request
2498+ . sign ( |message : & UnsignedInvoiceRequest |
2499+ Ok ( secp_ctx. sign_schnorr_no_aux_rand ( message. as_ref ( ) . as_digest ( ) , & keys) )
2500+ )
2501+ . unwrap ( ) ;
2502+
2503+ let mut encoded_invoice_request = Vec :: new ( ) ;
2504+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2505+
2506+ if let Err ( e) = InvoiceRequest :: try_from ( encoded_invoice_request) {
2507+ panic ! ( "error parsing invoice_request: {:?}" , e) ;
2508+ }
2509+
2510+ const UNKNOWN_EVEN_TYPE : u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES . start ;
2511+ assert ! ( UNKNOWN_EVEN_TYPE % 2 == 0 ) ;
2512+
2513+ let mut unsigned_invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
2514+ . amount_msats ( 1000 )
2515+ . build ( ) . unwrap ( )
2516+ . request_invoice ( vec ! [ 1 ; 32 ] , keys. public_key ( ) ) . unwrap ( )
2517+ . build ( ) . unwrap ( ) ;
2518+
2519+ BigSize ( UNKNOWN_EVEN_TYPE ) . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2520+ BigSize ( 32 ) . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2521+ [ 42u8 ; 32 ] . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2522+
2523+ let tlv_stream = TlvStream :: new ( & unsigned_invoice_request. bytes )
2524+ . chain ( TlvStream :: new ( & unsigned_invoice_request. experimental_bytes ) ) ;
2525+ unsigned_invoice_request. tagged_hash =
2526+ TaggedHash :: from_tlv_stream ( SIGNATURE_TAG , tlv_stream) ;
2527+
2528+ let invoice_request = unsigned_invoice_request
2529+ . sign ( |message : & UnsignedInvoiceRequest |
2530+ Ok ( secp_ctx. sign_schnorr_no_aux_rand ( message. as_ref ( ) . as_digest ( ) , & keys) )
2531+ )
2532+ . unwrap ( ) ;
2533+
2534+ let mut encoded_invoice_request = Vec :: new ( ) ;
2535+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2536+
2537+ match InvoiceRequest :: try_from ( encoded_invoice_request) {
2538+ Ok ( _) => panic ! ( "expected error" ) ,
2539+ Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: UnknownRequiredFeature ) ) ,
2540+ }
2541+ }
2542+
24752543 #[ test]
24762544 fn fails_parsing_invoice_request_with_out_of_range_tlv_records ( ) {
24772545 let secp_ctx = Secp256k1 :: new ( ) ;
24782546 let keys = Keypair :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
2547+
24792548 let invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
24802549 . amount_msats ( 1000 )
24812550 . build ( ) . unwrap ( )
@@ -2496,6 +2565,17 @@ mod tests {
24962565 Ok ( _) => panic ! ( "expected error" ) ,
24972566 Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
24982567 }
2568+
2569+ let mut encoded_invoice_request = Vec :: new ( ) ;
2570+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2571+ BigSize ( EXPERIMENTAL_INVOICE_REQUEST_TYPES . end ) . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2572+ BigSize ( 32 ) . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2573+ [ 42u8 ; 32 ] . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2574+
2575+ match InvoiceRequest :: try_from ( encoded_invoice_request) {
2576+ Ok ( _) => panic ! ( "expected error" ) ,
2577+ Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
2578+ }
24992579 }
25002580
25012581 #[ test]
0 commit comments