@@ -28,9 +28,7 @@ use crate::blinded_path::payment::{
2828 BlindedPaymentPath , Bolt12OfferContext , Bolt12RefundContext , PaymentContext ,
2929} ;
3030use crate :: events:: PaymentFailureReason ;
31- use crate :: ln:: channelmanager:: {
32- Bolt12PaymentError , PaymentId , Verification , OFFERS_MESSAGE_REQUEST_LIMIT ,
33- } ;
31+ use crate :: ln:: channelmanager:: { Bolt12PaymentError , PaymentId , Verification } ;
3432use crate :: ln:: inbound_payment;
3533use crate :: ln:: outbound_payment:: { Retry , RetryableInvoiceRequest , StaleExpiration } ;
3634use crate :: offers:: invoice:: {
7371///
7472/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
7573pub trait OffersMessageCommons {
76- /// Get pending offers messages
77- fn get_pending_offers_messages (
78- & self ,
79- ) -> MutexGuard < ' _ , Vec < ( OffersMessage , MessageSendInstructions ) > > ;
80-
8174 #[ cfg( feature = "dnssec" ) ]
8275 /// Get pending DNS onion messages
8376 fn get_pending_dns_onion_messages (
@@ -176,11 +169,6 @@ pub trait OffersMessageCommons {
176169 /// [`MessageRouter::create_blinded_paths`]: crate::onion_message::messenger::MessageRouter::create_blinded_paths
177170 fn create_blinded_paths ( & self , context : MessageContext ) -> Result < Vec < BlindedMessagePath > , ( ) > ;
178171
179- /// Enqueue invoice request
180- fn enqueue_invoice_request (
181- & self , invoice_request : InvoiceRequest , reply_paths : Vec < BlindedMessagePath > ,
182- ) -> Result < ( ) , Bolt12SemanticError > ;
183-
184172 /// Get the current time determined by highest seen timestamp
185173 fn get_current_blocktime ( & self ) -> Duration ;
186174
@@ -575,6 +563,11 @@ where
575563
576564 message_router : MR ,
577565
566+ #[ cfg( not( any( test, feature = "_test_utils" ) ) ) ]
567+ pending_offers_messages : Mutex < Vec < ( OffersMessage , MessageSendInstructions ) > > ,
568+ #[ cfg( any( test, feature = "_test_utils" ) ) ]
569+ pub ( crate ) pending_offers_messages : Mutex < Vec < ( OffersMessage , MessageSendInstructions ) > > ,
570+
578571 #[ cfg( feature = "_test_utils" ) ]
579572 /// In testing, it is useful be able to forge a name -> offer mapping so that we can pay an
580573 /// offer generated in the test.
@@ -607,9 +600,13 @@ where
607600 inbound_payment_key : expanded_inbound_key,
608601 our_network_pubkey,
609602 secp_ctx,
603+ entropy_source,
604+
610605 commons,
606+
611607 message_router,
612- entropy_source,
608+
609+ pending_offers_messages : Mutex :: new ( Vec :: new ( ) ) ,
613610 #[ cfg( feature = "_test_utils" ) ]
614611 testing_dnssec_proof_offer_resolution_override : Mutex :: new ( new_hash_map ( ) ) ,
615612 logger,
@@ -642,6 +639,13 @@ where
642639/// [`Refund`]: crate::offers::refund
643640pub const MAX_SHORT_LIVED_RELATIVE_EXPIRY : Duration = Duration :: from_secs ( 60 * 60 * 24 ) ;
644641
642+ /// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
643+ /// along different paths.
644+ /// Sending multiple requests increases the chances of successful delivery in case some
645+ /// paths are unavailable. However, only one invoice for a given [`PaymentId`] will be paid,
646+ /// even if multiple invoices are received.
647+ pub const OFFERS_MESSAGE_REQUEST_LIMIT : usize = 10 ;
648+
645649impl < ES : Deref , OMC : Deref , MR : Deref , L : Deref > OffersMessageFlow < ES , OMC , MR , L >
646650where
647651 ES :: Target : EntropySource ,
@@ -700,6 +704,42 @@ where
700704 )
701705 . and_then ( |paths| ( !paths. is_empty ( ) ) . then ( || paths) . ok_or ( ( ) ) )
702706 }
707+
708+ fn enqueue_invoice_request (
709+ & self , invoice_request : InvoiceRequest , reply_paths : Vec < BlindedMessagePath > ,
710+ ) -> Result < ( ) , Bolt12SemanticError > {
711+ let mut pending_offers_messages = self . pending_offers_messages . lock ( ) . unwrap ( ) ;
712+ if !invoice_request. paths ( ) . is_empty ( ) {
713+ reply_paths
714+ . iter ( )
715+ . flat_map ( |reply_path| {
716+ invoice_request. paths ( ) . iter ( ) . map ( move |path| ( path, reply_path) )
717+ } )
718+ . take ( OFFERS_MESSAGE_REQUEST_LIMIT )
719+ . for_each ( |( path, reply_path) | {
720+ let instructions = MessageSendInstructions :: WithSpecifiedReplyPath {
721+ destination : Destination :: BlindedPath ( path. clone ( ) ) ,
722+ reply_path : reply_path. clone ( ) ,
723+ } ;
724+ let message = OffersMessage :: InvoiceRequest ( invoice_request. clone ( ) ) ;
725+ pending_offers_messages. push ( ( message, instructions) ) ;
726+ } ) ;
727+ } else if let Some ( node_id) = invoice_request. issuer_signing_pubkey ( ) {
728+ for reply_path in reply_paths {
729+ let instructions = MessageSendInstructions :: WithSpecifiedReplyPath {
730+ destination : Destination :: Node ( node_id) ,
731+ reply_path,
732+ } ;
733+ let message = OffersMessage :: InvoiceRequest ( invoice_request. clone ( ) ) ;
734+ pending_offers_messages. push ( ( message, instructions) ) ;
735+ }
736+ } else {
737+ debug_assert ! ( false ) ;
738+ return Err ( Bolt12SemanticError :: MissingIssuerSigningPubkey ) ;
739+ }
740+
741+ Ok ( ( ) )
742+ }
703743}
704744
705745impl < ES : Deref , OMC : Deref , MR : Deref , L : Deref > OffersMessageFlow < ES , OMC , MR , L >
@@ -756,7 +796,7 @@ where
756796
757797 create_pending_payment ( & invoice_request, nonce) ?;
758798
759- self . commons . enqueue_invoice_request ( invoice_request, reply_paths)
799+ self . enqueue_invoice_request ( invoice_request, reply_paths)
760800 }
761801}
762802
@@ -1024,7 +1064,7 @@ where
10241064 } ) ;
10251065 match self . commons . create_blinded_paths ( context) {
10261066 Ok ( reply_paths) => {
1027- match self . commons . enqueue_invoice_request ( invoice_request, reply_paths) {
1067+ match self . enqueue_invoice_request ( invoice_request, reply_paths) {
10281068 Ok ( _) => { } ,
10291069 Err ( _) => {
10301070 log_warn ! (
@@ -1048,7 +1088,7 @@ where
10481088 }
10491089
10501090 fn release_pending_messages ( & self ) -> Vec < ( OffersMessage , MessageSendInstructions ) > {
1051- core:: mem:: take ( & mut self . commons . get_pending_offers_messages ( ) )
1091+ core:: mem:: take ( & mut self . pending_offers_messages . lock ( ) . unwrap ( ) )
10521092 }
10531093}
10541094
@@ -1382,7 +1422,7 @@ where
13821422 . create_blinded_paths ( context)
13831423 . map_err ( |_| Bolt12SemanticError :: MissingPaths ) ?;
13841424
1385- let mut pending_offers_messages = self . commons . get_pending_offers_messages ( ) ;
1425+ let mut pending_offers_messages = self . pending_offers_messages . lock ( ) . unwrap ( ) ;
13861426 if refund. paths ( ) . is_empty ( ) {
13871427 for reply_path in reply_paths {
13881428 let instructions = MessageSendInstructions :: WithSpecifiedReplyPath {
0 commit comments