@@ -27,9 +27,7 @@ use crate::blinded_path::payment::{
27
27
BlindedPaymentPath , Bolt12OfferContext , Bolt12RefundContext , PaymentContext ,
28
28
} ;
29
29
use 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 } ;
33
31
use crate :: ln:: outbound_payment:: { Retry , RetryableInvoiceRequest , StaleExpiration } ;
34
32
use crate :: offers:: invoice:: {
35
33
Bolt12Invoice , DerivedSigningPubkey , ExplicitSigningPubkey , InvoiceBuilder ,
71
69
///
72
70
/// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
73
71
pub trait OffersMessageCommons {
74
- /// Get pending offers messages
75
- fn get_pending_offers_messages (
76
- & self ,
77
- ) -> MutexGuard < ' _ , Vec < ( OffersMessage , MessageSendInstructions ) > > ;
78
-
79
72
#[ cfg( feature = "dnssec" ) ]
80
73
/// Get pending DNS onion messages
81
74
fn get_pending_dns_onion_messages (
@@ -174,11 +167,6 @@ pub trait OffersMessageCommons {
174
167
/// [`MessageRouter::create_blinded_paths`]: crate::onion_message::messenger::MessageRouter::create_blinded_paths
175
168
fn create_blinded_paths ( & self , context : MessageContext ) -> Result < Vec < BlindedMessagePath > , ( ) > ;
176
169
177
- /// Enqueue invoice request
178
- fn enqueue_invoice_request (
179
- & self , invoice_request : InvoiceRequest , reply_paths : Vec < BlindedMessagePath > ,
180
- ) -> Result < ( ) , Bolt12SemanticError > ;
181
-
182
170
/// Get the current time determined by highest seen timestamp
183
171
fn get_current_blocktime ( & self ) -> Duration ;
184
172
@@ -569,6 +557,11 @@ where
569
557
570
558
message_router : MR ,
571
559
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
+
572
565
#[ cfg( feature = "_test_utils" ) ]
573
566
/// In testing, it is useful be able to forge a name -> offer mapping so that we can pay an
574
567
/// offer generated in the test.
@@ -601,9 +594,13 @@ where
601
594
inbound_payment_key : expanded_inbound_key,
602
595
our_network_pubkey,
603
596
secp_ctx,
597
+ entropy_source,
598
+
604
599
commons,
600
+
605
601
message_router,
606
- entropy_source,
602
+
603
+ pending_offers_messages : Mutex :: new ( Vec :: new ( ) ) ,
607
604
#[ cfg( feature = "_test_utils" ) ]
608
605
testing_dnssec_proof_offer_resolution_override : Mutex :: new ( new_hash_map ( ) ) ,
609
606
logger,
@@ -636,6 +633,13 @@ where
636
633
/// [`Refund`]: crate::offers::refund
637
634
pub const MAX_SHORT_LIVED_RELATIVE_EXPIRY : Duration = Duration :: from_secs ( 60 * 60 * 24 ) ;
638
635
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
+
639
643
impl < ES : Deref , OMC : Deref , MR : Deref , L : Deref > OffersMessageFlow < ES , OMC , MR , L >
640
644
where
641
645
ES :: Target : EntropySource ,
@@ -694,6 +698,42 @@ where
694
698
)
695
699
. and_then ( |paths| ( !paths. is_empty ( ) ) . then ( || paths) . ok_or ( ( ) ) )
696
700
}
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
+ }
697
737
}
698
738
699
739
impl < ES : Deref , OMC : Deref , MR : Deref , L : Deref > OffersMessageFlow < ES , OMC , MR , L >
@@ -750,7 +790,7 @@ where
750
790
751
791
create_pending_payment ( & invoice_request, nonce) ?;
752
792
753
- self . commons . enqueue_invoice_request ( invoice_request, reply_paths)
793
+ self . enqueue_invoice_request ( invoice_request, reply_paths)
754
794
}
755
795
}
756
796
@@ -1018,7 +1058,7 @@ where
1018
1058
} ) ;
1019
1059
match self . commons . create_blinded_paths ( context) {
1020
1060
Ok ( reply_paths) => {
1021
- match self . commons . enqueue_invoice_request ( invoice_request, reply_paths) {
1061
+ match self . enqueue_invoice_request ( invoice_request, reply_paths) {
1022
1062
Ok ( _) => { } ,
1023
1063
Err ( _) => {
1024
1064
log_warn ! (
@@ -1042,7 +1082,7 @@ where
1042
1082
}
1043
1083
1044
1084
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 ( ) )
1046
1086
}
1047
1087
}
1048
1088
@@ -1376,7 +1416,7 @@ where
1376
1416
. create_blinded_paths ( context)
1377
1417
. map_err ( |_| Bolt12SemanticError :: MissingPaths ) ?;
1378
1418
1379
- let mut pending_offers_messages = self . commons . get_pending_offers_messages ( ) ;
1419
+ let mut pending_offers_messages = self . pending_offers_messages . lock ( ) . unwrap ( ) ;
1380
1420
if refund. paths ( ) . is_empty ( ) {
1381
1421
for reply_path in reply_paths {
1382
1422
let instructions = MessageSendInstructions :: WithSpecifiedReplyPath {
0 commit comments