Skip to content

Commit 37bf61c

Browse files
authored
Merge pull request #3026 from valentinewallace/2024-04-limit-path-len
Limit payment path length based on `payment_metadata`, custom TLVs, etc.
2 parents 511d7e3 + 3cc673b commit 37bf61c

15 files changed

+698
-160
lines changed

lightning/src/ln/blinded_payment_tests.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,10 @@ fn do_forward_checks_failure(check: ForwardCheckFail, intro_fails: bool) {
282282

283283
let amt_msat = 5000;
284284
let (_, payment_hash, payment_secret) = get_payment_preimage_hash(&nodes[3], Some(amt_msat), None);
285-
let route_params = get_blinded_route_parameters(amt_msat, payment_secret, 1, 1_0000_0000,
285+
let mut route_params = get_blinded_route_parameters(amt_msat, payment_secret, 1, 1_0000_0000,
286286
nodes.iter().skip(1).map(|n| n.node.get_our_node_id()).collect(),
287287
&[&chan_upd_1_2, &chan_upd_2_3], &chanmon_cfgs[3].keys_manager);
288+
route_params.payment_params.max_path_length = 18;
288289

289290
let route = get_route(&nodes[0], &route_params).unwrap();
290291
node_cfgs[0].router.expect_find_route(route_params.clone(), Ok(route.clone()));
@@ -298,11 +299,12 @@ fn do_forward_checks_failure(check: ForwardCheckFail, intro_fails: bool) {
298299
$update_add.cltv_expiry = 10; // causes outbound CLTV expiry to underflow
299300
},
300301
ForwardCheckFail::ForwardPayloadEncodedAsReceive => {
302+
let recipient_onion_fields = RecipientOnionFields::spontaneous_empty();
301303
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
302304
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
303305
let cur_height = nodes[0].best_block_info().1;
304306
let (mut onion_payloads, ..) = onion_utils::build_onion_payloads(
305-
&route.paths[0], amt_msat, RecipientOnionFields::spontaneous_empty(), cur_height, &None).unwrap();
307+
&route.paths[0], amt_msat, &recipient_onion_fields, cur_height, &None).unwrap();
306308
// Remove the receive payload so the blinded forward payload is encoded as a final payload
307309
// (i.e. next_hop_hmac == [0; 32])
308310
onion_payloads.pop();
@@ -875,8 +877,9 @@ fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
875877
let session_priv = SecretKey::from_slice(&session_priv).unwrap();
876878
let mut onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
877879
let cur_height = nodes[0].best_block_info().1;
880+
let recipient_onion_fields = RecipientOnionFields::spontaneous_empty();
878881
let (mut onion_payloads, ..) = onion_utils::build_onion_payloads(
879-
&route.paths[0], amt_msat, RecipientOnionFields::spontaneous_empty(), cur_height, &None).unwrap();
882+
&route.paths[0], amt_msat, &recipient_onion_fields, cur_height, &None).unwrap();
880883

881884
let update_add = &mut payment_event_1_2.msgs[0];
882885
onion_payloads.last_mut().map(|p| {

lightning/src/ln/channelmanager.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4084,8 +4084,8 @@ where
40844084
pub(crate) fn test_send_payment_along_path(&self, path: &Path, payment_hash: &PaymentHash, recipient_onion: RecipientOnionFields, total_value: u64, cur_height: u32, payment_id: PaymentId, keysend_preimage: &Option<PaymentPreimage>, session_priv_bytes: [u8; 32]) -> Result<(), APIError> {
40854085
let _lck = self.total_consistency_lock.read().unwrap();
40864086
self.send_payment_along_path(SendAlongPathArgs {
4087-
path, payment_hash, recipient_onion, total_value, cur_height, payment_id, keysend_preimage,
4088-
session_priv_bytes
4087+
path, payment_hash, recipient_onion: &recipient_onion, total_value,
4088+
cur_height, payment_id, keysend_preimage, session_priv_bytes
40894089
})
40904090
}
40914091

lightning/src/ln/functional_test_utils.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -2535,6 +2535,7 @@ pub struct PassAlongPathArgs<'a, 'b, 'c, 'd> {
25352535
pub expected_preimage: Option<PaymentPreimage>,
25362536
pub is_probe: bool,
25372537
pub custom_tlvs: Vec<(u64, Vec<u8>)>,
2538+
pub payment_metadata: Option<Vec<u8>>,
25382539
}
25392540

25402541
impl<'a, 'b, 'c, 'd> PassAlongPathArgs<'a, 'b, 'c, 'd> {
@@ -2545,7 +2546,7 @@ impl<'a, 'b, 'c, 'd> PassAlongPathArgs<'a, 'b, 'c, 'd> {
25452546
Self {
25462547
origin_node, expected_path, recv_value, payment_hash, payment_secret: None, event,
25472548
payment_claimable_expected: true, clear_recipient_events: true, expected_preimage: None,
2548-
is_probe: false, custom_tlvs: Vec::new(),
2549+
is_probe: false, custom_tlvs: Vec::new(), payment_metadata: None,
25492550
}
25502551
}
25512552
pub fn without_clearing_recipient_events(mut self) -> Self {
@@ -2573,13 +2574,17 @@ impl<'a, 'b, 'c, 'd> PassAlongPathArgs<'a, 'b, 'c, 'd> {
25732574
self.custom_tlvs = custom_tlvs;
25742575
self
25752576
}
2577+
pub fn with_payment_metadata(mut self, payment_metadata: Vec<u8>) -> Self {
2578+
self.payment_metadata = Some(payment_metadata);
2579+
self
2580+
}
25762581
}
25772582

25782583
pub fn do_pass_along_path<'a, 'b, 'c>(args: PassAlongPathArgs) -> Option<Event> {
25792584
let PassAlongPathArgs {
25802585
origin_node, expected_path, recv_value, payment_hash: our_payment_hash,
25812586
payment_secret: our_payment_secret, event: ev, payment_claimable_expected,
2582-
clear_recipient_events, expected_preimage, is_probe, custom_tlvs
2587+
clear_recipient_events, expected_preimage, is_probe, custom_tlvs, payment_metadata,
25832588
} = args;
25842589

25852590
let mut payment_event = SendEvent::from_event(ev);
@@ -2613,6 +2618,7 @@ pub fn do_pass_along_path<'a, 'b, 'c>(args: PassAlongPathArgs) -> Option<Event>
26132618
assert_eq!(node.node.get_our_node_id(), receiver_node_id.unwrap());
26142619
assert!(onion_fields.is_some());
26152620
assert_eq!(onion_fields.as_ref().unwrap().custom_tlvs, custom_tlvs);
2621+
assert_eq!(onion_fields.as_ref().unwrap().payment_metadata, payment_metadata);
26162622
match &purpose {
26172623
PaymentPurpose::Bolt11InvoicePayment { payment_preimage, payment_secret, .. } => {
26182624
assert_eq!(expected_preimage, *payment_preimage);

lightning/src/ln/functional_tests.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -1401,8 +1401,9 @@ fn test_fee_spike_violation_fails_htlc() {
14011401
let cur_height = nodes[1].node.best_block.read().unwrap().height + 1;
14021402

14031403
let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap();
1404+
let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret);
14041405
let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0],
1405-
3460001, RecipientOnionFields::secret_only(payment_secret), cur_height, &None).unwrap();
1406+
3460001, &recipient_onion_fields, cur_height, &None).unwrap();
14061407
let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash).unwrap();
14071408
let msg = msgs::UpdateAddHTLC {
14081409
channel_id: chan.2,
@@ -1598,8 +1599,9 @@ fn test_chan_reserve_violation_inbound_htlc_outbound_channel() {
15981599
let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
15991600
let cur_height = nodes[1].node.best_block.read().unwrap().height + 1;
16001601
let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap();
1602+
let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret);
16011603
let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(&route.paths[0],
1602-
700_000, RecipientOnionFields::secret_only(payment_secret), cur_height, &None).unwrap();
1604+
700_000, &recipient_onion_fields, cur_height, &None).unwrap();
16031605
let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash).unwrap();
16041606
let msg = msgs::UpdateAddHTLC {
16051607
channel_id: chan.2,
@@ -1777,8 +1779,9 @@ fn test_chan_reserve_violation_inbound_htlc_inbound_chan() {
17771779
let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
17781780
let cur_height = nodes[0].node.best_block.read().unwrap().height + 1;
17791781
let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route_2.paths[0], &session_priv).unwrap();
1782+
let recipient_onion_fields = RecipientOnionFields::spontaneous_empty();
17801783
let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
1781-
&route_2.paths[0], recv_value_2, RecipientOnionFields::spontaneous_empty(), cur_height, &None).unwrap();
1784+
&route_2.paths[0], recv_value_2, &recipient_onion_fields, cur_height, &None).unwrap();
17821785
let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &our_payment_hash_1).unwrap();
17831786
let msg = msgs::UpdateAddHTLC {
17841787
channel_id: chan.2,
@@ -3501,8 +3504,9 @@ fn fail_backward_pending_htlc_upon_channel_failure() {
35013504
let secp_ctx = Secp256k1::new();
35023505
let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
35033506
let current_height = nodes[1].node.best_block.read().unwrap().height + 1;
3507+
let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret);
35043508
let (onion_payloads, _amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(
3505-
&route.paths[0], 50_000, RecipientOnionFields::secret_only(payment_secret), current_height, &None).unwrap();
3509+
&route.paths[0], 50_000, &recipient_onion_fields, current_height, &None).unwrap();
35063510
let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv).unwrap();
35073511
let onion_routing_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash).unwrap();
35083512

@@ -6487,8 +6491,9 @@ fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() {
64876491
let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
64886492
let cur_height = nodes[0].node.best_block.read().unwrap().height + 1;
64896493
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::signing_only(), &route.paths[0], &session_priv).unwrap();
6494+
let recipient_onion_fields = RecipientOnionFields::secret_only(our_payment_secret);
64906495
let (onion_payloads, _htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
6491-
&route.paths[0], send_amt, RecipientOnionFields::secret_only(our_payment_secret), cur_height, &None).unwrap();
6496+
&route.paths[0], send_amt, &recipient_onion_fields, cur_height, &None).unwrap();
64926497
let onion_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &our_payment_hash).unwrap();
64936498

64946499
let mut msg = msgs::UpdateAddHTLC {
@@ -8222,8 +8227,9 @@ fn test_onion_value_mpp_set_calculation() {
82228227
let height = nodes[0].best_block_info().1;
82238228
let session_priv = SecretKey::from_slice(&session_priv).unwrap();
82248229
let mut onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
8230+
let recipient_onion_fields = RecipientOnionFields::secret_only(our_payment_secret);
82258231
let (mut onion_payloads, _, _) = onion_utils::build_onion_payloads(&route.paths[0], 100_000,
8226-
RecipientOnionFields::secret_only(our_payment_secret), height + 1, &None).unwrap();
8232+
&recipient_onion_fields, height + 1, &None).unwrap();
82278233
// Edit amt_to_forward to simulate the sender having set
82288234
// the final amount and the routing node taking less fee
82298235
if let msgs::OutboundOnionPayload::Receive {

0 commit comments

Comments
 (0)