Skip to content

Commit ee57738

Browse files
committed
Allow overshooting final cltv_expiry
Final nodes previously had stricter requirements on HTLC contents matching onion value compared to intermediate nodes. This allowed for probing, i.e. the last intermediate node could overshoot the value by a small amount and conclude from the acceptance or rejection of the HTLC whether the next node was the destination. This also applies to the msat amount, however this change was already present.
1 parent f3d8e58 commit ee57738

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,9 +2095,9 @@ where
20952095
payment_hash: PaymentHash, amt_msat: u64, cltv_expiry: u32, phantom_shared_secret: Option<[u8; 32]>) -> Result<PendingHTLCInfo, ReceiveError>
20962096
{
20972097
// final_incorrect_cltv_expiry
2098-
if hop_data.outgoing_cltv_value != cltv_expiry {
2098+
if hop_data.outgoing_cltv_value > cltv_expiry {
20992099
return Err(ReceiveError {
2100-
msg: "Upstream node set CLTV to the wrong value",
2100+
msg: "Upstream node set CLTV to less than the CLTV set by the sender",
21012101
err_code: 18,
21022102
err_data: cltv_expiry.to_be_bytes().to_vec()
21032103
})

lightning/src/ln/onion_route_tests.rs

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ fn test_onion_failure() {
552552
for f in pending_forwards.iter_mut() {
553553
match f {
554554
&mut HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo { ref mut forward_info, .. }) =>
555-
forward_info.outgoing_cltv_value += 1,
555+
forward_info.outgoing_cltv_value -= 1,
556556
_ => {},
557557
}
558558
}
@@ -602,6 +602,48 @@ fn test_onion_failure() {
602602
}, true, Some(23), None, None);
603603
}
604604

605+
#[test]
606+
fn test_overshoot_final_cltv() {
607+
let chanmon_cfgs = create_chanmon_cfgs(3);
608+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
609+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None; 3]);
610+
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
611+
create_announced_chan_between_nodes(&nodes, 0, 1);
612+
create_announced_chan_between_nodes(&nodes, 1, 2);
613+
let (route, payment_hash, payment_preimage, payment_secret) = get_route_and_payment_hash!(nodes[0], nodes[2], 40000);
614+
615+
let payment_id = PaymentId(nodes[0].keys_manager.backing.get_secure_random_bytes());
616+
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), payment_id).unwrap();
617+
618+
check_added_monitors!(nodes[0], 1);
619+
let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
620+
let mut update_add_0 = update_0.update_add_htlcs[0].clone();
621+
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add_0);
622+
commitment_signed_dance!(nodes[1], nodes[0], &update_0.commitment_signed, false, true);
623+
624+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
625+
for (_, pending_forwards) in nodes[1].node.forward_htlcs.lock().unwrap().iter_mut() {
626+
for f in pending_forwards.iter_mut() {
627+
match f {
628+
&mut HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo { ref mut forward_info, .. }) =>
629+
forward_info.outgoing_cltv_value += 1,
630+
_ => {},
631+
}
632+
}
633+
}
634+
expect_pending_htlcs_forwardable!(nodes[1]);
635+
636+
check_added_monitors!(&nodes[1], 1);
637+
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[2].node.get_our_node_id());
638+
let mut update_add_1 = update_1.update_add_htlcs[0].clone();
639+
nodes[2].node.handle_update_add_htlc(&nodes[1].node.get_our_node_id(), &update_add_1);
640+
commitment_signed_dance!(nodes[2], nodes[1], update_1.commitment_signed, false, true);
641+
642+
expect_pending_htlcs_forwardable!(nodes[2]);
643+
expect_payment_claimable!(nodes[2], payment_hash, payment_secret, 40_000);
644+
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
645+
}
646+
605647
fn do_test_onion_failure_stale_channel_update(announced_channel: bool) {
606648
// Create a network of three nodes and two channels connecting them. We'll be updating the
607649
// HTLC relay policy of the second channel, causing forwarding failures at the first hop.
@@ -1096,7 +1138,7 @@ fn test_phantom_final_incorrect_cltv_expiry() {
10961138
&mut HTLCForwardInfo::AddHTLC(PendingAddHTLCInfo {
10971139
forward_info: PendingHTLCInfo { ref mut outgoing_cltv_value, .. }, ..
10981140
}) => {
1099-
*outgoing_cltv_value += 1;
1141+
*outgoing_cltv_value -= 1;
11001142
},
11011143
_ => panic!("Unexpected forward"),
11021144
}
@@ -1114,7 +1156,7 @@ fn test_phantom_final_incorrect_cltv_expiry() {
11141156
commitment_signed_dance!(nodes[0], nodes[1], update_1.commitment_signed, false);
11151157

11161158
// Ensure the payment fails with the expected error.
1117-
let expected_cltv: u32 = 82;
1159+
let expected_cltv: u32 = 80;
11181160
let error_data = expected_cltv.to_be_bytes().to_vec();
11191161
let mut fail_conditions = PaymentFailedConditions::new()
11201162
.blamed_scid(phantom_scid)

0 commit comments

Comments
 (0)