Skip to content

Commit 44156ba

Browse files
committed
f - Correctly identify short_channel_id of failing route hop
1 parent fea8b04 commit 44156ba

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

lightning/src/ln/onion_route_tests.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,14 @@ fn run_onion_failure_test_with_fail_intercept<F1,F2,F3>(_name: &str, test_case:
211211
}
212212

213213
impl msgs::ChannelUpdate {
214-
fn dummy() -> msgs::ChannelUpdate {
214+
fn dummy(short_channel_id: u64) -> msgs::ChannelUpdate {
215215
use bitcoin::secp256k1::ffi::Signature as FFISignature;
216216
use bitcoin::secp256k1::Signature;
217217
msgs::ChannelUpdate {
218218
signature: Signature::from(unsafe { FFISignature::new() }),
219219
contents: msgs::UnsignedChannelUpdate {
220220
chain_hash: BlockHash::hash(&vec![0u8][..]),
221-
short_channel_id: 0,
221+
short_channel_id,
222222
timestamp: 0,
223223
flags: 0,
224224
cltv_expiry_delta: 0,
@@ -435,13 +435,14 @@ fn test_onion_failure() {
435435
run_onion_failure_test("invalid_onion_key", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| { msg.onion_routing_packet.public_key = Err(secp256k1::Error::InvalidPublicKey);}, ||{}, true,
436436
Some(BADONION|PERM|6), None, None);
437437

438+
let short_channel_id = channels[1].0.contents.short_channel_id;
438439
run_onion_failure_test_with_fail_intercept("temporary_channel_failure", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
439440
msg.amount_msat -= 1;
440441
}, |msg| {
441442
let session_priv = SecretKey::from_slice(&[3; 32]).unwrap();
442443
let onion_keys = onion_utils::construct_onion_keys(&Secp256k1::new(), &route.paths[0], &session_priv).unwrap();
443-
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], UPDATE|7, &ChannelUpdate::dummy().encode_with_len()[..]);
444-
}, ||{}, true, Some(UPDATE|7), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}), Some(channels[0].0.contents.short_channel_id));
444+
msg.reason = onion_utils::build_first_hop_failure_packet(&onion_keys[0].shared_secret[..], UPDATE|7, &ChannelUpdate::dummy(short_channel_id).encode_with_len()[..]);
445+
}, ||{}, true, Some(UPDATE|7), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy(short_channel_id)}), Some(short_channel_id));
445446

446447
let short_channel_id = channels[1].0.contents.short_channel_id;
447448
run_onion_failure_test_with_fail_intercept("permanent_channel_failure", 100, &nodes, &route, &payment_hash, &payment_secret, |msg| {
@@ -469,11 +470,12 @@ fn test_onion_failure() {
469470
run_onion_failure_test("unknown_next_peer", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(PERM|10),
470471
Some(NetworkUpdate::ChannelClosed{short_channel_id, is_permanent:true}), Some(short_channel_id));
471472

473+
let short_channel_id = channels[1].0.contents.short_channel_id;
472474
let amt_to_forward = nodes[1].node.channel_state.lock().unwrap().by_id.get(&channels[1].2).unwrap().get_counterparty_htlc_minimum_msat() - 1;
473475
let mut bogus_route = route.clone();
474476
let route_len = bogus_route.paths[0].len();
475477
bogus_route.paths[0][route_len-1].fee_msat = amt_to_forward;
476-
run_onion_failure_test("amount_below_minimum", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(UPDATE|11), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}), Some(channels[0].0.contents.short_channel_id));
478+
run_onion_failure_test("amount_below_minimum", 0, &nodes, &bogus_route, &payment_hash, &payment_secret, |_| {}, ||{}, true, Some(UPDATE|11), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy(short_channel_id)}), Some(short_channel_id));
477479

478480
// Test a positive test-case with one extra msat, meeting the minimum.
479481
bogus_route.paths[0][route_len-1].fee_msat = amt_to_forward + 1;
@@ -493,12 +495,13 @@ fn test_onion_failure() {
493495
msg.cltv_expiry -= 1;
494496
}, || {}, true, Some(UPDATE|13), Some(NetworkUpdate::ChannelClosed { short_channel_id, is_permanent: true}), Some(short_channel_id));
495497

498+
let short_channel_id = channels[1].0.contents.short_channel_id;
496499
run_onion_failure_test("expiry_too_soon", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| {
497500
let height = msg.cltv_expiry - CLTV_CLAIM_BUFFER - LATENCY_GRACE_PERIOD_BLOCKS + 1;
498501
connect_blocks(&nodes[0], height - nodes[0].best_block_info().1);
499502
connect_blocks(&nodes[1], height - nodes[1].best_block_info().1);
500503
connect_blocks(&nodes[2], height - nodes[2].best_block_info().1);
501-
}, ||{}, true, Some(UPDATE|14), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}), Some(channels[0].0.contents.short_channel_id));
504+
}, ||{}, true, Some(UPDATE|14), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy(short_channel_id)}), Some(short_channel_id));
502505

503506
run_onion_failure_test("unknown_payment_hash", 2, &nodes, &route, &payment_hash, &payment_secret, |_| {}, || {
504507
nodes[2].node.fail_htlc_backwards(&payment_hash);
@@ -537,11 +540,12 @@ fn test_onion_failure() {
537540
}
538541
}, true, Some(19), None, Some(channels[1].0.contents.short_channel_id));
539542

543+
let short_channel_id = channels[1].0.contents.short_channel_id;
540544
run_onion_failure_test("channel_disabled", 0, &nodes, &route, &payment_hash, &payment_secret, |_| {}, || {
541545
// disconnect event to the channel between nodes[1] ~ nodes[2]
542546
nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), false);
543547
nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false);
544-
}, true, Some(UPDATE|20), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy()}), Some(channels[0].0.contents.short_channel_id));
548+
}, true, Some(UPDATE|20), Some(NetworkUpdate::ChannelUpdateMessage{msg: ChannelUpdate::dummy(short_channel_id)}), Some(short_channel_id));
545549
reconnect_nodes(&nodes[1], &nodes[2], (false, false), (0, 0), (0, 0), (0, 0), (0, 0), (0, 0), (false, false));
546550

547551
run_onion_failure_test("expiry_too_far", 0, &nodes, &route, &payment_hash, &payment_secret, |msg| {

lightning/src/ln/onion_utils.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
356356
packet_decrypted = decryption_tmp;
357357

358358
is_from_final_node = route_hop_idx + 1 == path.len();
359+
let failing_route_hop = if is_from_final_node { route_hop } else { &path[route_hop_idx + 1] };
359360

360361
if let Ok(err_packet) = msgs::DecodedOnionErrorPacket::read(&mut Cursor::new(&packet_decrypted)) {
361362
let um = gen_um_from_shared_secret(&shared_secret[..]);
@@ -389,7 +390,6 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
389390
}
390391
else if error_code & PERM == PERM {
391392
if !payment_failed {
392-
let failing_route_hop = if is_from_final_node { route_hop } else { &path[route_hop_idx + 1] };
393393
network_update = Some(NetworkUpdate::ChannelClosed {
394394
short_channel_id: failing_route_hop.short_channel_id,
395395
is_permanent: true,
@@ -416,15 +416,18 @@ pub(super) fn process_onion_failure<T: secp256k1::Signing, L: Deref>(secp_ctx: &
416416
20 => chan_update.contents.flags & 2 == 0,
417417
_ => false, // unknown error code; take channel_update as valid
418418
};
419-
network_update = if is_chan_update_invalid {
419+
if is_chan_update_invalid {
420420
// This probably indicates the node which forwarded
421421
// to the node in question corrupted something.
422-
Some(NetworkUpdate::ChannelClosed {
422+
network_update = Some(NetworkUpdate::ChannelClosed {
423423
short_channel_id: route_hop.short_channel_id,
424424
is_permanent: true,
425-
})
425+
});
426426
} else {
427-
Some(NetworkUpdate::ChannelUpdateMessage {
427+
if failing_route_hop.short_channel_id == chan_update.contents.short_channel_id {
428+
short_channel_id = Some(failing_route_hop.short_channel_id);
429+
}
430+
network_update = Some(NetworkUpdate::ChannelUpdateMessage {
428431
msg: chan_update,
429432
})
430433
};

0 commit comments

Comments
 (0)