@@ -27,9 +27,7 @@ use crate::blinded_path::payment::{
2727 BlindedPaymentPath , Bolt12OfferContext , Bolt12RefundContext , PaymentContext ,
2828} ;
2929use crate :: events:: PaymentFailureReason ;
30- use crate :: ln:: channelmanager:: {
31- Bolt12PaymentError , PaymentId , Verification , OFFERS_MESSAGE_REQUEST_LIMIT ,
32- } ;
30+ use crate :: ln:: channelmanager:: { Bolt12PaymentError , PaymentId , Verification } ;
3331use crate :: ln:: outbound_payment:: { Retry , RetryableInvoiceRequest , StaleExpiration } ;
3432use crate :: offers:: invoice:: {
3533 Bolt12Invoice , DerivedSigningPubkey , ExplicitSigningPubkey , InvoiceBuilder ,
7169///
7270/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
7371pub trait OffersMessageCommons {
74- /// Get pending offers messages
75- fn get_pending_offers_messages (
76- & self ,
77- ) -> MutexGuard < ' _ , Vec < ( OffersMessage , MessageSendInstructions ) > > ;
78-
7972 #[ cfg( feature = "dnssec" ) ]
8073 /// Get pending DNS onion messages
8174 fn get_pending_dns_onion_messages (
@@ -174,11 +167,6 @@ pub trait OffersMessageCommons {
174167 /// [`MessageRouter::create_blinded_paths`]: crate::onion_message::messenger::MessageRouter::create_blinded_paths
175168 fn create_blinded_paths ( & self , context : MessageContext ) -> Result < Vec < BlindedMessagePath > , ( ) > ;
176169
177- /// Enqueue invoice request
178- fn enqueue_invoice_request (
179- & self , invoice_request : InvoiceRequest , reply_paths : Vec < BlindedMessagePath > ,
180- ) -> Result < ( ) , Bolt12SemanticError > ;
181-
182170 /// Get the current time determined by highest seen timestamp
183171 fn get_current_blocktime ( & self ) -> Duration ;
184172
@@ -569,6 +557,11 @@ where
569557
570558 message_router : MR ,
571559
560+ #[ cfg( not( any( test, feature = "_test_utils" ) ) ) ]
561+ pending_offers_messages : Mutex < Vec < ( OffersMessage , MessageSendInstructions ) > > ,
562+ #[ cfg( any( test, feature = "_test_utils" ) ) ]
563+ pub ( crate ) pending_offers_messages : Mutex < Vec < ( OffersMessage , MessageSendInstructions ) > > ,
564+
572565 #[ cfg( feature = "_test_utils" ) ]
573566 /// In testing, it is useful be able to forge a name -> offer mapping so that we can pay an
574567 /// offer generated in the test.
@@ -601,9 +594,13 @@ where
601594 inbound_payment_key : expanded_inbound_key,
602595 our_network_pubkey,
603596 secp_ctx,
597+ entropy_source,
598+
604599 commons,
600+
605601 message_router,
606- entropy_source,
602+
603+ pending_offers_messages : Mutex :: new ( Vec :: new ( ) ) ,
607604 #[ cfg( feature = "_test_utils" ) ]
608605 testing_dnssec_proof_offer_resolution_override : Mutex :: new ( new_hash_map ( ) ) ,
609606 logger,
@@ -636,6 +633,13 @@ where
636633/// [`Refund`]: crate::offers::refund
637634pub const MAX_SHORT_LIVED_RELATIVE_EXPIRY : Duration = Duration :: from_secs ( 60 * 60 * 24 ) ;
638635
636+ /// Defines the maximum number of [`OffersMessage`] including different reply paths to be sent
637+ /// along different paths.
638+ /// Sending multiple requests increases the chances of successful delivery in case some
639+ /// paths are unavailable. However, only one invoice for a given [`PaymentId`] will be paid,
640+ /// even if multiple invoices are received.
641+ pub const OFFERS_MESSAGE_REQUEST_LIMIT : usize = 10 ;
642+
639643impl < ES : Deref , OMC : Deref , MR : Deref , L : Deref > OffersMessageFlow < ES , OMC , MR , L >
640644where
641645 ES :: Target : EntropySource ,
@@ -694,6 +698,42 @@ where
694698 )
695699 . and_then ( |paths| ( !paths. is_empty ( ) ) . then ( || paths) . ok_or ( ( ) ) )
696700 }
701+
702+ fn enqueue_invoice_request (
703+ & self , invoice_request : InvoiceRequest , reply_paths : Vec < BlindedMessagePath > ,
704+ ) -> Result < ( ) , Bolt12SemanticError > {
705+ let mut pending_offers_messages = self . pending_offers_messages . lock ( ) . unwrap ( ) ;
706+ if !invoice_request. paths ( ) . is_empty ( ) {
707+ reply_paths
708+ . iter ( )
709+ . flat_map ( |reply_path| {
710+ invoice_request. paths ( ) . iter ( ) . map ( move |path| ( path, reply_path) )
711+ } )
712+ . take ( OFFERS_MESSAGE_REQUEST_LIMIT )
713+ . for_each ( |( path, reply_path) | {
714+ let instructions = MessageSendInstructions :: WithSpecifiedReplyPath {
715+ destination : Destination :: BlindedPath ( path. clone ( ) ) ,
716+ reply_path : reply_path. clone ( ) ,
717+ } ;
718+ let message = OffersMessage :: InvoiceRequest ( invoice_request. clone ( ) ) ;
719+ pending_offers_messages. push ( ( message, instructions) ) ;
720+ } ) ;
721+ } else if let Some ( node_id) = invoice_request. issuer_signing_pubkey ( ) {
722+ for reply_path in reply_paths {
723+ let instructions = MessageSendInstructions :: WithSpecifiedReplyPath {
724+ destination : Destination :: Node ( node_id) ,
725+ reply_path,
726+ } ;
727+ let message = OffersMessage :: InvoiceRequest ( invoice_request. clone ( ) ) ;
728+ pending_offers_messages. push ( ( message, instructions) ) ;
729+ }
730+ } else {
731+ debug_assert ! ( false ) ;
732+ return Err ( Bolt12SemanticError :: MissingIssuerSigningPubkey ) ;
733+ }
734+
735+ Ok ( ( ) )
736+ }
697737}
698738
699739impl < ES : Deref , OMC : Deref , MR : Deref , L : Deref > OffersMessageFlow < ES , OMC , MR , L >
@@ -750,7 +790,7 @@ where
750790
751791 create_pending_payment ( & invoice_request, nonce) ?;
752792
753- self . commons . enqueue_invoice_request ( invoice_request, reply_paths)
793+ self . enqueue_invoice_request ( invoice_request, reply_paths)
754794 }
755795}
756796
@@ -1018,7 +1058,7 @@ where
10181058 } ) ;
10191059 match self . commons . create_blinded_paths ( context) {
10201060 Ok ( reply_paths) => {
1021- match self . commons . enqueue_invoice_request ( invoice_request, reply_paths) {
1061+ match self . enqueue_invoice_request ( invoice_request, reply_paths) {
10221062 Ok ( _) => { } ,
10231063 Err ( _) => {
10241064 log_warn ! (
@@ -1042,7 +1082,7 @@ where
10421082 }
10431083
10441084 fn release_pending_messages ( & self ) -> Vec < ( OffersMessage , MessageSendInstructions ) > {
1045- core:: mem:: take ( & mut self . commons . get_pending_offers_messages ( ) )
1085+ core:: mem:: take ( & mut self . pending_offers_messages . lock ( ) . unwrap ( ) )
10461086 }
10471087}
10481088
@@ -1376,7 +1416,7 @@ where
13761416 . create_blinded_paths ( context)
13771417 . map_err ( |_| Bolt12SemanticError :: MissingPaths ) ?;
13781418
1379- let mut pending_offers_messages = self . commons . get_pending_offers_messages ( ) ;
1419+ let mut pending_offers_messages = self . pending_offers_messages . lock ( ) . unwrap ( ) ;
13801420 if refund. paths ( ) . is_empty ( ) {
13811421 for reply_path in reply_paths {
13821422 let instructions = MessageSendInstructions :: WithSpecifiedReplyPath {
0 commit comments