Skip to content

Commit f38ab14

Browse files
committed
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.
1 parent 8b7ee68 commit f38ab14

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

lightning/src/routing/router.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,6 +2455,9 @@ where L::Target: Logger {
24552455
// because we deterministically terminated the search due to low liquidity.
24562456
if !found_new_path && channel_saturation_pow_half != 0 {
24572457
channel_saturation_pow_half = 0;
2458+
} else if already_collected_value_msat < final_value_msat && path_value_msat != recommended_value_msat && !found_new_path {
2459+
log_trace!(logger, "Failed to collect enough value, but running again to collect extra paths with a potentially higher limit.");
2460+
path_value_msat = recommended_value_msat;
24582461
} else if already_collected_value_msat >= recommended_value_msat || !found_new_path {
24592462
log_trace!(logger, "Have now collected {} msat (seeking {} msat) in paths. Last path loop {} a new path.",
24602463
already_collected_value_msat, recommended_value_msat, if found_new_path { "found" } else { "did not find" });
@@ -3224,6 +3227,56 @@ mod tests {
32243227
assert_eq!(fees, 5_000);
32253228
}
32263229

3230+
#[test]
3231+
fn htlc_minimum_recipient_overpay_test() {
3232+
let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();
3233+
let (our_privkey, our_id, privkeys, nodes) = get_nodes(&secp_ctx);
3234+
let config = UserConfig::default();
3235+
let payment_params = PaymentParameters::from_node_id(nodes[2], 42).with_bolt11_features(channelmanager::provided_invoice_features(&config)).unwrap();
3236+
let scorer = ln_test_utils::TestScorer::new();
3237+
let keys_manager = ln_test_utils::TestKeysInterface::new(&[0u8; 32], Network::Testnet);
3238+
let random_seed_bytes = keys_manager.get_secure_random_bytes();
3239+
3240+
// Route to node2 over a single path which requires overpaying the recipient themselves.
3241+
3242+
// First disable all paths except the us -> node1 -> node2 path
3243+
update_channel(&gossip_sync, &secp_ctx, &privkeys[2], UnsignedChannelUpdate {
3244+
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
3245+
short_channel_id: 13,
3246+
timestamp: 2,
3247+
flags: 3,
3248+
cltv_expiry_delta: 0,
3249+
htlc_minimum_msat: 0,
3250+
htlc_maximum_msat: 0,
3251+
fee_base_msat: 0,
3252+
fee_proportional_millionths: 0,
3253+
excess_data: Vec::new()
3254+
});
3255+
3256+
// Set channel 4 to free but with a high htlc_minimum_msat
3257+
update_channel(&gossip_sync, &secp_ctx, &privkeys[1], UnsignedChannelUpdate {
3258+
chain_hash: genesis_block(Network::Testnet).header.block_hash(),
3259+
short_channel_id: 4,
3260+
timestamp: 2,
3261+
flags: 0,
3262+
cltv_expiry_delta: 0,
3263+
htlc_minimum_msat: 15_000,
3264+
htlc_maximum_msat: MAX_VALUE_MSAT,
3265+
fee_base_msat: 0,
3266+
fee_proportional_millionths: 0,
3267+
excess_data: Vec::new()
3268+
});
3269+
3270+
// Now check that we'll find a path if the htlc_minimum is overrun substantially.
3271+
let mut route_params = RouteParameters::from_payment_params_and_value(
3272+
payment_params.clone(), 5_000);
3273+
// TODO: This can even overrun the fee limit set by the recipient!
3274+
route_params.max_total_routing_fee_msat = Some(9_999);
3275+
let route = get_route(&our_id, &route_params, &network_graph.read_only(), None,
3276+
Arc::clone(&logger), &scorer, &Default::default(), &random_seed_bytes).unwrap();
3277+
assert_eq!(route.get_total_fees(), 10_000);
3278+
}
3279+
32273280
#[test]
32283281
fn disable_channels_test() {
32293282
let (secp_ctx, network_graph, gossip_sync, _, logger) = build_graph();

0 commit comments

Comments
 (0)