@@ -1334,7 +1334,7 @@ impl Readable for InvoiceRequestFields {
13341334
13351335#[ cfg( test) ]
13361336mod tests {
1337- use super :: { ExperimentalInvoiceRequestTlvStreamRef , INVOICE_REQUEST_TYPES , InvoiceRequest , InvoiceRequestFields , InvoiceRequestTlvStreamRef , PAYER_NOTE_LIMIT , SIGNATURE_TAG , UnsignedInvoiceRequest } ;
1337+ use super :: { EXPERIMENTAL_INVOICE_REQUEST_TYPES , ExperimentalInvoiceRequestTlvStreamRef , INVOICE_REQUEST_TYPES , InvoiceRequest , InvoiceRequestFields , InvoiceRequestTlvStreamRef , PAYER_NOTE_LIMIT , SIGNATURE_TAG , UnsignedInvoiceRequest } ;
13381338
13391339 use bitcoin:: constants:: ChainHash ;
13401340 use bitcoin:: network:: Network ;
@@ -1348,7 +1348,7 @@ mod tests {
13481348 use crate :: ln:: inbound_payment:: ExpandedKey ;
13491349 use crate :: ln:: msgs:: { DecodeError , MAX_VALUE_MSAT } ;
13501350 use crate :: offers:: invoice:: { Bolt12Invoice , SIGNATURE_TAG as INVOICE_SIGNATURE_TAG } ;
1351- use crate :: offers:: merkle:: { SignError , SignatureTlvStreamRef , TaggedHash , self } ;
1351+ use crate :: offers:: merkle:: { SignError , SignatureTlvStreamRef , TaggedHash , TlvStream , self } ;
13521352 use crate :: offers:: nonce:: Nonce ;
13531353 use crate :: offers:: offer:: { Amount , ExperimentalOfferTlvStreamRef , OfferTlvStreamRef , Quantity } ;
13541354 #[ cfg( not( c_bindings) ) ]
@@ -2483,10 +2483,79 @@ mod tests {
24832483 }
24842484 }
24852485
2486+ #[ test]
2487+ fn parses_invoice_request_with_experimental_tlv_records ( ) {
2488+ const UNKNOWN_ODD_TYPE : u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES . start + 1 ;
2489+ assert ! ( UNKNOWN_ODD_TYPE % 2 == 1 ) ;
2490+
2491+ let secp_ctx = Secp256k1 :: new ( ) ;
2492+ let keys = Keypair :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
2493+ let mut unsigned_invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
2494+ . amount_msats ( 1000 )
2495+ . build ( ) . unwrap ( )
2496+ . request_invoice ( vec ! [ 1 ; 32 ] , keys. public_key ( ) ) . unwrap ( )
2497+ . build ( ) . unwrap ( ) ;
2498+
2499+ BigSize ( UNKNOWN_ODD_TYPE ) . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2500+ BigSize ( 32 ) . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2501+ [ 42u8 ; 32 ] . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2502+
2503+ let tlv_stream = TlvStream :: new ( & unsigned_invoice_request. bytes )
2504+ . chain ( TlvStream :: new ( & unsigned_invoice_request. experimental_bytes ) ) ;
2505+ unsigned_invoice_request. tagged_hash =
2506+ TaggedHash :: from_tlv_stream ( SIGNATURE_TAG , tlv_stream) ;
2507+
2508+ let invoice_request = unsigned_invoice_request
2509+ . sign ( |message : & UnsignedInvoiceRequest |
2510+ Ok ( secp_ctx. sign_schnorr_no_aux_rand ( message. as_ref ( ) . as_digest ( ) , & keys) )
2511+ )
2512+ . unwrap ( ) ;
2513+
2514+ let mut encoded_invoice_request = Vec :: new ( ) ;
2515+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2516+
2517+ if let Err ( e) = InvoiceRequest :: try_from ( encoded_invoice_request) {
2518+ panic ! ( "error parsing invoice_request: {:?}" , e) ;
2519+ }
2520+
2521+ const UNKNOWN_EVEN_TYPE : u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES . start ;
2522+ assert ! ( UNKNOWN_EVEN_TYPE % 2 == 0 ) ;
2523+
2524+ let mut unsigned_invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
2525+ . amount_msats ( 1000 )
2526+ . build ( ) . unwrap ( )
2527+ . request_invoice ( vec ! [ 1 ; 32 ] , keys. public_key ( ) ) . unwrap ( )
2528+ . build ( ) . unwrap ( ) ;
2529+
2530+ BigSize ( UNKNOWN_EVEN_TYPE ) . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2531+ BigSize ( 32 ) . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2532+ [ 42u8 ; 32 ] . write ( & mut unsigned_invoice_request. experimental_bytes ) . unwrap ( ) ;
2533+
2534+ let tlv_stream = TlvStream :: new ( & unsigned_invoice_request. bytes )
2535+ . chain ( TlvStream :: new ( & unsigned_invoice_request. experimental_bytes ) ) ;
2536+ unsigned_invoice_request. tagged_hash =
2537+ TaggedHash :: from_tlv_stream ( SIGNATURE_TAG , tlv_stream) ;
2538+
2539+ let invoice_request = unsigned_invoice_request
2540+ . sign ( |message : & UnsignedInvoiceRequest |
2541+ Ok ( secp_ctx. sign_schnorr_no_aux_rand ( message. as_ref ( ) . as_digest ( ) , & keys) )
2542+ )
2543+ . unwrap ( ) ;
2544+
2545+ let mut encoded_invoice_request = Vec :: new ( ) ;
2546+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2547+
2548+ match InvoiceRequest :: try_from ( encoded_invoice_request) {
2549+ Ok ( _) => panic ! ( "expected error" ) ,
2550+ Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: UnknownRequiredFeature ) ) ,
2551+ }
2552+ }
2553+
24862554 #[ test]
24872555 fn fails_parsing_invoice_request_with_out_of_range_tlv_records ( ) {
24882556 let secp_ctx = Secp256k1 :: new ( ) ;
24892557 let keys = Keypair :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
2558+
24902559 let invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
24912560 . amount_msats ( 1000 )
24922561 . build ( ) . unwrap ( )
@@ -2507,6 +2576,17 @@ mod tests {
25072576 Ok ( _) => panic ! ( "expected error" ) ,
25082577 Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
25092578 }
2579+
2580+ let mut encoded_invoice_request = Vec :: new ( ) ;
2581+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2582+ BigSize ( EXPERIMENTAL_INVOICE_REQUEST_TYPES . end ) . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2583+ BigSize ( 32 ) . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2584+ [ 42u8 ; 32 ] . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2585+
2586+ match InvoiceRequest :: try_from ( encoded_invoice_request) {
2587+ Ok ( _) => panic ! ( "expected error" ) ,
2588+ Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
2589+ }
25102590 }
25112591
25122592 #[ test]
0 commit comments