mirror of
https://github.com/lightningdevkit/rust-lightning.git
synced 2025-02-24 23:08:36 +01:00
Use temporary_node_failure
for a phantom HTLC with bogus CLTV
When we receive a phantom HTLC with a bogus/modified CLTV, we should fail back with `incorrect_cltv_expiry`, but that requires a `channel_update`, which we cannot generate for a phantom HTLC which has no corresponding channel. Thus, instead, we have to fall back to `incorrect_cltv_expiry`. Fixes #1879
This commit is contained in:
parent
8ec1480724
commit
6daf62fea3
2 changed files with 46 additions and 2 deletions
|
@ -2278,10 +2278,13 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
|
|||
}
|
||||
chan_update_opt
|
||||
} else {
|
||||
if (msg.cltv_expiry as u64) < (*outgoing_cltv_value) as u64 + MIN_CLTV_EXPIRY_DELTA as u64 { // incorrect_cltv_expiry
|
||||
if (msg.cltv_expiry as u64) < (*outgoing_cltv_value) as u64 + MIN_CLTV_EXPIRY_DELTA as u64 {
|
||||
// We really should set `incorrect_cltv_expiry` here but as we're not
|
||||
// forwarding over a real channel we can't generate a channel_update
|
||||
// for it. Instead we just return a generic temporary_node_failure.
|
||||
break Some((
|
||||
"Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta",
|
||||
0x1000 | 13, None,
|
||||
0x2000 | 2, None,
|
||||
));
|
||||
}
|
||||
None
|
||||
|
|
|
@ -1109,6 +1109,47 @@ fn test_phantom_failure_too_low_cltv() {
|
|||
expect_payment_failed_conditions(&nodes[0], payment_hash, true, fail_conditions);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_phantom_failure_modified_cltv() {
|
||||
// Test that we fail back phantoms if the upstream node fiddled with the CLTV too much with the
|
||||
// correct error code.
|
||||
let chanmon_cfgs = create_chanmon_cfgs(2);
|
||||
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
|
||||
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
|
||||
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
|
||||
|
||||
let channel = create_announced_chan_between_nodes(&nodes, 0, 1, channelmanager::provided_init_features(), channelmanager::provided_init_features());
|
||||
|
||||
// Get the route.
|
||||
let recv_value_msat = 10_000;
|
||||
let (_, payment_hash, payment_secret) = get_payment_preimage_hash!(nodes[1], Some(recv_value_msat));
|
||||
let (mut route, phantom_scid) = get_phantom_route!(nodes, recv_value_msat, channel);
|
||||
|
||||
// Route the HTLC through to the destination.
|
||||
nodes[0].node.send_payment(&route, payment_hash, &Some(payment_secret), PaymentId(payment_hash.0)).unwrap();
|
||||
check_added_monitors!(nodes[0], 1);
|
||||
let update_0 = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
|
||||
let mut update_add = update_0.update_add_htlcs[0].clone();
|
||||
|
||||
// Modify the route to have a too-low cltv.
|
||||
update_add.cltv_expiry -= 10;
|
||||
|
||||
nodes[1].node.handle_update_add_htlc(&nodes[0].node.get_our_node_id(), &update_add);
|
||||
commitment_signed_dance!(nodes[1], nodes[0], &update_0.commitment_signed, false, true);
|
||||
|
||||
let update_1 = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
|
||||
assert!(update_1.update_fail_htlcs.len() == 1);
|
||||
let fail_msg = update_1.update_fail_htlcs[0].clone();
|
||||
nodes[0].node.handle_update_fail_htlc(&nodes[1].node.get_our_node_id(), &fail_msg);
|
||||
commitment_signed_dance!(nodes[0], nodes[1], update_1.commitment_signed, false);
|
||||
|
||||
// Ensure the payment fails with the expected error.
|
||||
let mut fail_conditions = PaymentFailedConditions::new()
|
||||
.blamed_scid(phantom_scid)
|
||||
.expected_htlc_error_data(0x2000 | 2, &[]);
|
||||
expect_payment_failed_conditions(&nodes[0], payment_hash, false, fail_conditions);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_phantom_failure_too_low_recv_amt() {
|
||||
let chanmon_cfgs = create_chanmon_cfgs(2);
|
||||
|
|
Loading…
Add table
Reference in a new issue