Skip to content

Commit c4ac620

Browse files
Don't remove failed payments when all paths fail
This is because we want the ability to retry completely failed payments. Upcoming commits will remove these payments on timeout to prevent DoS issues Also test that this removal allows retrying single-path payments
1 parent d3d5d7e commit c4ac620

File tree

2 files changed

+53
-4
lines changed

2 files changed

+53
-4
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2996,9 +2996,6 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
29962996
error_data: None,
29972997
}
29982998
);
2999-
if payment.get().remaining_parts() == 0 {
3000-
payment.remove();
3001-
}
30022999
}
30033000
} else {
30043001
log_trace!(self.logger, "Received duplicative fail for HTLC with payment_hash {}", log_bytes!(payment_hash.0));
@@ -3036,7 +3033,6 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
30363033
}
30373034
if sessions.get().remaining_parts() == 0 {
30383035
all_paths_failed = true;
3039-
sessions.remove();
30403036
}
30413037
} else {
30423038
log_trace!(self.logger, "Received duplicative fail for HTLC with payment_hash {}", log_bytes!(payment_hash.0));

lightning/src/ln/functional_tests.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4273,6 +4273,59 @@ fn mpp_retry() {
42734273
claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage);
42744274
}
42754275

4276+
#[test]
4277+
fn retry_single_path_payment() {
4278+
let chanmon_cfgs = create_chanmon_cfgs(3);
4279+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
4280+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
4281+
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
4282+
4283+
let _chan_0 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
4284+
let _chan_1 = create_announced_chan_between_nodes(&nodes, 2, 1, InitFeatures::known(), InitFeatures::known());
4285+
// Rebalance to find a route
4286+
send_payment(&nodes[2], &vec!(&nodes[1])[..], 3_000_000);
4287+
4288+
let logger = test_utils::TestLogger::new();
4289+
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
4290+
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
4291+
let route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[2].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &Vec::new(), 100_000, TEST_FINAL_CLTV, &logger).unwrap();
4292+
4293+
// Rebalance so that the first hop fails.
4294+
send_payment(&nodes[1], &vec!(&nodes[2])[..], 2_000_000);
4295+
4296+
// Make sure the payment fails on the first hop.
4297+
let payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
4298+
check_added_monitors!(nodes[0], 1);
4299+
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
4300+
assert_eq!(events.len(), 1);
4301+
let mut payment_event = SendEvent::from_event(events.pop().unwrap());
4302+
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
4303+
check_added_monitors!(nodes[1], 0);
4304+
commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
4305+
expect_pending_htlcs_forwardable!(nodes[1]);
4306+
expect_pending_htlcs_forwardable!(&nodes[1]);
4307+
let htlc_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
4308+
assert!(htlc_updates.update_add_htlcs.is_empty());
4309+
assert_eq!(htlc_updates.update_fail_htlcs.len(), 1);
4310+
assert!(htlc_updates.update_fulfill_htlcs.is_empty());
4311+
assert!(htlc_updates.update_fail_malformed_htlcs.is_empty());
4312+
check_added_monitors!(nodes[1], 1);
4313+
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &htlc_updates.update_fail_htlcs[0]);
4314+
commitment_signed_dance!(nodes[0], nodes[1], htlc_updates.commitment_signed, false);
4315+
expect_payment_failed!(nodes[0], payment_hash, false);
4316+
4317+
// Rebalance the channel so the retry succeeds.
4318+
send_payment(&nodes[2], &vec!(&nodes[1])[..], 3_000_000);
4319+
4320+
// Retry the payment and make sure it succeeds.
4321+
nodes[0].node.retry_payment(&route, payment_id).unwrap();
4322+
check_added_monitors!(nodes[0], 1);
4323+
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
4324+
assert_eq!(events.len(), 1);
4325+
pass_along_path(&nodes[0], &[&nodes[1], &nodes[2]], 100_000, payment_hash, Some(payment_secret), events.pop().unwrap(), true, None);
4326+
claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage);
4327+
}
4328+
42764329
#[test]
42774330
fn test_dup_htlc_onchain_fails_on_reload() {
42784331
// When a Channel is closed, any outbound HTLCs which were relayed through it are simply

0 commit comments

Comments
 (0)