@@ -168,6 +168,14 @@ impl<R: Router, ES: EntropySource, MD: LSPS2Bolt12PaymentMetadataDecoder> Router
168168 first_hops : Vec < ChannelDetails > , tlvs : ReceiveTlvs , amount_msats : Option < u64 > ,
169169 secp_ctx : & Secp256k1 < T > ,
170170 ) -> Result < Vec < BlindedPaymentPath > , ( ) > {
171+ let all_params = self . metadata_lsps2_params ( & tlvs. payment_context ) ;
172+ if all_params. is_empty ( )
173+ && first_hops. is_empty ( )
174+ && matches ! ( & tlvs. payment_context, PaymentContext :: AsyncBolt12Offer ( _) )
175+ {
176+ return Err ( ( ) ) ;
177+ }
178+
171179 // Retrieve paths through existing channels from the inner router.
172180 let inner_res = self . inner_router . create_blinded_payment_paths (
173181 recipient,
@@ -180,7 +188,6 @@ impl<R: Router, ES: EntropySource, MD: LSPS2Bolt12PaymentMetadataDecoder> Router
180188
181189 // If no LSPS2 parameters were present in the payment metadata, just fallback to the inner
182190 // router's paths.
183- let all_params = self . metadata_lsps2_params ( & tlvs. payment_context ) ;
184191 if all_params. is_empty ( ) {
185192 return inner_res;
186193 }
@@ -259,12 +266,14 @@ mod tests {
259266 use bitcoin:: secp256k1:: { PublicKey , Secp256k1 , SecretKey } ;
260267
261268 use lightning:: blinded_path:: payment:: {
262- Bolt12OfferContext , Bolt12RefundContext , PaymentConstraints , PaymentContext , ReceiveTlvs ,
269+ AsyncBolt12OfferContext , BlindedPaymentPath , Bolt12OfferContext , Bolt12RefundContext ,
270+ PaymentConstraints , PaymentContext , ReceiveTlvs ,
263271 } ;
264272 use lightning:: blinded_path:: NodeIdLookUp ;
265273 use lightning:: ln:: channel_state:: ChannelDetails ;
266274 use lightning:: ln:: channelmanager:: MIN_FINAL_CLTV_EXPIRY_DELTA ;
267275 use lightning:: offers:: invoice_request:: InvoiceRequestFields ;
276+ use lightning:: offers:: nonce:: Nonce ;
268277 use lightning:: offers:: offer:: OfferId ;
269278 use lightning:: routing:: router:: { InFlightHtlcs , Route , RouteParameters , Router } ;
270279 use lightning:: sign:: { EntropySource , NodeSigner , ReceiveAuthKey , Recipient } ;
@@ -383,6 +392,19 @@ mod tests {
383392 }
384393 }
385394
395+ fn async_bolt12_offer_tlvs (
396+ offer_nonce : Nonce , payment_metadata : Option < BTreeMap < u64 , Vec < u8 > > > ,
397+ ) -> ReceiveTlvs {
398+ ReceiveTlvs {
399+ payment_secret : PaymentSecret ( [ 2 ; 32 ] ) ,
400+ payment_constraints : PaymentConstraints { max_cltv_expiry : 100 , htlc_minimum_msat : 1 } ,
401+ payment_context : PaymentContext :: AsyncBolt12Offer ( AsyncBolt12OfferContext {
402+ offer_nonce,
403+ payment_metadata,
404+ } ) ,
405+ }
406+ }
407+
386408 fn bolt12_refund_tlvs ( ) -> ReceiveTlvs {
387409 ReceiveTlvs {
388410 payment_secret : PaymentSecret ( [ 2 ; 32 ] ) ,
@@ -498,6 +520,43 @@ mod tests {
498520 assert_eq ! ( router. inner_router. create_blinded_payment_paths_calls( ) , 1 ) ;
499521 }
500522
523+ #[ test]
524+ fn errors_for_async_offer_without_metadata_or_first_hops ( ) {
525+ let inner_router = MockRouter :: new ( ) ;
526+ let recipient = pubkey ( 10 ) ;
527+ let secp_ctx = Secp256k1 :: new ( ) ;
528+ let tlvs = async_bolt12_offer_tlvs ( Nonce :: from_entropy_source ( TestEntropy ) , None ) ;
529+ let inner_path = BlindedPaymentPath :: new (
530+ & [ ] ,
531+ recipient,
532+ ReceiveAuthKey ( [ 3 ; 32 ] ) ,
533+ tlvs. clone ( ) ,
534+ u64:: MAX ,
535+ MIN_FINAL_CLTV_EXPIRY_DELTA ,
536+ & TestEntropy ,
537+ & secp_ctx,
538+ )
539+ . unwrap ( ) ;
540+ * inner_router. paths_to_return . lock ( ) . unwrap ( ) = Some ( vec ! [ inner_path] ) ;
541+
542+ let router = LSPS2BOLT12Router :: new_with_payment_metadata_decoder (
543+ inner_router,
544+ TestEntropy ,
545+ TestMetadataDecoder ,
546+ ) ;
547+ let result = router. create_blinded_payment_paths (
548+ recipient,
549+ ReceiveAuthKey ( [ 3 ; 32 ] ) ,
550+ Vec :: new ( ) ,
551+ tlvs,
552+ Some ( 10_000 ) ,
553+ & secp_ctx,
554+ ) ;
555+
556+ assert ! ( result. is_err( ) ) ;
557+ assert_eq ! ( router. inner_router. create_blinded_payment_paths_calls( ) , 0 ) ;
558+ }
559+
501560 #[ test]
502561 fn creates_paths_for_all_metadata_intercept_scids ( ) {
503562 let inner_router = MockRouter :: new ( ) ;
0 commit comments