]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Rewrite failure payment retry tests to avoid perm-fail storage
authorMatt Corallo <git@bluematt.me>
Sun, 10 Sep 2023 22:11:56 +0000 (22:11 +0000)
committerMatt Corallo <git@bluematt.me>
Thu, 21 Sep 2023 17:58:47 +0000 (17:58 +0000)
Two tests in the payment tests currently rely on failing to persist
ChannelMonitorUpdates as their method of failing payments before
they even get out the door.

In the coming commits we'll drop the persist failure error codes,
so here rewrite these tests to rely on trying to send more than is
available in a channel.

lightning/src/ln/payment_tests.rs

index 3def4e3629bf2fb98d227d9a95e5b1faf6493bc9..e5af136656f8ab8328e47f796bb6e8c29139f5ac 100644 (file)
@@ -2258,12 +2258,14 @@ fn auto_retry_partial_failure() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
+       // Open three channels, the first has plenty of liquidity, the second and third have ~no
+       // available liquidity, causing any outbound payments routed over it to fail immediately.
        let chan_1_id = create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
-       let chan_2_id = create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
-       let chan_3_id = create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
+       let chan_2_id = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 989_000_000).0.contents.short_channel_id;
+       let chan_3_id = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 989_000_000).0.contents.short_channel_id;
 
        // Marshall data to send the payment
-       let amt_msat = 20_000;
+       let amt_msat = 10_000_000;
        let (_, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], amt_msat);
        #[cfg(feature = "std")]
        let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
@@ -2278,16 +2280,6 @@ fn auto_retry_partial_failure() {
                .with_bolt11_features(invoice_features).unwrap();
        let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat);
 
-       // Ensure the first monitor update (for the initial send path1 over chan_1) succeeds, but the
-       // second (for the initial send path2 over chan_2) fails.
-       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
-       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure);
-       // Ensure third monitor update (for the retry1's path1 over chan_1) succeeds, but the fourth (for
-       // the retry1's path2 over chan_3) fails, and monitor updates succeed after that.
-       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
-       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure);
-       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
-
        // Configure the initial send, retry1 and retry2's paths.
        let send_route = Route {
                paths: vec![
@@ -2364,32 +2356,23 @@ fn auto_retry_partial_failure() {
        // Send a payment that will partially fail on send, then partially fail on retry, then succeed.
        nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret),
                PaymentId(payment_hash.0), route_params, Retry::Attempts(3)).unwrap();
-       let closed_chan_events = nodes[0].node.get_and_clear_pending_events();
-       assert_eq!(closed_chan_events.len(), 4);
-       match closed_chan_events[0] {
-               Event::ChannelClosed { .. } => {},
-               _ => panic!("Unexpected event"),
-       }
-       match closed_chan_events[1] {
+       let payment_failed_events = nodes[0].node.get_and_clear_pending_events();
+       assert_eq!(payment_failed_events.len(), 2);
+       match payment_failed_events[0] {
                Event::PaymentPathFailed { .. } => {},
                _ => panic!("Unexpected event"),
        }
-       match closed_chan_events[2] {
-               Event::ChannelClosed { .. } => {},
-               _ => panic!("Unexpected event"),
-       }
-       match closed_chan_events[3] {
+       match payment_failed_events[1] {
                Event::PaymentPathFailed { .. } => {},
                _ => panic!("Unexpected event"),
        }
 
        // Pass the first part of the payment along the path.
-       check_added_monitors!(nodes[0], 5); // three outbound channel updates succeeded, two permanently failed
+       check_added_monitors!(nodes[0], 1); // only one HTLC actually made it out
        let mut msg_events = nodes[0].node.get_and_clear_pending_msg_events();
 
-       // First message is the first update_add, remaining messages are broadcasting channel updates and
-       // errors for the permfailed channels
-       assert_eq!(msg_events.len(), 5);
+       // Only one HTLC/channel update actually made it out
+       assert_eq!(msg_events.len(), 1);
        let mut payment_event = SendEvent::from_event(msg_events.remove(0));
 
        nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &payment_event.msgs[0]);
@@ -2478,12 +2461,13 @@ fn auto_retry_zero_attempts_send_error() {
        let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
        let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
 
-       create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
-       create_announced_chan_between_nodes(&nodes, 0, 1).0.contents.short_channel_id;
+       // Open a single channel that does not have sufficient liquidity for the payment we want to
+       // send.
+       let chan_id  = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 989_000_000).0.contents.short_channel_id;
 
        // Marshall data to send the payment
-       let amt_msat = 20_000;
-       let (_, payment_hash, _, payment_secret) = get_route_and_payment_hash!(&nodes[0], nodes[1], amt_msat);
+       let amt_msat = 10_000_000;
+       let (_, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[1], Some(amt_msat), None);
        #[cfg(feature = "std")]
        let payment_expiry_secs = SystemTime::UNIX_EPOCH.elapsed().unwrap().as_secs() + 60 * 60;
        #[cfg(not(feature = "std"))]
@@ -2497,16 +2481,31 @@ fn auto_retry_zero_attempts_send_error() {
                .with_bolt11_features(invoice_features).unwrap();
        let route_params = RouteParameters::from_payment_params_and_value(payment_params, amt_msat);
 
-       chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure);
+       // Override the route search to return a route, rather than failing at the route-finding step.
+       let send_route = Route {
+               paths: vec![
+                       Path { hops: vec![RouteHop {
+                               pubkey: nodes[1].node.get_our_node_id(),
+                               node_features: nodes[1].node.node_features(),
+                               short_channel_id: chan_id,
+                               channel_features: nodes[1].node.channel_features(),
+                               fee_msat: amt_msat,
+                               cltv_expiry_delta: 100,
+                               maybe_announced_channel: true,
+                       }], blinded_tail: None },
+               ],
+               route_params: Some(route_params.clone()),
+       };
+       nodes[0].router.expect_find_route(route_params.clone(), Ok(send_route));
+
        nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret),
                PaymentId(payment_hash.0), route_params, Retry::Attempts(0)).unwrap();
-       assert_eq!(nodes[0].node.get_and_clear_pending_msg_events().len(), 2); // channel close messages
+       assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
        let events = nodes[0].node.get_and_clear_pending_events();
-       assert_eq!(events.len(), 3);
-       if let Event::ChannelClosed { .. } = events[0] { } else { panic!(); }
-       if let Event::PaymentPathFailed { .. } = events[1] { } else { panic!(); }
-       if let Event::PaymentFailed { .. } = events[2] { } else { panic!(); }
-       check_added_monitors!(nodes[0], 2);
+       assert_eq!(events.len(), 2);
+       if let Event::PaymentPathFailed { .. } = events[0] { } else { panic!(); }
+       if let Event::PaymentFailed { .. } = events[1] { } else { panic!(); }
+       check_added_monitors!(nodes[0], 0);
 }
 
 #[test]