Skip to content

Commit 61cf752

Browse files
committed
Have Route hold RouteParameters
1 parent 266a3aa commit 61cf752

File tree

7 files changed

+65
-35
lines changed

7 files changed

+65
-35
lines changed

fuzz/src/chanmon_consistency.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ fn send_payment(source: &ChanMan, dest: &ChanMan, dest_chan_id: u64, amt: u64, p
376376
fee_msat: amt,
377377
cltv_expiry_delta: 200,
378378
}], blinded_tail: None }],
379-
payment_params: None,
379+
route_params: None,
380380
}, payment_hash, RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_id)) {
381381
check_payment_err(err, amt > max_value_sendable || amt < min_value_sendable);
382382
false
@@ -409,15 +409,15 @@ fn send_hop_payment(source: &ChanMan, middle: &ChanMan, middle_chan_id: u64, des
409409
channel_features: middle.channel_features(),
410410
fee_msat: first_hop_fee,
411411
cltv_expiry_delta: 100,
412-
},RouteHop {
412+
}, RouteHop {
413413
pubkey: dest.get_our_node_id(),
414414
node_features: dest.node_features(),
415415
short_channel_id: dest_chan_id,
416416
channel_features: dest.channel_features(),
417417
fee_msat: amt,
418418
cltv_expiry_delta: 200,
419419
}], blinded_tail: None }],
420-
payment_params: None,
420+
route_params: None,
421421
}, payment_hash, RecipientOnionFields::secret_only(payment_secret), PaymentId(payment_id)) {
422422
let sent_amt = amt + first_hop_fee;
423423
check_payment_err(err, sent_amt < min_value_sendable || sent_amt > max_value_sendable);

lightning/src/ln/functional_tests.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,7 +1049,9 @@ fn fake_network_test() {
10491049
});
10501050
hops[1].fee_msat = chan_4.1.contents.fee_base_msat as u64 + chan_4.1.contents.fee_proportional_millionths as u64 * hops[2].fee_msat as u64 / 1000000;
10511051
hops[0].fee_msat = chan_3.0.contents.fee_base_msat as u64 + chan_3.0.contents.fee_proportional_millionths as u64 * hops[1].fee_msat as u64 / 1000000;
1052-
let payment_preimage_1 = send_along_route(&nodes[1], Route { paths: vec![Path { hops, blinded_tail: None }], payment_params: None }, &vec!(&nodes[2], &nodes[3], &nodes[1])[..], 1000000).0;
1052+
let payment_preimage_1 = send_along_route(&nodes[1],
1053+
Route { paths: vec![Path { hops, blinded_tail: None }], route_params: None },
1054+
&vec!(&nodes[2], &nodes[3], &nodes[1])[..], 1000000).0;
10531055

10541056
let mut hops = Vec::with_capacity(3);
10551057
hops.push(RouteHop {
@@ -1078,7 +1080,9 @@ fn fake_network_test() {
10781080
});
10791081
hops[1].fee_msat = chan_2.1.contents.fee_base_msat as u64 + chan_2.1.contents.fee_proportional_millionths as u64 * hops[2].fee_msat as u64 / 1000000;
10801082
hops[0].fee_msat = chan_3.1.contents.fee_base_msat as u64 + chan_3.1.contents.fee_proportional_millionths as u64 * hops[1].fee_msat as u64 / 1000000;
1081-
let payment_hash_2 = send_along_route(&nodes[1], Route { paths: vec![Path { hops, blinded_tail: None }], payment_params: None }, &vec!(&nodes[3], &nodes[2], &nodes[1])[..], 1000000).1;
1083+
let payment_hash_2 = send_along_route(&nodes[1],
1084+
Route { paths: vec![Path { hops, blinded_tail: None }], route_params: None },
1085+
&vec!(&nodes[3], &nodes[2], &nodes[1])[..], 1000000).1;
10821086

10831087
// Claim the rebalances...
10841088
fail_payment(&nodes[1], &vec!(&nodes[3], &nodes[2], &nodes[1])[..], payment_hash_2);

lightning/src/ln/onion_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ mod tests {
10071007
short_channel_id: 0, fee_msat: 0, cltv_expiry_delta: 0 // We fill in the payloads manually instead of generating them from RouteHops.
10081008
},
10091009
], blinded_tail: None }],
1010-
payment_params: None,
1010+
route_params: None,
10111011
};
10121012

10131013
let onion_keys = super::construct_onion_keys(&secp_ctx, &route.paths[0], &get_test_session_key()).unwrap();

lightning/src/ln/outbound_payment.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ impl OutboundPayments {
976976
}))
977977
}
978978

979-
let route = Route { paths: vec![path], payment_params: None };
979+
let route = Route { paths: vec![path], route_params: None };
980980
let onion_session_privs = self.add_new_pending_payment(payment_hash,
981981
RecipientOnionFields::spontaneous_empty(), payment_id, None, &route, None, None,
982982
entropy_source, best_block_height)?;
@@ -1145,9 +1145,9 @@ impl OutboundPayments {
11451145
results,
11461146
payment_id,
11471147
failed_paths_retry: if pending_amt_unsent != 0 {
1148-
if let Some(payment_params) = &route.payment_params {
1148+
if let Some(payment_params) = route.route_params.as_ref().map(|p| p.payment_params.clone()) {
11491149
Some(RouteParameters {
1150-
payment_params: payment_params.clone(),
1150+
payment_params: payment_params,
11511151
final_value_msat: pending_amt_unsent,
11521152
})
11531153
} else { None }
@@ -1569,7 +1569,7 @@ mod tests {
15691569
let pending_events = Mutex::new(VecDeque::new());
15701570
if on_retry {
15711571
outbound_payments.add_new_pending_payment(PaymentHash([0; 32]), RecipientOnionFields::spontaneous_empty(),
1572-
PaymentId([0; 32]), None, &Route { paths: vec![], payment_params: None },
1572+
PaymentId([0; 32]), None, &Route { paths: vec![], route_params: None },
15731573
Some(Retry::Attempts(1)), Some(expired_route_params.payment_params.clone()),
15741574
&&keys_manager, 0).unwrap();
15751575
outbound_payments.retry_payment_internal(
@@ -1613,7 +1613,7 @@ mod tests {
16131613
let pending_events = Mutex::new(VecDeque::new());
16141614
if on_retry {
16151615
outbound_payments.add_new_pending_payment(PaymentHash([0; 32]), RecipientOnionFields::spontaneous_empty(),
1616-
PaymentId([0; 32]), None, &Route { paths: vec![], payment_params: None },
1616+
PaymentId([0; 32]), None, &Route { paths: vec![], route_params: None },
16171617
Some(Retry::Attempts(1)), Some(route_params.payment_params.clone()),
16181618
&&keys_manager, 0).unwrap();
16191619
outbound_payments.retry_payment_internal(
@@ -1657,7 +1657,7 @@ mod tests {
16571657
fee_msat: 0,
16581658
cltv_expiry_delta: 0,
16591659
}], blinded_tail: None }],
1660-
payment_params: Some(payment_params),
1660+
route_params: Some(route_params.clone()),
16611661
};
16621662
router.expect_find_route(route_params.clone(), Ok(route.clone()));
16631663
let mut route_params_w_failed_scid = route_params.clone();

lightning/src/ln/payment_tests.rs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ fn mpp_retry() {
9494

9595
// Initiate the MPP payment.
9696
let payment_id = PaymentId(payment_hash.0);
97-
let mut route_params = RouteParameters::from_payment_params_and_value(route.payment_params.clone().unwrap(), amt_msat);
97+
let mut route_params = route.route_params.clone().unwrap();
9898

9999
nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
100100
nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret),
@@ -524,7 +524,7 @@ fn do_retry_with_no_persist(confirm_before_reload: bool) {
524524
let amt_msat = 1_000_000;
525525
let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat);
526526
let (payment_preimage_1, payment_hash_1, _, payment_id_1) = send_along_route(&nodes[0], route.clone(), &[&nodes[1], &nodes[2]], 1_000_000);
527-
let route_params = RouteParameters::from_payment_params_and_value(route.payment_params.clone().unwrap(), amt_msat);
527+
let route_params = route.route_params.unwrap().clone();
528528
nodes[0].node.send_payment(payment_hash, RecipientOnionFields::secret_only(payment_secret),
529529
PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
530530
check_added_monitors!(nodes[0], 1);
@@ -2211,7 +2211,7 @@ fn auto_retry_partial_failure() {
22112211
cltv_expiry_delta: 100,
22122212
}], blinded_tail: None },
22132213
],
2214-
payment_params: Some(route_params.payment_params.clone()),
2214+
route_params: Some(route_params.clone()),
22152215
};
22162216
let retry_1_route = Route {
22172217
paths: vec![
@@ -2232,7 +2232,7 @@ fn auto_retry_partial_failure() {
22322232
cltv_expiry_delta: 100,
22332233
}], blinded_tail: None },
22342234
],
2235-
payment_params: Some(route_params.payment_params.clone()),
2235+
route_params: Some(route_params.clone()),
22362236
};
22372237
let retry_2_route = Route {
22382238
paths: vec![
@@ -2245,7 +2245,7 @@ fn auto_retry_partial_failure() {
22452245
cltv_expiry_delta: 100,
22462246
}], blinded_tail: None },
22472247
],
2248-
payment_params: Some(route_params.payment_params.clone()),
2248+
route_params: Some(route_params.clone()),
22492249
};
22502250
nodes[0].router.expect_find_route(route_params.clone(), Ok(send_route));
22512251
let mut payment_params = route_params.payment_params.clone();
@@ -2497,13 +2497,13 @@ fn retry_multi_path_single_failed_payment() {
24972497
cltv_expiry_delta: 100,
24982498
}], blinded_tail: None },
24992499
],
2500-
payment_params: Some(payment_params),
2500+
route_params: Some(route_params.clone()),
25012501
};
25022502
nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
25032503
// On retry, split the payment across both channels.
25042504
route.paths[0].hops[0].fee_msat = 50_000_001;
25052505
route.paths[1].hops[0].fee_msat = 50_000_000;
2506-
let mut pay_params = route.payment_params.clone().unwrap();
2506+
let mut pay_params = route.route_params.clone().unwrap().payment_params;
25072507
pay_params.previously_failed_channels.push(chans[1].short_channel_id.unwrap());
25082508
nodes[0].router.expect_find_route(
25092509
// Note that the second request here requests the amount we originally failed to send,
@@ -2578,7 +2578,9 @@ fn immediate_retry_on_failure() {
25782578
cltv_expiry_delta: 100,
25792579
}], blinded_tail: None },
25802580
],
2581-
payment_params: Some(PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV)),
2581+
route_params: Some(RouteParameters::from_payment_params_and_value(
2582+
PaymentParameters::from_node_id(nodes[1].node.get_our_node_id(), TEST_FINAL_CLTV),
2583+
100_000_001)),
25822584
};
25832585
nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
25842586
// On retry, split the payment across both channels.
@@ -2684,7 +2686,9 @@ fn no_extra_retries_on_back_to_back_fail() {
26842686
cltv_expiry_delta: 100,
26852687
}], blinded_tail: None }
26862688
],
2687-
payment_params: Some(PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)),
2689+
route_params: Some(RouteParameters::from_payment_params_and_value(
2690+
PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV),
2691+
100_000_000)),
26882692
};
26892693
nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
26902694
let mut second_payment_params = route_params.payment_params.clone();
@@ -2882,7 +2886,9 @@ fn test_simple_partial_retry() {
28822886
cltv_expiry_delta: 100,
28832887
}], blinded_tail: None }
28842888
],
2885-
payment_params: Some(PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)),
2889+
route_params: Some(RouteParameters::from_payment_params_and_value(
2890+
PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV),
2891+
100_000_000)),
28862892
};
28872893
nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
28882894
let mut second_payment_params = route_params.payment_params.clone();
@@ -3044,7 +3050,9 @@ fn test_threaded_payment_retries() {
30443050
cltv_expiry_delta: 100,
30453051
}], blinded_tail: None }
30463052
],
3047-
payment_params: Some(PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV)),
3053+
route_params: Some(RouteParameters::from_payment_params_and_value(
3054+
PaymentParameters::from_node_id(nodes[2].node.get_our_node_id(), TEST_FINAL_CLTV),
3055+
amt_msat - amt_msat / 1000)),
30483056
};
30493057
nodes[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
30503058

@@ -3470,7 +3478,7 @@ fn test_retry_custom_tlvs() {
34703478

34713479
// Initiate the payment
34723480
let payment_id = PaymentId(payment_hash.0);
3473-
let mut route_params = RouteParameters::from_payment_params_and_value(route.payment_params.clone().unwrap(), amt_msat);
3481+
let mut route_params = route.route_params.clone().unwrap();
34743482

34753483
let custom_tlvs = vec![((1 << 16) + 1, vec![0x42u8; 16])];
34763484
let onion_fields = RecipientOnionFields::secret_only(payment_secret);

lightning/src/routing/router.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,12 @@ pub struct Route {
337337
/// [`BlindedTail`]s are present, then the pubkey of the last [`RouteHop`] in each path must be
338338
/// the same.
339339
pub paths: Vec<Path>,
340-
/// The `payment_params` parameter passed via [`RouteParameters`] to [`find_route`].
340+
/// The `route_params` parameter passed to [`find_route`].
341341
///
342342
/// This is used by `ChannelManager` to track information which may be required for retries.
343-
pub payment_params: Option<PaymentParameters>,
343+
///
344+
/// Will be `None` for objects serialized with LDK versions prior to 0.0.117.
345+
pub route_params: Option<RouteParameters>,
344346
}
345347

346348
impl Route {
@@ -383,8 +385,11 @@ impl Writeable for Route {
383385
}
384386
}
385387
write_tlv_fields!(writer, {
386-
(1, self.payment_params, option),
388+
// For compatibility with LDK versions prior to 0.0.117, we take the individual
389+
// RouteParameters' fields and reconstruct them on read.
390+
(1, self.route_params.as_ref().map(|p| &p.payment_params), option),
387391
(2, blinded_tails, optional_vec),
392+
(3, self.route_params.as_ref().map(|p| p.final_value_msat), option),
388393
});
389394
Ok(())
390395
}
@@ -411,6 +416,7 @@ impl Readable for Route {
411416
_init_and_read_len_prefixed_tlv_fields!(reader, {
412417
(1, payment_params, (option: ReadableArgs, min_final_cltv_expiry_delta)),
413418
(2, blinded_tails, optional_vec),
419+
(3, final_value_msat, option),
414420
});
415421
let blinded_tails = blinded_tails.unwrap_or(Vec::new());
416422
if blinded_tails.len() != 0 {
@@ -419,14 +425,23 @@ impl Readable for Route {
419425
path.blinded_tail = blinded_tail_opt;
420426
}
421427
}
422-
Ok(Route { paths, payment_params })
428+
429+
// If we previously wrote the corresponding fields, reconstruct RouteParameters.
430+
let route_params = match (payment_params, final_value_msat) {
431+
(Some(payment_params), Some(final_value_msat)) => {
432+
Some(RouteParameters { payment_params, final_value_msat })
433+
}
434+
_ => None,
435+
};
436+
437+
Ok(Route { paths, route_params })
423438
}
424439
}
425440

426441
/// Parameters needed to find a [`Route`].
427442
///
428443
/// Passed to [`find_route`] and [`build_route_from_hops`].
429-
#[derive(Clone, Debug, PartialEq, Eq)]
444+
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
430445
pub struct RouteParameters {
431446
/// The parameters of the failed payment path.
432447
pub payment_params: PaymentParameters,
@@ -2489,7 +2504,7 @@ where L::Target: Logger {
24892504
}
24902505
}
24912506

2492-
let route = Route { paths, payment_params: Some(payment_params.clone()) };
2507+
let route = Route { paths, route_params: Some(route_params.clone()) };
24932508
log_info!(logger, "Got route: {}", log_route!(route));
24942509
Ok(route)
24952510
}
@@ -5953,7 +5968,7 @@ mod tests {
59535968
short_channel_id: 0, fee_msat: 225, cltv_expiry_delta: 0
59545969
},
59555970
], blinded_tail: None }],
5956-
payment_params: None,
5971+
route_params: None,
59575972
};
59585973

59595974
assert_eq!(route.get_total_fees(), 250);
@@ -5986,7 +6001,7 @@ mod tests {
59866001
short_channel_id: 0, fee_msat: 150, cltv_expiry_delta: 0
59876002
},
59886003
], blinded_tail: None }],
5989-
payment_params: None,
6004+
route_params: None,
59906005
};
59916006

59926007
assert_eq!(route.get_total_fees(), 200);
@@ -5998,7 +6013,7 @@ mod tests {
59986013
// In an earlier version of `Route::get_total_fees` and `Route::get_total_amount`, they
59996014
// would both panic if the route was completely empty. We test to ensure they return 0
60006015
// here, even though its somewhat nonsensical as a route.
6001-
let route = Route { paths: Vec::new(), payment_params: None };
6016+
let route = Route { paths: Vec::new(), route_params: None };
60026017

60036018
assert_eq!(route.get_total_fees(), 0);
60046019
assert_eq!(route.get_total_amount(), 0);
@@ -6597,7 +6612,7 @@ mod tests {
65976612
fee_msat: 100,
65986613
cltv_expiry_delta: 0,
65996614
}], blinded_tail: None }],
6600-
payment_params: None,
6615+
route_params: None,
66016616
};
66026617
let encoded_route = route.encode();
66036618
let decoded_route: Route = Readable::read(&mut Cursor::new(&encoded_route[..])).unwrap();
@@ -6691,7 +6706,7 @@ mod tests {
66916706
excess_final_cltv_expiry_delta: 0,
66926707
final_value_msat: 200,
66936708
}),
6694-
}], payment_params: None};
6709+
}], route_params: None};
66956710

66966711
let payment_params = PaymentParameters::from_node_id(ln_test_utils::pubkey(47), 18);
66976712
let (_, network_graph, _, _, _) = build_line_graph();
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Backwards Compatibility
2+
3+
- `Route` objects written with LDK versions prior to 0.0.117 won't be retryable after being deserialized with LDK 0.0.117 or above.

0 commit comments

Comments
 (0)