Check for abandon-able payments on startup
authorValentine Wallace <vwallace@protonmail.com>
Fri, 17 Feb 2023 22:14:43 +0000 (17:14 -0500)
committerValentine Wallace <vwallace@protonmail.com>
Fri, 17 Feb 2023 22:14:43 +0000 (17:14 -0500)
lightning/src/ln/channelmanager.rs
lightning/src/ln/outbound_payment.rs
lightning/src/ln/payment_tests.rs

index d47fbe0babd17d98d1674c58377d7bf3942bbeb8..e7a558cb6151fad5755da98b2cfdefe99e89275c 100644 (file)
@@ -7526,7 +7526,8 @@ where
                        }
                }
 
-               if !forward_htlcs.is_empty() {
+               let pending_outbounds = OutboundPayments { pending_outbound_payments: Mutex::new(pending_outbound_payments.unwrap()), retry_lock: Mutex::new(()) };
+               if !forward_htlcs.is_empty() || pending_outbounds.needs_abandon() {
                        // If we have pending HTLCs to forward, assume we either dropped a
                        // `PendingHTLCsForwardable` or the user received it but never processed it as they
                        // shut down before the timer hit. Either way, set the time_forwardable to a small
@@ -7694,7 +7695,7 @@ where
 
                        inbound_payment_key: expanded_inbound_key,
                        pending_inbound_payments: Mutex::new(pending_inbound_payments),
-                       pending_outbound_payments: OutboundPayments { pending_outbound_payments: Mutex::new(pending_outbound_payments.unwrap()), retry_lock: Mutex::new(()), },
+                       pending_outbound_payments: pending_outbounds,
                        pending_intercepted_htlcs: Mutex::new(pending_intercepted_htlcs.unwrap()),
 
                        forward_htlcs: Mutex::new(forward_htlcs),
index 6ebd7bc547fe42b1db2242b89ca249ca514c8ae3..715a041dcf3512b0fdfb83244d7418b148b3cc80 100644 (file)
@@ -546,6 +546,12 @@ impl OutboundPayments {
                });
        }
 
+       pub(super) fn needs_abandon(&self) -> bool {
+               let outbounds = self.pending_outbound_payments.lock().unwrap();
+               outbounds.iter().any(|(_, pmt)|
+                       !pmt.is_auto_retryable_now() && pmt.remaining_parts() == 0 && !pmt.is_fulfilled())
+       }
+
        /// Will return `Ok(())` iff at least one HTLC is sent for the payment.
        fn pay_internal<R: Deref, NS: Deref, ES: Deref, IH, SP, L: Deref>(
                &self, payment_id: PaymentId,
index 4c228a3226aeaa6ce89b5056623d3747785c24cb..8e35e650b7020495687c5e635856c50789dc3d7d 100644 (file)
@@ -1721,8 +1721,9 @@ fn do_automatic_retries(test: AutoRetry) {
                let chan_1_monitor_serialized = get_monitor!(nodes[0], channel_id_1).encode();
                reload_node!(nodes[0], node_encoded, &[&chan_1_monitor_serialized], persister, new_chain_monitor, node_0_deserialized);
 
+               let mut events = nodes[0].node.get_and_clear_pending_events();
+               expect_pending_htlcs_forwardable_from_events!(nodes[0], events, true);
                // Make sure we don't retry again.
-               nodes[0].node.process_pending_htlc_forwards();
                let mut msg_events = nodes[0].node.get_and_clear_pending_msg_events();
                assert_eq!(msg_events.len(), 0);