@@ -73,9 +73,9 @@ pub(crate) enum PendingOutboundPayment {
73
73
route_params_config : RouteParametersConfig ,
74
74
retryable_invoice_request : Option < RetryableInvoiceRequest >
75
75
} ,
76
- // This state will never be persisted to disk because we transition from `AwaitingInvoice` to
77
- // `Retryable` atomically within the `ChannelManager::total_consistency_lock`. Useful to avoid
78
- // holding the `OutboundPayments::pending_outbound_payments` lock during pathfinding.
76
+ // Represents the state after the invoice has been received, transitioning from the corresponding
77
+ // `AwaitingInvoice` state.
78
+ // Helps avoid holding the `OutboundPayments::pending_outbound_payments` lock during pathfinding.
79
79
InvoiceReceived {
80
80
payment_hash : PaymentHash ,
81
81
retry_strategy : Retry ,
@@ -851,7 +851,7 @@ impl OutboundPayments {
851
851
entropy_source : & ES , node_signer : & NS , node_id_lookup : & NL ,
852
852
secp_ctx : & Secp256k1 < secp256k1:: All > , best_block_height : u32 , logger : & L ,
853
853
pending_events : & Mutex < VecDeque < ( events:: Event , Option < EventCompletionAction > ) > > ,
854
- send_payment_along_path : SP , with_manual_handling : bool
854
+ send_payment_along_path : SP ,
855
855
) -> Result < ( ) , Bolt12PaymentError >
856
856
where
857
857
R :: Target : Router ,
@@ -862,15 +862,9 @@ impl OutboundPayments {
862
862
IH : Fn ( ) -> InFlightHtlcs ,
863
863
SP : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
864
864
{
865
- // When manual invoice handling is enabled, the corresponding `PendingOutboundPayment` entry
866
- // is already updated at the time the invoice is received. This ensures that `InvoiceReceived`
867
- // event generation remains idempotent, even if the same invoice is received again before the
868
- // event is handled by the user.
869
- let ( payment_hash, retry_strategy, params_config) = if with_manual_handling {
870
- self . received_invoice_details ( invoice, payment_id) ?
871
- } else {
872
- self . mark_invoice_received_and_get_details ( invoice, payment_id) ?
873
- } ;
865
+
866
+ let ( payment_hash, retry_strategy, params_config, _) = self
867
+ . get_received_invoice_details ( invoice, payment_id) ?;
874
868
875
869
if invoice. invoice_features ( ) . requires_unknown_bits_from ( & features) {
876
870
self . abandon_payment (
@@ -1781,12 +1775,17 @@ impl OutboundPayments {
1781
1775
pub ( super ) fn mark_invoice_received (
1782
1776
& self , invoice : & Bolt12Invoice , payment_id : PaymentId
1783
1777
) -> Result < ( ) , Bolt12PaymentError > {
1784
- self . mark_invoice_received_and_get_details ( invoice, payment_id) . map ( |_| ( ) )
1778
+ self . get_received_invoice_details ( invoice, payment_id)
1779
+ . and_then ( |( _, _, _, invoice_marked_received) | {
1780
+ invoice_marked_received
1781
+ . then_some ( ( ) )
1782
+ . ok_or ( Bolt12PaymentError :: DuplicateInvoice )
1783
+ } )
1785
1784
}
1786
1785
1787
- fn mark_invoice_received_and_get_details (
1786
+ fn get_received_invoice_details (
1788
1787
& self , invoice : & Bolt12Invoice , payment_id : PaymentId
1789
- ) -> Result < ( PaymentHash , Retry , RouteParametersConfig ) , Bolt12PaymentError > {
1788
+ ) -> Result < ( PaymentHash , Retry , RouteParametersConfig , bool ) , Bolt12PaymentError > {
1790
1789
match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
1791
1790
hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
1792
1791
PendingOutboundPayment :: AwaitingInvoice {
@@ -1801,23 +1800,16 @@ impl OutboundPayments {
1801
1800
route_params_config : config,
1802
1801
} ;
1803
1802
1804
- Ok ( ( payment_hash, retry, config) )
1803
+ Ok ( ( payment_hash, retry, config, true ) )
1805
1804
} ,
1806
- _ => Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
1807
- } ,
1808
- hash_map:: Entry :: Vacant ( _) => Err ( Bolt12PaymentError :: UnexpectedInvoice ) ,
1809
- }
1810
- }
1811
-
1812
- fn received_invoice_details (
1813
- & self , invoice : & Bolt12Invoice , payment_id : PaymentId ,
1814
- ) -> Result < ( PaymentHash , Retry , RouteParametersConfig ) , Bolt12PaymentError > {
1815
- match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
1816
- hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
1805
+ // When manual invoice handling is enabled, the corresponding `PendingOutboundPayment` entry
1806
+ // is already updated at the time the invoice is received. This ensures that `InvoiceReceived`
1807
+ // event generation remains idempotent, even if the same invoice is received again before the
1808
+ // event is handled by the user.
1817
1809
PendingOutboundPayment :: InvoiceReceived {
1818
1810
retry_strategy, route_params_config, ..
1819
1811
} => {
1820
- Ok ( ( invoice. payment_hash ( ) , * retry_strategy, * route_params_config) )
1812
+ Ok ( ( invoice. payment_hash ( ) , * retry_strategy, * route_params_config, false ) )
1821
1813
} ,
1822
1814
_ => Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
1823
1815
} ,
@@ -2904,7 +2896,7 @@ mod tests {
2904
2896
outbound_payments. send_payment_for_bolt12_invoice(
2905
2897
& invoice, payment_id, &&router, vec![ ] , Bolt12InvoiceFeatures :: empty( ) ,
2906
2898
|| InFlightHtlcs :: new( ) , &&keys_manager, &&keys_manager, & EmptyNodeIdLookUp { } ,
2907
- & secp_ctx, 0 , &&logger, & pending_events, |_| panic!( ) , false
2899
+ & secp_ctx, 0 , &&logger, & pending_events, |_| panic!( )
2908
2900
) ,
2909
2901
Err ( Bolt12PaymentError :: SendingFailed ( RetryableSendFailure :: PaymentExpired ) ) ,
2910
2902
) ;
@@ -2966,7 +2958,7 @@ mod tests {
2966
2958
outbound_payments. send_payment_for_bolt12_invoice(
2967
2959
& invoice, payment_id, &&router, vec![ ] , Bolt12InvoiceFeatures :: empty( ) ,
2968
2960
|| InFlightHtlcs :: new( ) , &&keys_manager, &&keys_manager, & EmptyNodeIdLookUp { } ,
2969
- & secp_ctx, 0 , &&logger, & pending_events, |_| panic!( ) , false
2961
+ & secp_ctx, 0 , &&logger, & pending_events, |_| panic!( )
2970
2962
) ,
2971
2963
Err ( Bolt12PaymentError :: SendingFailed ( RetryableSendFailure :: RouteNotFound ) ) ,
2972
2964
) ;
@@ -3041,7 +3033,7 @@ mod tests {
3041
3033
outbound_payments. send_payment_for_bolt12_invoice(
3042
3034
& invoice, payment_id, &&router, vec![ ] , Bolt12InvoiceFeatures :: empty( ) ,
3043
3035
|| InFlightHtlcs :: new( ) , &&keys_manager, &&keys_manager, & EmptyNodeIdLookUp { } ,
3044
- & secp_ctx, 0 , &&logger, & pending_events, |_| panic!( ) , false
3036
+ & secp_ctx, 0 , &&logger, & pending_events, |_| panic!( )
3045
3037
) ,
3046
3038
Err ( Bolt12PaymentError :: UnexpectedInvoice ) ,
3047
3039
) ;
@@ -3061,7 +3053,7 @@ mod tests {
3061
3053
outbound_payments. send_payment_for_bolt12_invoice(
3062
3054
& invoice, payment_id, &&router, vec![ ] , Bolt12InvoiceFeatures :: empty( ) ,
3063
3055
|| InFlightHtlcs :: new( ) , &&keys_manager, &&keys_manager, & EmptyNodeIdLookUp { } ,
3064
- & secp_ctx, 0 , &&logger, & pending_events, |_| Ok ( ( ) ) , false
3056
+ & secp_ctx, 0 , &&logger, & pending_events, |_| Ok ( ( ) )
3065
3057
) ,
3066
3058
Ok ( ( ) ) ,
3067
3059
) ;
@@ -3072,7 +3064,7 @@ mod tests {
3072
3064
outbound_payments. send_payment_for_bolt12_invoice(
3073
3065
& invoice, payment_id, &&router, vec![ ] , Bolt12InvoiceFeatures :: empty( ) ,
3074
3066
|| InFlightHtlcs :: new( ) , &&keys_manager, &&keys_manager, & EmptyNodeIdLookUp { } ,
3075
- & secp_ctx, 0 , &&logger, & pending_events, |_| panic!( ) , false
3067
+ & secp_ctx, 0 , &&logger, & pending_events, |_| panic!( )
3076
3068
) ,
3077
3069
Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
3078
3070
) ;
0 commit comments