Implement utilities for keysending to private nodes
[rust-lightning] / lightning / src / routing / router.rs
index 6c14ebebd89b70d55b1e4f59af827a9f0a6b1cde..eda25572a22710d3df0220c411514b35a844deee 100644 (file)
@@ -327,6 +327,18 @@ fn compute_fees(amount_msat: u64, channel_fees: RoutingFees) -> Option<u64> {
        }
 }
 
+/// Gets a keysend route from us (payer) to the given target node (payee). This is needed because
+/// keysend payments do not have an invoice from which to pull the payee's supported features, which
+/// makes it tricky to otherwise supply the `payee_features` parameter of `get_route`.
+pub fn get_keysend_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, payee:
+                       &PublicKey, first_hops: Option<&[&ChannelDetails]>, last_hops: &[&RouteHint],
+                       final_value_msat: u64, final_cltv: u32, logger: L) -> Result<Route,
+                       LightningError> where L::Target: Logger {
+       let invoice_features = InvoiceFeatures::for_keysend();
+       get_route(our_node_id, network, payee, Some(invoice_features), first_hops, last_hops,
+            final_value_msat, final_cltv, logger)
+}
+
 /// Gets a route from us (payer) to the given target node (payee).
 ///
 /// If the payee provided features in their invoice, they should be provided via payee_features.
@@ -882,7 +894,11 @@ pub fn get_route<L: Deref>(our_node_id: &PublicKey, network: &NetworkGraph, paye
                                        htlc_maximum_msat: hop.htlc_maximum_msat,
                                        fees: hop.fees,
                                };
-                               if add_entry!(hop.short_channel_id, hop.src_node_id, payee, directional_info, None::<u64>, &empty_channel_features, 0, path_value_msat, 0) {
+                               // We assume that the recipient only included route hints for routes which had
+                               // sufficient value to route `final_value_msat`. Note that in the case of "0-value"
+                               // invoices where the invoice does not specify value this may not be the case, but
+                               // better to include the hints than not.
+                               if add_entry!(hop.short_channel_id, hop.src_node_id, payee, directional_info, Some((final_value_msat + 999) / 1000), &empty_channel_features, 0, path_value_msat, 0) {
                                        // If this hop connects to a node with which we have a direct channel,
                                        // ignore the network graph and, if the last hop was added, add our
                                        // direct channel to the candidate set.
@@ -1198,7 +1214,7 @@ mod tests {
        use bitcoin::secp256k1::{Secp256k1, All};
 
        use prelude::*;
-       use std::sync::Arc;
+       use sync::{self, Arc};
 
        fn get_channel_details(short_channel_id: Option<u64>, node_id: PublicKey,
                        features: InitFeatures, outbound_capacity_msat: u64) -> channelmanager::ChannelDetails {
@@ -1321,7 +1337,7 @@ mod tests {
                }
        }
 
-       fn build_graph() -> (Secp256k1<All>, NetGraphMsgHandler<std::sync::Arc<test_utils::TestChainSource>, std::sync::Arc<crate::util::test_utils::TestLogger>>, std::sync::Arc<test_utils::TestChainSource>, std::sync::Arc<test_utils::TestLogger>) {
+       fn build_graph() -> (Secp256k1<All>, NetGraphMsgHandler<sync::Arc<test_utils::TestChainSource>, sync::Arc<crate::util::test_utils::TestLogger>>, sync::Arc<test_utils::TestChainSource>, sync::Arc<test_utils::TestLogger>) {
                let secp_ctx = Secp256k1::new();
                let logger = Arc::new(test_utils::TestLogger::new());
                let chain_monitor = Arc::new(test_utils::TestChainSource::new(Network::Testnet));
@@ -1992,8 +2008,7 @@ mod tests {
                let (_, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
 
                // Disable nodes 1, 2, and 8 by requiring unknown feature bits
-               let mut unknown_features = NodeFeatures::known();
-               unknown_features.set_required_unknown_bits();
+               let unknown_features = NodeFeatures::known().set_unknown_feature_required();
                add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[0], unknown_features.clone(), 1);
                add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[1], unknown_features.clone(), 1);
                add_or_update_node(&net_graph_msg_handler, &secp_ctx, &privkeys[7], unknown_features.clone(), 1);