Skip to content

Commit 6582aae

Browse files
authored
Merge pull request #1109 from TheBlueMatt/2021-10-init-fail-payment-retry-leak
Move pending payment tracking to after the new HTLC flies
2 parents ab0739e + a58c617 commit 6582aae

File tree

4 files changed

+285
-216
lines changed

4 files changed

+285
-216
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ struct PendingInboundPayment {
402402

403403
/// Stores the session_priv for each part of a payment that is still pending. For versions 0.0.102
404404
/// and later, also stores information for retrying the payment.
405-
enum PendingOutboundPayment {
405+
pub(crate) enum PendingOutboundPayment {
406406
Legacy {
407407
session_privs: HashSet<[u8; 32]>,
408408
},
@@ -1951,16 +1951,6 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
19511951
let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, prng_seed, payment_hash);
19521952

19531953
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
1954-
let mut pending_outbounds = self.pending_outbound_payments.lock().unwrap();
1955-
let payment = pending_outbounds.entry(payment_id).or_insert_with(|| PendingOutboundPayment::Retryable {
1956-
session_privs: HashSet::new(),
1957-
pending_amt_msat: 0,
1958-
payment_hash: *payment_hash,
1959-
payment_secret: *payment_secret,
1960-
starting_block_height: self.best_block.read().unwrap().height(),
1961-
total_msat: total_value,
1962-
});
1963-
assert!(payment.insert(session_priv_bytes, path.last().unwrap().fee_msat));
19641954

19651955
let err: Result<(), _> = loop {
19661956
let mut channel_lock = self.channel_state.lock().unwrap();
@@ -1978,12 +1968,27 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
19781968
if !chan.get().is_live() {
19791969
return Err(APIError::ChannelUnavailable{err: "Peer for first hop currently disconnected/pending monitor update!".to_owned()});
19801970
}
1981-
break_chan_entry!(self, chan.get_mut().send_htlc_and_commit(htlc_msat, payment_hash.clone(), htlc_cltv, HTLCSource::OutboundRoute {
1982-
path: path.clone(),
1983-
session_priv: session_priv.clone(),
1984-
first_hop_htlc_msat: htlc_msat,
1985-
payment_id,
1986-
}, onion_packet, &self.logger), channel_state, chan)
1971+
let send_res = break_chan_entry!(self, chan.get_mut().send_htlc_and_commit(
1972+
htlc_msat, payment_hash.clone(), htlc_cltv, HTLCSource::OutboundRoute {
1973+
path: path.clone(),
1974+
session_priv: session_priv.clone(),
1975+
first_hop_htlc_msat: htlc_msat,
1976+
payment_id,
1977+
}, onion_packet, &self.logger),
1978+
channel_state, chan);
1979+
1980+
let mut pending_outbounds = self.pending_outbound_payments.lock().unwrap();
1981+
let payment = pending_outbounds.entry(payment_id).or_insert_with(|| PendingOutboundPayment::Retryable {
1982+
session_privs: HashSet::new(),
1983+
pending_amt_msat: 0,
1984+
payment_hash: *payment_hash,
1985+
payment_secret: *payment_secret,
1986+
starting_block_height: self.best_block.read().unwrap().height(),
1987+
total_msat: total_value,
1988+
});
1989+
assert!(payment.insert(session_priv_bytes, path.last().unwrap().fee_msat));
1990+
1991+
send_res
19871992
} {
19881993
Some((update_add, commitment_signed, monitor_update)) => {
19891994
if let Err(e) = self.chain_monitor.update_channel(chan.get().get_funding_txo().unwrap(), monitor_update) {
@@ -2173,7 +2178,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
21732178
}
21742179
} else {
21752180
return Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError {
2176-
err: "Payment with ID {} not found".to_string()
2181+
err: format!("Payment with ID {} not found", log_bytes!(payment_id.0)),
21772182
}))
21782183
}
21792184
};
@@ -4383,6 +4388,11 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
43834388
self.process_pending_events(&event_handler);
43844389
events.into_inner()
43854390
}
4391+
4392+
#[cfg(test)]
4393+
pub fn has_pending_payments(&self) -> bool {
4394+
!self.pending_outbound_payments.lock().unwrap().is_empty()
4395+
}
43864396
}
43874397

43884398
impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> MessageSendEventsProvider for ChannelManager<Signer, M, T, K, F, L>

lightning/src/ln/functional_tests.rs

Lines changed: 0 additions & 198 deletions
Original file line numberDiff line numberDiff line change
@@ -4183,204 +4183,6 @@ fn mpp_failure() {
41834183
fail_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_hash);
41844184
}
41854185

4186-
#[test]
4187-
fn mpp_retry() {
4188-
let chanmon_cfgs = create_chanmon_cfgs(4);
4189-
let node_cfgs = create_node_cfgs(4, &chanmon_cfgs);
4190-
let node_chanmgrs = create_node_chanmgrs(4, &node_cfgs, &[None, None, None, None]);
4191-
let nodes = create_network(4, &node_cfgs, &node_chanmgrs);
4192-
4193-
let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id;
4194-
let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 2, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id;
4195-
let chan_3_id = create_announced_chan_between_nodes(&nodes, 1, 3, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id;
4196-
let chan_4_id = create_announced_chan_between_nodes(&nodes, 3, 2, InitFeatures::known(), InitFeatures::known()).0.contents.short_channel_id;
4197-
let logger = test_utils::TestLogger::new();
4198-
// Rebalance
4199-
send_payment(&nodes[3], &vec!(&nodes[2])[..], 1_500_000);
4200-
4201-
let (payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(&nodes[3]);
4202-
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
4203-
let mut route = get_route(&nodes[0].node.get_our_node_id(), &net_graph_msg_handler.network_graph, &nodes[3].node.get_our_node_id(), Some(InvoiceFeatures::known()), None, &[], 1_000_000, TEST_FINAL_CLTV, &logger).unwrap();
4204-
let path = route.paths[0].clone();
4205-
route.paths.push(path);
4206-
route.paths[0][0].pubkey = nodes[1].node.get_our_node_id();
4207-
route.paths[0][0].short_channel_id = chan_1_id;
4208-
route.paths[0][1].short_channel_id = chan_3_id;
4209-
route.paths[1][0].pubkey = nodes[2].node.get_our_node_id();
4210-
route.paths[1][0].short_channel_id = chan_2_id;
4211-
route.paths[1][1].short_channel_id = chan_4_id;
4212-
4213-
// Initiate the MPP payment.
4214-
let payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
4215-
check_added_monitors!(nodes[0], 2); // one monitor per path
4216-
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
4217-
assert_eq!(events.len(), 2);
4218-
4219-
// Pass half of the payment along the success path.
4220-
let success_path_msgs = events.remove(0);
4221-
pass_along_path(&nodes[0], &[&nodes[1], &nodes[3]], 2_000_000, payment_hash, Some(payment_secret), success_path_msgs, false, None);
4222-
4223-
// Add the HTLC along the first hop.
4224-
let fail_path_msgs_1 = events.remove(0);
4225-
let (update_add, commitment_signed) = match fail_path_msgs_1 {
4226-
MessageSendEvent::UpdateHTLCs { node_id: _, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => {
4227-
assert_eq!(update_add_htlcs.len(), 1);
4228-
assert!(update_fail_htlcs.is_empty());
4229-
assert!(update_fulfill_htlcs.is_empty());
4230-
assert!(update_fail_malformed_htlcs.is_empty());
4231-
assert!(update_fee.is_none());
4232-
(update_add_htlcs[0].clone(), commitment_signed.clone())
4233-
},
4234-
_ => panic!("Unexpected event"),
4235-
};
4236-
nodes[2].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add);
4237-
commitment_signed_dance!(nodes[2], nodes[0], commitment_signed, false);
4238-
4239-
// Attempt to forward the payment and complete the 2nd path's failure.
4240-
expect_pending_htlcs_forwardable!(&nodes[2]);
4241-
expect_pending_htlcs_forwardable!(&nodes[2]);
4242-
let htlc_updates = get_htlc_update_msgs!(nodes[2], nodes[0].node.get_our_node_id());
4243-
assert!(htlc_updates.update_add_htlcs.is_empty());
4244-
assert_eq!(htlc_updates.update_fail_htlcs.len(), 1);
4245-
assert!(htlc_updates.update_fulfill_htlcs.is_empty());
4246-
assert!(htlc_updates.update_fail_malformed_htlcs.is_empty());
4247-
check_added_monitors!(nodes[2], 1);
4248-
nodes[0].node.handle_update_fail_htlc(&nodes[2].node.get_our_node_id(), &htlc_updates.update_fail_htlcs[0]);
4249-
commitment_signed_dance!(nodes[0], nodes[2], htlc_updates.commitment_signed, false);
4250-
expect_payment_failed!(nodes[0], payment_hash, false);
4251-
4252-
// Rebalance the channel so the second half of the payment can succeed.
4253-
send_payment(&nodes[3], &vec!(&nodes[2])[..], 1_500_000);
4254-
4255-
// Make sure it errors as expected given a too-large amount.
4256-
if let Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError { err })) = nodes[0].node.retry_payment(&route, payment_id) {
4257-
assert!(err.contains("over total_payment_amt_msat"));
4258-
} else { panic!("Unexpected error"); }
4259-
4260-
// Make sure it errors as expected given the wrong payment_id.
4261-
if let Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError { err })) = nodes[0].node.retry_payment(&route, PaymentId([0; 32])) {
4262-
assert!(err.contains("not found"));
4263-
} else { panic!("Unexpected error"); }
4264-
4265-
// Retry the second half of the payment and make sure it succeeds.
4266-
let mut path = route.clone();
4267-
path.paths.remove(0);
4268-
nodes[0].node.retry_payment(&path, payment_id).unwrap();
4269-
check_added_monitors!(nodes[0], 1);
4270-
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
4271-
assert_eq!(events.len(), 1);
4272-
pass_along_path(&nodes[0], &[&nodes[2], &nodes[3]], 2_000_000, payment_hash, Some(payment_secret), events.pop().unwrap(), true, None);
4273-
claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[3]], &[&nodes[2], &nodes[3]]], false, payment_preimage);
4274-
}
4275-
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-
// Mine two blocks (we expire retries after 3, so this will check that we don't expire early)
4321-
connect_blocks(&nodes[0], 2);
4322-
4323-
// Retry the payment and make sure it succeeds.
4324-
nodes[0].node.retry_payment(&route, payment_id).unwrap();
4325-
check_added_monitors!(nodes[0], 1);
4326-
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
4327-
assert_eq!(events.len(), 1);
4328-
pass_along_path(&nodes[0], &[&nodes[1], &nodes[2]], 100_000, payment_hash, Some(payment_secret), events.pop().unwrap(), true, None);
4329-
claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage);
4330-
}
4331-
4332-
#[test]
4333-
fn retry_expired_payment() {
4334-
let chanmon_cfgs = create_chanmon_cfgs(3);
4335-
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
4336-
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
4337-
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
4338-
4339-
let _chan_0 = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known());
4340-
let _chan_1 = create_announced_chan_between_nodes(&nodes, 2, 1, InitFeatures::known(), InitFeatures::known());
4341-
// Rebalance to find a route
4342-
send_payment(&nodes[2], &vec!(&nodes[1])[..], 3_000_000);
4343-
4344-
let logger = test_utils::TestLogger::new();
4345-
let (_payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[2]);
4346-
let net_graph_msg_handler = &nodes[0].net_graph_msg_handler;
4347-
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();
4348-
4349-
// Rebalance so that the first hop fails.
4350-
send_payment(&nodes[1], &vec!(&nodes[2])[..], 2_000_000);
4351-
4352-
// Make sure the payment fails on the first hop.
4353-
let payment_id = nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret)).unwrap();
4354-
check_added_monitors!(nodes[0], 1);
4355-
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
4356-
assert_eq!(events.len(), 1);
4357-
let mut payment_event = SendEvent::from_event(events.pop().unwrap());
4358-
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
4359-
check_added_monitors!(nodes[1], 0);
4360-
commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
4361-
expect_pending_htlcs_forwardable!(nodes[1]);
4362-
expect_pending_htlcs_forwardable!(&nodes[1]);
4363-
let htlc_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
4364-
assert!(htlc_updates.update_add_htlcs.is_empty());
4365-
assert_eq!(htlc_updates.update_fail_htlcs.len(), 1);
4366-
assert!(htlc_updates.update_fulfill_htlcs.is_empty());
4367-
assert!(htlc_updates.update_fail_malformed_htlcs.is_empty());
4368-
check_added_monitors!(nodes[1], 1);
4369-
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &htlc_updates.update_fail_htlcs[0]);
4370-
commitment_signed_dance!(nodes[0], nodes[1], htlc_updates.commitment_signed, false);
4371-
expect_payment_failed!(nodes[0], payment_hash, false);
4372-
4373-
// Mine blocks so the payment will have expired.
4374-
connect_blocks(&nodes[0], 3);
4375-
4376-
// Retry the payment and make sure it errors as expected.
4377-
if let Err(PaymentSendFailure::ParameterError(APIError::APIMisuseError { err })) = nodes[0].node.retry_payment(&route, payment_id) {
4378-
assert!(err.contains("not found"));
4379-
} else {
4380-
panic!("Unexpected error");
4381-
}
4382-
}
4383-
43844186
#[test]
43854187
fn test_dup_htlc_onchain_fails_on_reload() {
43864188
// When a Channel is closed, any outbound HTLCs which were relayed through it are simply

lightning/src/ln/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ pub mod wire;
5151
mod functional_tests;
5252
#[cfg(test)]
5353
#[allow(unused_mut)]
54+
mod payment_tests;
55+
#[cfg(test)]
56+
#[allow(unused_mut)]
5457
mod chanmon_update_fail_tests;
5558
#[cfg(test)]
5659
#[allow(unused_mut)]

0 commit comments

Comments
 (0)