@@ -72,9 +72,9 @@ pub(crate) enum PendingOutboundPayment {
7272 route_params_config : RouteParametersConfig ,
7373 retryable_invoice_request : Option < RetryableInvoiceRequest >
7474 } ,
75- // This state will never be persisted to disk because we transition from `AwaitingInvoice` to
76- // `Retryable` atomically within the `ChannelManager::total_consistency_lock`. Useful to avoid
77- // holding the `OutboundPayments::pending_outbound_payments` lock during pathfinding.
75+ // Represents the state after the invoice has been received, transitioning from the corresponding
76+ // `AwaitingInvoice` state.
77+ // Helps avoid holding the `OutboundPayments::pending_outbound_payments` lock during pathfinding.
7878 InvoiceReceived {
7979 payment_hash : PaymentHash ,
8080 retry_strategy : Retry ,
@@ -931,26 +931,9 @@ impl OutboundPayments {
931931 IH : Fn ( ) -> InFlightHtlcs ,
932932 SP : Fn ( SendAlongPathArgs ) -> Result < ( ) , APIError > ,
933933 {
934- let payment_hash = invoice. payment_hash ( ) ;
935- let params_config;
936- let retry_strategy;
937- match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
938- hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
939- PendingOutboundPayment :: AwaitingInvoice {
940- retry_strategy : retry, route_params_config, ..
941- } => {
942- retry_strategy = * retry;
943- params_config = * route_params_config;
944- * entry. into_mut ( ) = PendingOutboundPayment :: InvoiceReceived {
945- payment_hash,
946- retry_strategy : * retry,
947- route_params_config : * route_params_config,
948- } ;
949- } ,
950- _ => return Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
951- } ,
952- hash_map:: Entry :: Vacant ( _) => return Err ( Bolt12PaymentError :: UnexpectedInvoice ) ,
953- }
934+
935+ let ( payment_hash, retry_strategy, params_config, _) = self
936+ . mark_invoice_received_and_get_details ( invoice, payment_id) ?;
954937
955938 if invoice. invoice_features ( ) . requires_unknown_bits_from ( & features) {
956939 self . abandon_payment (
@@ -1863,6 +1846,51 @@ impl OutboundPayments {
18631846 }
18641847 }
18651848
1849+ pub ( super ) fn mark_invoice_received (
1850+ & self , invoice : & Bolt12Invoice , payment_id : PaymentId
1851+ ) -> Result < ( ) , Bolt12PaymentError > {
1852+ self . mark_invoice_received_and_get_details ( invoice, payment_id)
1853+ . and_then ( |( _, _, _, is_newly_marked) | {
1854+ is_newly_marked
1855+ . then_some ( ( ) )
1856+ . ok_or ( Bolt12PaymentError :: DuplicateInvoice )
1857+ } )
1858+ }
1859+
1860+ fn mark_invoice_received_and_get_details (
1861+ & self , invoice : & Bolt12Invoice , payment_id : PaymentId
1862+ ) -> Result < ( PaymentHash , Retry , RouteParametersConfig , bool ) , Bolt12PaymentError > {
1863+ match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
1864+ hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
1865+ PendingOutboundPayment :: AwaitingInvoice {
1866+ retry_strategy : retry, route_params_config, ..
1867+ } => {
1868+ let payment_hash = invoice. payment_hash ( ) ;
1869+ let retry = * retry;
1870+ let config = * route_params_config;
1871+ * entry. into_mut ( ) = PendingOutboundPayment :: InvoiceReceived {
1872+ payment_hash,
1873+ retry_strategy : retry,
1874+ route_params_config : config,
1875+ } ;
1876+
1877+ Ok ( ( payment_hash, retry, config, true ) )
1878+ } ,
1879+ // When manual invoice handling is enabled, the corresponding `PendingOutboundPayment` entry
1880+ // is already updated at the time the invoice is received. This ensures that `InvoiceReceived`
1881+ // event generation remains idempotent, even if the same invoice is received again before the
1882+ // event is handled by the user.
1883+ PendingOutboundPayment :: InvoiceReceived {
1884+ retry_strategy, route_params_config, ..
1885+ } => {
1886+ Ok ( ( invoice. payment_hash ( ) , * retry_strategy, * route_params_config, false ) )
1887+ } ,
1888+ _ => Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
1889+ } ,
1890+ hash_map:: Entry :: Vacant ( _) => Err ( Bolt12PaymentError :: UnexpectedInvoice ) ,
1891+ }
1892+ }
1893+
18661894 fn pay_route_internal < NS : Deref , F > (
18671895 & self , route : & Route , payment_hash : PaymentHash , recipient_onion : & RecipientOnionFields ,
18681896 keysend_preimage : Option < PaymentPreimage > , invoice_request : Option < & InvoiceRequest > ,
0 commit comments