From: Matt Corallo <649246+TheBlueMatt@users.noreply.github.com> Date: Thu, 16 Feb 2023 23:41:09 +0000 (+0000) Subject: Merge pull request #2009 from TheBlueMatt/2023-02-no-racey-retries X-Git-Tag: v0.0.114-beta~14 X-Git-Url: http://git.bitcoin.ninja/?a=commitdiff_plain;h=d0b8f455fe86d3e55231d35d35dd96693abe2049;p=rust-lightning Merge pull request #2009 from TheBlueMatt/2023-02-no-racey-retries Fix (and test) threaded payment retries --- d0b8f455fe86d3e55231d35d35dd96693abe2049 diff --cc lightning/src/ln/payment_tests.rs index e398ce031,bc0910384..4c228a322 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@@ -40,9 -39,63 +40,9 @@@ use crate::routing::gossip::NodeId #[cfg(feature = "std")] use { crate::util::time::tests::SinceEpoch, - std::time::{SystemTime, Duration} + std::time::{SystemTime, Instant, Duration} }; -#[test] -fn retry_single_path_payment() { - let chanmon_cfgs = create_chanmon_cfgs(3); - let node_cfgs = create_node_cfgs(3, &chanmon_cfgs); - let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]); - let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs); - - let _chan_0 = create_announced_chan_between_nodes(&nodes, 0, 1); - let chan_1 = create_announced_chan_between_nodes(&nodes, 2, 1); - // Rebalance to find a route - send_payment(&nodes[2], &vec!(&nodes[1])[..], 3_000_000); - - let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 100_000); - - // Rebalance so that the first hop fails. - send_payment(&nodes[1], &vec!(&nodes[2])[..], 2_000_000); - - // Make sure the payment fails on the first hop. - let payment_id = PaymentId(payment_hash.0); - nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), payment_id).unwrap(); - check_added_monitors!(nodes[0], 1); - let mut events = nodes[0].node.get_and_clear_pending_msg_events(); - assert_eq!(events.len(), 1); - let mut payment_event = SendEvent::from_event(events.pop().unwrap()); - nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]); - check_added_monitors!(nodes[1], 0); - commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false); - expect_pending_htlcs_forwardable!(nodes[1]); - expect_pending_htlcs_forwardable_and_htlc_handling_failed!(&nodes[1], vec![HTLCDestination::NextHopChannel { node_id: Some(nodes[2].node.get_our_node_id()), channel_id: chan_1.2 }]); - let htlc_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id()); - assert!(htlc_updates.update_add_htlcs.is_empty()); - assert_eq!(htlc_updates.update_fail_htlcs.len(), 1); - assert!(htlc_updates.update_fulfill_htlcs.is_empty()); - assert!(htlc_updates.update_fail_malformed_htlcs.is_empty()); - check_added_monitors!(nodes[1], 1); - nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &htlc_updates.update_fail_htlcs[0]); - commitment_signed_dance!(nodes[0], nodes[1], htlc_updates.commitment_signed, false); - expect_payment_failed_conditions(&nodes[0], payment_hash, false, PaymentFailedConditions::new().mpp_parts_remain()); - - // Rebalance the channel so the retry succeeds. - send_payment(&nodes[2], &vec!(&nodes[1])[..], 3_000_000); - - // Mine two blocks (we expire retries after 3, so this will check that we don't expire early) - connect_blocks(&nodes[0], 2); - - // Retry the payment and make sure it succeeds. - nodes[0].node.retry_payment(&route, payment_id).unwrap(); - check_added_monitors!(nodes[0], 1); - let mut events = nodes[0].node.get_and_clear_pending_msg_events(); - assert_eq!(events.len(), 1); - pass_along_path(&nodes[0], &[&nodes[1], &nodes[2]], 100_000, payment_hash, Some(payment_secret), events.pop().unwrap(), true, None); - claim_payment_along_route(&nodes[0], &[&[&nodes[1], &nodes[2]]], false, payment_preimage); -} - #[test] fn mpp_failure() { let chanmon_cfgs = create_chanmon_cfgs(4); diff --cc lightning/src/util/test_utils.rs index 1c2cfe00d,2d68e74c2..b2b5cacfe --- a/lightning/src/util/test_utils.rs +++ b/lightning/src/util/test_utils.rs @@@ -135,13 -108,18 +135,14 @@@ impl<'a> Router for TestRouter<'a> &[42; 32] ) } - fn notify_payment_path_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {} - fn notify_payment_path_successful(&self, _path: &[&RouteHop]) {} - fn notify_payment_probe_successful(&self, _path: &[&RouteHop]) {} - fn notify_payment_probe_failed(&self, _path: &[&RouteHop], _short_channel_id: u64) {} } - #[cfg(feature = "std")] // If we put this on the `if`, we get "attributes are not yet allowed on `if` expressions" on 1.41.1 impl<'a> Drop for TestRouter<'a> { fn drop(&mut self) { - if std::thread::panicking() { - return; + #[cfg(feature = "std")] { + if std::thread::panicking() { + return; + } } assert!(self.next_routes.lock().unwrap().is_empty()); }