Skip to content

Commit f106a82

Browse files
committed
Remove the final_cltv_expiry_delta in RouteParameters entirely
fbc0847 purported to "move" the `final_cltv_expiry_delta` field to `PaymentParamters` from `RouteParameters`. However, for naive backwards-compatibility reasons it left the existing on in place and only added a new, redundant field in `PaymentParameters`. It turns out there's really no reason for this - if we take a more critical eye towards backwards compatibility we can figure out the correct value in every `PaymentParameters` while deserializing. We do this here - making `PaymentParameters` a `ReadableArgs` taking a "default" `cltv_expiry_delta` when it goes to read. This allows existing `RouteParameters` objects to pass the read `final_cltv_expiry_delta` field in to be used if the new field wasn't present.
1 parent 0fb6ea6 commit f106a82

File tree

7 files changed

+105
-84
lines changed

7 files changed

+105
-84
lines changed

lightning-invoice/src/payment.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ fn pay_invoice_using_amount<P: Deref>(
156156
let route_params = RouteParameters {
157157
payment_params,
158158
final_value_msat: amount_msats,
159-
final_cltv_expiry_delta: invoice.min_final_cltv_expiry_delta() as u32,
160159
};
161160

162161
payer.send_payment(payment_hash, &payment_secret, payment_id, route_params, retry_strategy)

lightning-invoice/src/utils.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,6 @@ mod test {
686686
let route_params = RouteParameters {
687687
payment_params,
688688
final_value_msat: invoice.amount_milli_satoshis().unwrap(),
689-
final_cltv_expiry_delta: invoice.min_final_cltv_expiry_delta() as u32,
690689
};
691690
let first_hops = nodes[0].node.list_usable_channels();
692691
let network_graph = &node_cfgs[0].network_graph;
@@ -1050,7 +1049,6 @@ mod test {
10501049
let params = RouteParameters {
10511050
payment_params,
10521051
final_value_msat: invoice.amount_milli_satoshis().unwrap(),
1053-
final_cltv_expiry_delta: invoice.min_final_cltv_expiry_delta() as u32,
10541052
};
10551053
let first_hops = nodes[0].node.list_usable_channels();
10561054
let network_graph = &node_cfgs[0].network_graph;

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6793,14 +6793,14 @@ impl Readable for HTLCSource {
67936793
let mut path: Option<Vec<RouteHop>> = Some(Vec::new());
67946794
let mut payment_id = None;
67956795
let mut payment_secret = None;
6796-
let mut payment_params = None;
6796+
let mut payment_params: Option<PaymentParameters> = None;
67976797
read_tlv_fields!(reader, {
67986798
(0, session_priv, required),
67996799
(1, payment_id, option),
68006800
(2, first_hop_htlc_msat, required),
68016801
(3, payment_secret, option),
68026802
(4, path, vec_type),
6803-
(5, payment_params, option),
6803+
(5, payment_params, (option: ReadableArgs, 0)),
68046804
});
68056805
if payment_id.is_none() {
68066806
// For backwards compat, if there was no payment_id written, use the session_priv bytes
@@ -6811,6 +6811,11 @@ impl Readable for HTLCSource {
68116811
return Err(DecodeError::InvalidValue);
68126812
}
68136813
let path = path.unwrap();
6814+
if let Some(params) = payment_params.as_mut() {
6815+
if params.final_cltv_expiry_delta == 0 {
6816+
params.final_cltv_expiry_delta = path.last().unwrap().cltv_expiry_delta;
6817+
}
6818+
}
68146819
Ok(HTLCSource::OutboundRoute {
68156820
session_priv: session_priv.0.unwrap(),
68166821
first_hop_htlc_msat,
@@ -7991,7 +7996,6 @@ mod tests {
79917996
let route_params = RouteParameters {
79927997
payment_params: PaymentParameters::for_keysend(expected_route.last().unwrap().node.get_our_node_id(), TEST_FINAL_CLTV),
79937998
final_value_msat: 100_000,
7994-
final_cltv_expiry_delta: TEST_FINAL_CLTV,
79957999
};
79968000
let route = find_route(
79978001
&nodes[0].node.get_our_node_id(), &route_params, &nodes[0].network_graph,
@@ -8082,7 +8086,6 @@ mod tests {
80828086
let route_params = RouteParameters {
80838087
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40),
80848088
final_value_msat: 10_000,
8085-
final_cltv_expiry_delta: 40,
80868089
};
80878090
let network_graph = nodes[0].network_graph.clone();
80888091
let first_hops = nodes[0].node.list_usable_channels();
@@ -8125,7 +8128,6 @@ mod tests {
81258128
let route_params = RouteParameters {
81268129
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40),
81278130
final_value_msat: 10_000,
8128-
final_cltv_expiry_delta: 40,
81298131
};
81308132
let network_graph = nodes[0].network_graph.clone();
81318133
let first_hops = nodes[0].node.list_usable_channels();

lightning/src/ln/functional_tests.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9250,7 +9250,6 @@ fn test_keysend_payments_to_public_node() {
92509250
let route_params = RouteParameters {
92519251
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40),
92529252
final_value_msat: 10000,
9253-
final_cltv_expiry_delta: 40,
92549253
};
92559254
let scorer = test_utils::TestScorer::new();
92569255
let random_seed_bytes = chanmon_cfgs[1].keys_manager.get_secure_random_bytes();
@@ -9281,7 +9280,6 @@ fn test_keysend_payments_to_private_node() {
92819280
let route_params = RouteParameters {
92829281
payment_params: PaymentParameters::for_keysend(payee_pubkey, 40),
92839282
final_value_msat: 10000,
9284-
final_cltv_expiry_delta: 40,
92859283
};
92869284
let network_graph = nodes[0].network_graph.clone();
92879285
let first_hops = nodes[0].node.list_usable_channels();

lightning/src/ln/outbound_payment.rs

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use bitcoin::secp256k1::{self, Secp256k1, SecretKey};
1616
use crate::chain::keysinterface::{EntropySource, NodeSigner, Recipient};
1717
use crate::ln::{PaymentHash, PaymentPreimage, PaymentSecret};
1818
use crate::ln::channelmanager::{ChannelDetails, HTLCSource, IDEMPOTENCY_TIMEOUT_TICKS, MIN_HTLC_RELAY_HOLDING_CELL_MILLIS, PaymentId};
19-
use crate::ln::channelmanager::MIN_FINAL_CLTV_EXPIRY_DELTA as LDK_DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA;
2019
use crate::ln::msgs::DecodeError;
2120
use crate::ln::onion_utils::HTLCFailReason;
2221
use crate::routing::router::{InFlightHtlcs, PaymentParameters, Route, RouteHop, RouteParameters, RoutePath, Router};
@@ -26,6 +25,7 @@ use crate::util::logger::Logger;
2625
use crate::util::time::Time;
2726
#[cfg(all(not(feature = "no-std"), test))]
2827
use crate::util::time::tests::SinceEpoch;
28+
use crate::util::ser::ReadableArgs;
2929

3030
use core::cmp;
3131
use core::fmt::{self, Display, Formatter};
@@ -503,12 +503,6 @@ impl OutboundPayments {
503503
if pending_amt_msat < total_msat {
504504
retry_id_route_params = Some((*pmt_id, RouteParameters {
505505
final_value_msat: *total_msat - *pending_amt_msat,
506-
final_cltv_expiry_delta:
507-
if let Some(delta) = params.final_cltv_expiry_delta { delta }
508-
else {
509-
debug_assert!(false, "We always set the final_cltv_expiry_delta when a path fails");
510-
LDK_DEFAULT_MIN_FINAL_CLTV_EXPIRY_DELTA.into()
511-
},
512506
payment_params: params.clone(),
513507
}));
514508
break
@@ -854,9 +848,6 @@ impl OutboundPayments {
854848
Some(RouteParameters {
855849
payment_params: payment_params.clone(),
856850
final_value_msat: pending_amt_unsent,
857-
final_cltv_expiry_delta:
858-
if let Some(delta) = payment_params.final_cltv_expiry_delta { delta }
859-
else { max_unsent_cltv_delta },
860851
})
861852
} else { None }
862853
} else { None },
@@ -1042,23 +1033,14 @@ impl OutboundPayments {
10421033
// `payment_params`) back to the user.
10431034
let path_last_hop = path.last().expect("Outbound payments must have had a valid path");
10441035
if let Some(params) = payment.get_mut().payment_parameters() {
1045-
if params.final_cltv_expiry_delta.is_none() {
1046-
// This should be rare, but a user could provide None for the payment data, and
1047-
// we need it when we go to retry the payment, so fill it in.
1048-
params.final_cltv_expiry_delta = Some(path_last_hop.cltv_expiry_delta);
1049-
}
10501036
retry = Some(RouteParameters {
10511037
payment_params: params.clone(),
10521038
final_value_msat: path_last_hop.fee_msat,
1053-
final_cltv_expiry_delta: params.final_cltv_expiry_delta.unwrap(),
10541039
});
10551040
} else if let Some(params) = payment_params {
10561041
retry = Some(RouteParameters {
10571042
payment_params: params.clone(),
10581043
final_value_msat: path_last_hop.fee_msat,
1059-
final_cltv_expiry_delta:
1060-
if let Some(delta) = params.final_cltv_expiry_delta { delta }
1061-
else { path_last_hop.cltv_expiry_delta },
10621044
});
10631045
}
10641046

@@ -1195,7 +1177,9 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
11951177
(0, session_privs, required),
11961178
(1, pending_fee_msat, option),
11971179
(2, payment_hash, required),
1198-
(3, payment_params, option),
1180+
// Note that while we "default" payment_param's final CLTV expiry delta to 0 we should
1181+
// never see it - `payment_params` was added here after the field was added/required.
1182+
(3, payment_params, (option: ReadableArgs, 0)),
11991183
(4, payment_secret, option),
12001184
(5, keysend_preimage, option),
12011185
(6, total_msat, required),
@@ -1251,7 +1235,6 @@ mod tests {
12511235
let expired_route_params = RouteParameters {
12521236
payment_params,
12531237
final_value_msat: 0,
1254-
final_cltv_expiry_delta: 0,
12551238
};
12561239
let err = if on_retry {
12571240
outbound_payments.pay_internal(
@@ -1288,7 +1271,6 @@ mod tests {
12881271
let route_params = RouteParameters {
12891272
payment_params,
12901273
final_value_msat: 0,
1291-
final_cltv_expiry_delta: 0,
12921274
};
12931275
router.expect_find_route(route_params.clone(),
12941276
Err(LightningError { err: String::new(), action: ErrorAction::IgnoreError }));

lightning/src/ln/payment_tests.rs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,12 +1384,12 @@ fn do_test_intercepted_payment(test: InterceptTest) {
13841384
let route_params = RouteParameters {
13851385
payment_params,
13861386
final_value_msat: amt_msat,
1387-
final_cltv_expiry_delta: TEST_FINAL_CLTV,
13881387
};
13891388
let route = get_route(
13901389
&nodes[0].node.get_our_node_id(), &route_params.payment_params,
13911390
&nodes[0].network_graph.read_only(), None, route_params.final_value_msat,
1392-
route_params.final_cltv_expiry_delta, nodes[0].logger, &scorer, &random_seed_bytes
1391+
route_params.payment_params.final_cltv_expiry_delta, nodes[0].logger, &scorer,
1392+
&random_seed_bytes,
13931393
).unwrap();
13941394

13951395
let (payment_hash, payment_secret) = nodes[2].node.create_inbound_payment(Some(amt_msat), 60 * 60, None).unwrap();
@@ -1574,7 +1574,6 @@ fn do_automatic_retries(test: AutoRetry) {
15741574
let route_params = RouteParameters {
15751575
payment_params,
15761576
final_value_msat: amt_msat,
1577-
final_cltv_expiry_delta: TEST_FINAL_CLTV,
15781577
};
15791578
let (_, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat);
15801579

@@ -1783,7 +1782,6 @@ fn auto_retry_partial_failure() {
17831782
let route_params = RouteParameters {
17841783
payment_params,
17851784
final_value_msat: amt_msat,
1786-
final_cltv_expiry_delta: TEST_FINAL_CLTV,
17871785
};
17881786

17891787
// Ensure the first monitor update (for the initial send path1 over chan_1) succeeds, but the
@@ -1855,11 +1853,11 @@ fn auto_retry_partial_failure() {
18551853
nodes[0].router.expect_find_route(route_params.clone(), Ok(send_route));
18561854
nodes[0].router.expect_find_route(RouteParameters {
18571855
payment_params: route_params.payment_params.clone(),
1858-
final_value_msat: amt_msat / 2, final_cltv_expiry_delta: TEST_FINAL_CLTV
1856+
final_value_msat: amt_msat / 2,
18591857
}, Ok(retry_1_route));
18601858
nodes[0].router.expect_find_route(RouteParameters {
18611859
payment_params: route_params.payment_params.clone(),
1862-
final_value_msat: amt_msat / 4, final_cltv_expiry_delta: TEST_FINAL_CLTV
1860+
final_value_msat: amt_msat / 4,
18631861
}, Ok(retry_2_route));
18641862

18651863
// Send a payment that will partially fail on send, then partially fail on retry, then succeed.
@@ -1985,7 +1983,6 @@ fn auto_retry_zero_attempts_send_error() {
19851983
let route_params = RouteParameters {
19861984
payment_params,
19871985
final_value_msat: amt_msat,
1988-
final_cltv_expiry_delta: TEST_FINAL_CLTV,
19891986
};
19901987

19911988
chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::PermanentFailure);
@@ -2023,7 +2020,6 @@ fn fails_paying_after_rejected_by_payee() {
20232020
let route_params = RouteParameters {
20242021
payment_params,
20252022
final_value_msat: amt_msat,
2026-
final_cltv_expiry_delta: TEST_FINAL_CLTV,
20272023
};
20282024

20292025
nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
@@ -2070,7 +2066,6 @@ fn retry_multi_path_single_failed_payment() {
20702066
let route_params = RouteParameters {
20712067
payment_params: payment_params.clone(),
20722068
final_value_msat: amt_msat,
2073-
final_cltv_expiry_delta: TEST_FINAL_CLTV,
20742069
};
20752070

20762071
let chans = nodes[0].node.list_usable_channels();
@@ -2103,7 +2098,7 @@ fn retry_multi_path_single_failed_payment() {
21032098
payment_params: route.payment_params.clone().unwrap(),
21042099
// Note that the second request here requests the amount we originally failed to send,
21052100
// not the amount remaining on the full payment, which should be changed.
2106-
final_value_msat: 100_000_001, final_cltv_expiry_delta: TEST_FINAL_CLTV
2101+
final_value_msat: 100_000_001,
21072102
}, Ok(route.clone()));
21082103

21092104
{
@@ -2149,7 +2144,6 @@ fn immediate_retry_on_failure() {
21492144
let route_params = RouteParameters {
21502145
payment_params,
21512146
final_value_msat: amt_msat,
2152-
final_cltv_expiry_delta: TEST_FINAL_CLTV,
21532147
};
21542148

21552149
let chans = nodes[0].node.list_usable_channels();
@@ -2174,7 +2168,7 @@ fn immediate_retry_on_failure() {
21742168
route.paths[1][0].fee_msat = 50_000_001;
21752169
nodes[0].router.expect_find_route(RouteParameters {
21762170
payment_params: route_params.payment_params.clone(),
2177-
final_value_msat: amt_msat, final_cltv_expiry_delta: TEST_FINAL_CLTV
2171+
final_value_msat: amt_msat,
21782172
}, Ok(route.clone()));
21792173

21802174
nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
@@ -2223,7 +2217,6 @@ fn no_extra_retries_on_back_to_back_fail() {
22232217
let route_params = RouteParameters {
22242218
payment_params,
22252219
final_value_msat: amt_msat,
2226-
final_cltv_expiry_delta: TEST_FINAL_CLTV,
22272220
};
22282221

22292222
let mut route = Route {
@@ -2269,7 +2262,7 @@ fn no_extra_retries_on_back_to_back_fail() {
22692262
route.paths[0][1].fee_msat = amt_msat;
22702263
nodes[0].router.expect_find_route(RouteParameters {
22712264
payment_params: second_payment_params,
2272-
final_value_msat: amt_msat, final_cltv_expiry_delta: TEST_FINAL_CLTV,
2265+
final_value_msat: amt_msat,
22732266
}, Ok(route.clone()));
22742267

22752268
nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();
@@ -2428,7 +2421,6 @@ fn test_simple_partial_retry() {
24282421
let route_params = RouteParameters {
24292422
payment_params,
24302423
final_value_msat: amt_msat,
2431-
final_cltv_expiry_delta: TEST_FINAL_CLTV,
24322424
};
24332425

24342426
let mut route = Route {
@@ -2473,7 +2465,7 @@ fn test_simple_partial_retry() {
24732465
route.paths.remove(0);
24742466
nodes[0].router.expect_find_route(RouteParameters {
24752467
payment_params: second_payment_params,
2476-
final_value_msat: amt_msat / 2, final_cltv_expiry_delta: TEST_FINAL_CLTV,
2468+
final_value_msat: amt_msat / 2,
24772469
}, Ok(route.clone()));
24782470

24792471
nodes[0].node.send_payment_with_retry(payment_hash, &Some(payment_secret), PaymentId(payment_hash.0), route_params, Retry::Attempts(1)).unwrap();

0 commit comments

Comments
 (0)