/// [`Event::PaymentSent`]: crate::util::events::Event::PaymentSent
/// [`Event::PaymentFailed`]: crate::util::events::Event::PaymentFailed
DuplicatePayment,
- /// Some paths which were attempted failed to send, though possibly not all. At least some
- /// paths have irrevocably committed to the HTLC.
+ /// Some paths that were attempted failed to send, though some paths may have succeeded. At least
+ /// some paths have irrevocably committed to the HTLC.
///
- /// The results here are ordered the same as the paths in the route object which was passed to
+ /// The results here are ordered the same as the paths in the route object that was passed to
/// send_payment.
///
- /// Any entries which contain `Err(APIError::MonitorUpdateInprogress)` will send once a
+ /// Any entries that contain `Err(APIError::MonitorUpdateInprogress)` will send once a
/// [`MonitorEvent::Completed`] is provided for the next-hop channel with the latest update_id.
///
/// [`MonitorEvent::Completed`]: crate::chain::channelmonitor::MonitorEvent::Completed
pub(super) struct OutboundPayments {
pub(super) pending_outbound_payments: Mutex<HashMap<PaymentId, PendingOutboundPayment>>,
+ pub(super) retry_lock: Mutex<()>,
}
impl OutboundPayments {
pub(super) fn new() -> Self {
Self {
- pending_outbound_payments: Mutex::new(HashMap::new())
+ pending_outbound_payments: Mutex::new(HashMap::new()),
+ retry_lock: Mutex::new(()),
}
}
FH: Fn() -> Vec<ChannelDetails>,
L::Target: Logger,
{
+ let _single_thread = self.retry_lock.lock().unwrap();
loop {
let mut outbounds = self.pending_outbound_payments.lock().unwrap();
let mut retry_id_route_params = None;
});
}
- if !payment_is_probe && (!is_retryable_now || !payment_retryable || retry.is_none()) {
+ if payment_is_probe || !is_retryable_now || !payment_retryable || retry.is_none() {
let _ = payment.get_mut().mark_abandoned(); // we'll only Err if it's a legacy payment
is_retryable_now = false;
}
if payment.get().remaining_parts() == 0 {
all_paths_failed = true;
if payment.get().abandoned() {
- full_failure_ev = Some(events::Event::PaymentFailed {
- payment_id: *payment_id,
- payment_hash: payment.get().payment_hash().expect("PendingOutboundPayments::RetriesExceeded always has a payment hash set"),
- });
+ if !payment_is_probe {
+ full_failure_ev = Some(events::Event::PaymentFailed {
+ payment_id: *payment_id,
+ payment_hash: payment.get().payment_hash().expect("PendingOutboundPayments::RetriesExceeded always has a payment hash set"),
+ });
+ }
payment.remove();
}
}