Probe up to second-to-last hop if last was provided by route hint
authorElias Rohrer <dev@tnull.de>
Mon, 11 Sep 2023 11:50:10 +0000 (13:50 +0200)
committerElias Rohrer <dev@tnull.de>
Mon, 18 Sep 2023 13:08:27 +0000 (15:08 +0200)
If the last hop was provided by route hint we assume it's not an announced channel.
If furthermore only a single route hint is provided we refrain from probing through
all the way to the end and instead probe up to the second-to-last channel.

Optimally we'd do this not based on above mentioned assumption but
rather by checking inclusion in our network graph. However, we don't
have access to our graph in `ChannelManager`.

lightning/src/ln/channelmanager.rs

index 1b971dce497a390e29fa060c801376e129ce9bca..2748062c905c3539a7cc43fa59498b733662e5a3 100644 (file)
@@ -3539,7 +3539,29 @@ where
                let mut used_liquidity_map = HashMap::with_capacity(first_hops.len());
 
                let mut res = Vec::new();
-               for path in route.paths {
+
+               for mut path in route.paths {
+                       // If the last hop is probably an unannounced channel we refrain from probing all the
+                       // way through to the end and instead probe up to the second-to-last channel.
+                       while let Some(last_path_hop) = path.hops.last() {
+                               if last_path_hop.maybe_announced_channel {
+                                       // We found a potentially announced last hop.
+                                       break;
+                               } else {
+                                       // Drop the last hop, as it's likely unannounced.
+                                       log_debug!(
+                                               self.logger,
+                                               "Avoided sending payment probe all the way to last hop {} as it is likely unannounced.",
+                                               last_path_hop.short_channel_id
+                                       );
+                                       let final_value_msat = path.final_value_msat();
+                                       path.hops.pop();
+                                       if let Some(new_last) = path.hops.last_mut() {
+                                               new_last.fee_msat += final_value_msat;
+                                       }
+                               }
+                       }
+
                        if path.hops.len() < 2 {
                                log_debug!(
                                        self.logger,