Skip to content

Commit fd21871

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 ddb5411 commit fd21871

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
@@ -2073,9 +2073,9 @@ where
20732073
payment_hash: PaymentHash, amt_msat: u64, cltv_expiry: u32, phantom_shared_secret: Option<[u8; 32]>) -> Result<PendingHTLCInfo, ReceiveError>
20742074
{
20752075
// final_incorrect_cltv_expiry
2076-
if hop_data.outgoing_cltv_value != cltv_expiry {
2076+
if hop_data.outgoing_cltv_value > cltv_expiry {
20772077
return Err(ReceiveError {
2078-
msg: "Upstream node set CLTV to the wrong value",
2078+
msg: "Upstream node set CLTV to less than the CLTV set by the sender",
20792079
err_code: 18,
20802080
err_data: cltv_expiry.to_be_bytes().to_vec()
20812081
})

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)