Skip to content

Commit bd41dc6

Browse files
Support abandoning pending outbound async payments.
1 parent c12db14 commit bd41dc6

File tree

1 file changed

+60
-14
lines changed

1 file changed

+60
-14
lines changed

lightning/src/ln/outbound_payment.rs

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -206,20 +206,26 @@ impl PendingOutboundPayment {
206206
}
207207

208208
fn mark_abandoned(&mut self, reason: PaymentFailureReason) {
209-
if let PendingOutboundPayment::Retryable { session_privs, payment_hash, .. } = self {
210-
let mut our_session_privs = new_hash_set();
211-
core::mem::swap(&mut our_session_privs, session_privs);
212-
*self = PendingOutboundPayment::Abandoned {
213-
session_privs: our_session_privs,
214-
payment_hash: *payment_hash,
215-
reason: Some(reason)
216-
};
217-
} else if let PendingOutboundPayment::InvoiceReceived { payment_hash, .. } = self {
218-
*self = PendingOutboundPayment::Abandoned {
219-
session_privs: new_hash_set(),
220-
payment_hash: *payment_hash,
221-
reason: Some(reason)
222-
};
209+
let session_privs = match self {
210+
PendingOutboundPayment::Retryable { session_privs, .. } => {
211+
let mut our_session_privs = new_hash_set();
212+
core::mem::swap(&mut our_session_privs, session_privs);
213+
our_session_privs
214+
},
215+
_ => new_hash_set(),
216+
};
217+
match self {
218+
Self::Retryable { payment_hash, .. } |
219+
Self::InvoiceReceived { payment_hash, .. } |
220+
Self::StaticInvoiceReceived { payment_hash, .. } =>
221+
{
222+
*self = Self::Abandoned {
223+
session_privs,
224+
payment_hash: *payment_hash,
225+
reason: Some(reason),
226+
};
227+
},
228+
_ => {}
223229
}
224230
}
225231

@@ -2719,4 +2725,44 @@ mod tests {
27192725
reason: Some(PaymentFailureReason::PaymentExpired),
27202726
}, None));
27212727
}
2728+
2729+
#[test]
2730+
fn abandon_unreleased_async_payment() {
2731+
let pending_events = Mutex::new(VecDeque::new());
2732+
let outbound_payments = OutboundPayments::new();
2733+
let payment_id = PaymentId([0; 32]);
2734+
let absolute_expiry = 60;
2735+
2736+
let mut outbounds = outbound_payments.pending_outbound_payments.lock().unwrap();
2737+
let payment_params = PaymentParameters::from_node_id(test_utils::pubkey(42), 0)
2738+
.with_expiry_time(absolute_expiry);
2739+
let route_params = RouteParameters {
2740+
payment_params,
2741+
final_value_msat: 0,
2742+
max_total_routing_fee_msat: None,
2743+
};
2744+
let payment_hash = PaymentHash([0; 32]);
2745+
let outbound = PendingOutboundPayment::StaticInvoiceReceived {
2746+
payment_hash,
2747+
keysend_preimage: PaymentPreimage([0; 32]),
2748+
retry_strategy: Retry::Attempts(0),
2749+
payment_release_secret: [0; 32],
2750+
route_params,
2751+
};
2752+
outbounds.insert(payment_id, outbound);
2753+
core::mem::drop(outbounds);
2754+
2755+
outbound_payments.abandon_payment(
2756+
payment_id, PaymentFailureReason::UserAbandoned, &pending_events
2757+
);
2758+
let outbounds = outbound_payments.pending_outbound_payments.lock().unwrap();
2759+
assert_eq!(outbounds.len(), 0);
2760+
let events = pending_events.lock().unwrap();
2761+
assert_eq!(events.len(), 1);
2762+
assert_eq!(events[0], (Event::PaymentFailed {
2763+
payment_hash: Some(payment_hash),
2764+
payment_id,
2765+
reason: Some(PaymentFailureReason::UserAbandoned),
2766+
}, None));
2767+
}
27222768
}

0 commit comments

Comments
 (0)