From: Matt Corallo Date: Tue, 26 Sep 2023 21:58:53 +0000 (+0000) Subject: Try to overpay the recipient if we fail to find a path at all X-Git-Tag: v0.0.117-rc1~13^2~2 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=f3e33f40742e0543850a181718335e5d54e3bb7c;p=rust-lightning Try to overpay the recipient if we fail to find a path at all Previously we'd only try to overpay if we managed to find a path to the recipient which was sufficient. However, if we fail to find any path to the recipient at all we should still retry overpaying the recipient. Ultimately we should be silling to pay whatever reasonable performance penalty if the alternative is not finding a path at all, which we do here. --- diff --git a/lightning/src/routing/router.rs b/lightning/src/routing/router.rs index 1c51bb98..bca681df 100644 --- a/lightning/src/routing/router.rs +++ b/lightning/src/routing/router.rs @@ -2454,6 +2454,9 @@ where L::Target: Logger { // because we deterministically terminated the search due to low liquidity. if !found_new_path && channel_saturation_pow_half != 0 { channel_saturation_pow_half = 0; + } else if !found_new_path && hit_minimum_limit && already_collected_value_msat < final_value_msat && path_value_msat != recommended_value_msat { + log_trace!(logger, "Failed to collect enough value, but running again to collect extra paths with a potentially higher limit."); + path_value_msat = recommended_value_msat; } else if already_collected_value_msat >= recommended_value_msat || !found_new_path { log_trace!(logger, "Have now collected {} msat (seeking {} msat) in paths. Last path loop {} a new path.", already_collected_value_msat, recommended_value_msat, if found_new_path { "found" } else { "did not find" }); @@ -3223,6 +3226,56 @@ mod tests { assert_eq!(fees, 5_000); } + #[test] + fn htlc_minimum_recipient_overpay_test() { + let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph(); + let (_, our_id, privkeys, nodes) = get_nodes(&secp_ctx); + let config = UserConfig::default(); + let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_bolt11_features(channelmanager::provided_invoice_features(&config)).unwrap(); + let scorer = ln_test_utils::TestScorer::new(); + let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet); + let random_seed_bytes = keys_manager.get_secure_random_bytes(); + + // Route to node2 over a single path which requires overpaying the recipient themselves. + + // First disable all paths except the us -> node1 -> node2 path + update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate { + chain_hash: genesis_block(Network::Testnet).header.block_hash(), + short_channel_id: 13, + timestamp: 2, + flags: 3, + cltv_expiry_delta: 0, + htlc_minimum_msat: 0, + htlc_maximum_msat: 0, + fee_base_msat: 0, + fee_proportional_millionths: 0, + excess_data: Vec::new() + }); + + // Set channel 4 to free but with a high htlc_minimum_msat + update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate { + chain_hash: genesis_block(Network::Testnet).header.block_hash(), + short_channel_id: 4, + timestamp: 2, + flags: 0, + cltv_expiry_delta: 0, + htlc_minimum_msat: 15_000, + htlc_maximum_msat: MAX_VALUE_MSAT, + fee_base_msat: 0, + fee_proportional_millionths: 0, + excess_data: Vec::new() + }); + + // Now check that we'll find a path if the htlc_minimum is overrun substantially. + let mut route_params = RouteParameters::from_payment_params_and_value( + payment_params.clone(), 5_000); + // TODO: This can even overrun the fee limit set by the recipient! + route_params.max_total_routing_fee_msat = Some(9_999); + let route = get_route(&our_id, &route_params, &network_graph.read_only(), None, + Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap(); + assert_eq!(route.get_total_fees(), 10_000); + } + #[test] fn disable_channels_test() { let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();