@@ -1361,7 +1361,7 @@ impl Readable for InvoiceRequestFields {
1361
1361
1362
1362
#[ cfg( test) ]
1363
1363
mod tests {
1364
- use super :: { ExperimentalInvoiceRequestTlvStreamRef , INVOICE_REQUEST_TYPES , InvoiceRequest , InvoiceRequestFields , InvoiceRequestTlvStreamRef , PAYER_NOTE_LIMIT , SIGNATURE_TAG , UnsignedInvoiceRequest } ;
1364
+ use super :: { EXPERIMENTAL_INVOICE_REQUEST_TYPES , ExperimentalInvoiceRequestTlvStreamRef , INVOICE_REQUEST_TYPES , InvoiceRequest , InvoiceRequestFields , InvoiceRequestTlvStreamRef , PAYER_NOTE_LIMIT , SIGNATURE_TAG , UnsignedInvoiceRequest } ;
1365
1365
1366
1366
use bitcoin:: constants:: ChainHash ;
1367
1367
use bitcoin:: network:: Network ;
@@ -1375,7 +1375,7 @@ mod tests {
1375
1375
use crate :: ln:: inbound_payment:: ExpandedKey ;
1376
1376
use crate :: ln:: msgs:: { DecodeError , MAX_VALUE_MSAT } ;
1377
1377
use crate :: offers:: invoice:: { Bolt12Invoice , SIGNATURE_TAG as INVOICE_SIGNATURE_TAG } ;
1378
- use crate :: offers:: merkle:: { SignError , SignatureTlvStreamRef , TaggedHash , self } ;
1378
+ use crate :: offers:: merkle:: { SignError , SignatureTlvStreamRef , TaggedHash , TlvStream , self } ;
1379
1379
use crate :: offers:: nonce:: Nonce ;
1380
1380
use crate :: offers:: offer:: { Amount , ExperimentalOfferTlvStreamRef , OfferTlvStreamRef , Quantity } ;
1381
1381
#[ cfg( not( c_bindings) ) ]
@@ -2525,10 +2525,118 @@ mod tests {
2525
2525
}
2526
2526
}
2527
2527
2528
+ #[ test]
2529
+ fn parses_invoice_request_with_experimental_tlv_records ( ) {
2530
+ const UNKNOWN_ODD_TYPE : u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES . start + 1 ;
2531
+ assert ! ( UNKNOWN_ODD_TYPE % 2 == 1 ) ;
2532
+
2533
+ let secp_ctx = Secp256k1 :: new ( ) ;
2534
+ let keys = Keypair :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
2535
+ let mut unsigned_invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
2536
+ . amount_msats ( 1000 )
2537
+ . build ( ) . unwrap ( )
2538
+ . request_invoice ( vec ! [ 1 ; 32 ] , keys. public_key ( ) ) . unwrap ( )
2539
+ . build ( ) . unwrap ( ) ;
2540
+
2541
+ let mut unknown_bytes = Vec :: new ( ) ;
2542
+ BigSize ( UNKNOWN_ODD_TYPE ) . write ( & mut unknown_bytes) . unwrap ( ) ;
2543
+ BigSize ( 32 ) . write ( & mut unknown_bytes) . unwrap ( ) ;
2544
+ [ 42u8 ; 32 ] . write ( & mut unknown_bytes) . unwrap ( ) ;
2545
+
2546
+ unsigned_invoice_request. bytes . reserve_exact (
2547
+ unsigned_invoice_request. bytes . capacity ( )
2548
+ - unsigned_invoice_request. bytes . len ( )
2549
+ + unknown_bytes. len ( ) ,
2550
+ ) ;
2551
+ unsigned_invoice_request. experimental_bytes . extend_from_slice ( & unknown_bytes) ;
2552
+
2553
+ let tlv_stream = TlvStream :: new ( & unsigned_invoice_request. bytes )
2554
+ . chain ( TlvStream :: new ( & unsigned_invoice_request. experimental_bytes ) ) ;
2555
+ unsigned_invoice_request. tagged_hash =
2556
+ TaggedHash :: from_tlv_stream ( SIGNATURE_TAG , tlv_stream) ;
2557
+
2558
+ let invoice_request = unsigned_invoice_request
2559
+ . sign ( |message : & UnsignedInvoiceRequest |
2560
+ Ok ( secp_ctx. sign_schnorr_no_aux_rand ( message. as_ref ( ) . as_digest ( ) , & keys) )
2561
+ )
2562
+ . unwrap ( ) ;
2563
+
2564
+ let mut encoded_invoice_request = Vec :: new ( ) ;
2565
+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2566
+
2567
+ match InvoiceRequest :: try_from ( encoded_invoice_request. clone ( ) ) {
2568
+ Ok ( invoice_request) => assert_eq ! ( invoice_request. bytes, encoded_invoice_request) ,
2569
+ Err ( e) => panic ! ( "error parsing invoice_request: {:?}" , e) ,
2570
+ }
2571
+
2572
+ const UNKNOWN_EVEN_TYPE : u64 = EXPERIMENTAL_INVOICE_REQUEST_TYPES . start ;
2573
+ assert ! ( UNKNOWN_EVEN_TYPE % 2 == 0 ) ;
2574
+
2575
+ let mut unsigned_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
+
2581
+ let mut unknown_bytes = Vec :: new ( ) ;
2582
+ BigSize ( UNKNOWN_EVEN_TYPE ) . write ( & mut unknown_bytes) . unwrap ( ) ;
2583
+ BigSize ( 32 ) . write ( & mut unknown_bytes) . unwrap ( ) ;
2584
+ [ 42u8 ; 32 ] . write ( & mut unknown_bytes) . unwrap ( ) ;
2585
+
2586
+ unsigned_invoice_request. bytes . reserve_exact (
2587
+ unsigned_invoice_request. bytes . capacity ( )
2588
+ - unsigned_invoice_request. bytes . len ( )
2589
+ + unknown_bytes. len ( ) ,
2590
+ ) ;
2591
+ unsigned_invoice_request. experimental_bytes . extend_from_slice ( & unknown_bytes) ;
2592
+
2593
+ let tlv_stream = TlvStream :: new ( & unsigned_invoice_request. bytes )
2594
+ . chain ( TlvStream :: new ( & unsigned_invoice_request. experimental_bytes ) ) ;
2595
+ unsigned_invoice_request. tagged_hash =
2596
+ TaggedHash :: from_tlv_stream ( SIGNATURE_TAG , tlv_stream) ;
2597
+
2598
+ let invoice_request = unsigned_invoice_request
2599
+ . sign ( |message : & UnsignedInvoiceRequest |
2600
+ Ok ( secp_ctx. sign_schnorr_no_aux_rand ( message. as_ref ( ) . as_digest ( ) , & keys) )
2601
+ )
2602
+ . unwrap ( ) ;
2603
+
2604
+ let mut encoded_invoice_request = Vec :: new ( ) ;
2605
+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2606
+
2607
+ match InvoiceRequest :: try_from ( encoded_invoice_request) {
2608
+ Ok ( _) => panic ! ( "expected error" ) ,
2609
+ Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: UnknownRequiredFeature ) ) ,
2610
+ }
2611
+
2612
+ let invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
2613
+ . amount_msats ( 1000 )
2614
+ . build ( ) . unwrap ( )
2615
+ . request_invoice ( vec ! [ 1 ; 32 ] , keys. public_key ( ) ) . unwrap ( )
2616
+ . build ( ) . unwrap ( )
2617
+ . sign ( |message : & UnsignedInvoiceRequest |
2618
+ Ok ( secp_ctx. sign_schnorr_no_aux_rand ( message. as_ref ( ) . as_digest ( ) , & keys) )
2619
+ )
2620
+ . unwrap ( ) ;
2621
+
2622
+ let mut encoded_invoice_request = Vec :: new ( ) ;
2623
+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2624
+
2625
+ BigSize ( UNKNOWN_ODD_TYPE ) . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2626
+ BigSize ( 32 ) . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2627
+ [ 42u8 ; 32 ] . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2628
+
2629
+ match InvoiceRequest :: try_from ( encoded_invoice_request) {
2630
+ Ok ( _) => panic ! ( "expected error" ) ,
2631
+ Err ( e) => assert_eq ! ( e, Bolt12ParseError :: InvalidSignature ( secp256k1:: Error :: IncorrectSignature ) ) ,
2632
+ }
2633
+ }
2634
+
2528
2635
#[ test]
2529
2636
fn fails_parsing_invoice_request_with_out_of_range_tlv_records ( ) {
2530
2637
let secp_ctx = Secp256k1 :: new ( ) ;
2531
2638
let keys = Keypair :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
2639
+
2532
2640
let invoice_request = OfferBuilder :: new ( keys. public_key ( ) )
2533
2641
. amount_msats ( 1000 )
2534
2642
. build ( ) . unwrap ( )
@@ -2549,6 +2657,17 @@ mod tests {
2549
2657
Ok ( _) => panic ! ( "expected error" ) ,
2550
2658
Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
2551
2659
}
2660
+
2661
+ let mut encoded_invoice_request = Vec :: new ( ) ;
2662
+ invoice_request. write ( & mut encoded_invoice_request) . unwrap ( ) ;
2663
+ BigSize ( EXPERIMENTAL_INVOICE_REQUEST_TYPES . end ) . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2664
+ BigSize ( 32 ) . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2665
+ [ 42u8 ; 32 ] . write ( & mut encoded_invoice_request) . unwrap ( ) ;
2666
+
2667
+ match InvoiceRequest :: try_from ( encoded_invoice_request) {
2668
+ Ok ( _) => panic ! ( "expected error" ) ,
2669
+ Err ( e) => assert_eq ! ( e, Bolt12ParseError :: Decode ( DecodeError :: InvalidValue ) ) ,
2670
+ }
2552
2671
}
2553
2672
2554
2673
#[ test]
0 commit comments