Skip to content

Commit f5e37c6

Browse files
committed
Test failing backward any pending HTLCs
Upon channel failure, any pending HTLCs in a channel's holding cell must be failed backward. The added test exercises this behavior and demonstrates a deadlock triggered within the handle_error!() macro. The deadlock occurs when the channel_state lock is already held and then reacquired when finish_force_close_channel() is called.
1 parent 8bd155e commit f5e37c6

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

lightning/src/ln/functional_tests.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2988,6 +2988,77 @@ fn test_commitment_revoked_fail_backward_exhaustive_b() {
29882988
do_test_commitment_revoked_fail_backward_exhaustive(true, false, true);
29892989
}
29902990

2991+
#[test]
2992+
fn fail_pending_htlc_backward_upon_channel_failure() {
2993+
let chanmon_cfgs = create_chanmon_cfgs(3);
2994+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
2995+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
2996+
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
2997+
let _chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1_000_000, 500_000_000, InitFeatures::supported(), InitFeatures::supported());
2998+
let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 1_000_000, 500_000_000, InitFeatures::supported(), InitFeatures::supported());
2999+
3000+
// Alice -> Bob -> Chuck: Route a payment but without Chuck sending revoke_and_ack.
3001+
{
3002+
let (_, payment_hash) = route_payment(&nodes[0], &[&nodes[1]], 50_000);
3003+
let remaining_route = nodes[1].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 50_000, TEST_FINAL_CLTV).unwrap();
3004+
nodes[1].node.send_payment(remaining_route, payment_hash).unwrap();
3005+
check_added_monitors!(nodes[1], 1);
3006+
3007+
let payment_event = {
3008+
let mut events = nodes[1].node.get_and_clear_pending_msg_events();
3009+
assert_eq!(events.len(), 1);
3010+
SendEvent::from_event(events.remove(0))
3011+
};
3012+
assert_eq!(payment_event.node_id, nodes[2].node.get_our_node_id());
3013+
assert_eq!(payment_event.msgs.len(), 1);
3014+
}
3015+
3016+
// Alice -> Bob -> Chuck: Route another payment but now Bob waits for Chuck's earlier revoke_and_ack.
3017+
let (_, failed_payment_hash) = route_payment(&nodes[0], &[&nodes[1]], 50_000);
3018+
{
3019+
let remaining_route = nodes[1].router.get_route(&nodes[2].node.get_our_node_id(), None, &Vec::new(), 50_000, TEST_FINAL_CLTV).unwrap();
3020+
nodes[1].node.send_payment(remaining_route, failed_payment_hash).unwrap();
3021+
check_added_monitors!(nodes[1], 0);
3022+
3023+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
3024+
}
3025+
3026+
// Alice <- Bob <- Chuck: Send a malformed update_add_htlc so Bob fails the channel.
3027+
{
3028+
let route = nodes[2].router.get_route(&nodes[0].node.get_our_node_id(), None, &Vec::new(), 50_000, TEST_FINAL_CLTV).unwrap();
3029+
let (_, payment_hash) = get_payment_preimage_hash!(nodes[2]);
3030+
3031+
let secp_ctx = Secp256k1::new();
3032+
let session_priv = {
3033+
let mut session_key = [0; 32];
3034+
let mut rng = thread_rng();
3035+
rng.fill_bytes(&mut session_key);
3036+
SecretKey::from_slice(&session_key).expect("RNG is bad!")
3037+
};
3038+
3039+
let current_height = nodes[2].node.latest_block_height.load(Ordering::Acquire) as u32 + 1;
3040+
let (onion_payloads, _amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(&route, current_height).unwrap();
3041+
let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route, &session_priv).unwrap();
3042+
let onion_routing_packet = onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash);
3043+
3044+
// Send a 0-msat update_add_htlc to fail the channel.
3045+
let update_add_htlc = msgs::UpdateAddHTLC {
3046+
channel_id: chan_2.2,
3047+
htlc_id: 0,
3048+
amount_msat: 0,
3049+
payment_hash,
3050+
cltv_expiry,
3051+
onion_routing_packet,
3052+
};
3053+
nodes[1].node.handle_update_add_htlc(&nodes[2].node.get_our_node_id(), &update_add_htlc);
3054+
}
3055+
3056+
// Check that Bob fails backward the pending HTLC from the second payment.
3057+
expect_payment_failed!(nodes[1], failed_payment_hash, true);
3058+
check_closed_broadcast!(nodes[1], true);
3059+
check_added_monitors!(nodes[1], 1);
3060+
}
3061+
29913062
#[test]
29923063
fn test_htlc_ignore_latest_remote_commitment() {
29933064
// Test that HTLC transactions spending the latest remote commitment transaction are simply

0 commit comments

Comments
 (0)