Skip to content

Commit 3968647

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 86143fd commit 3968647

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

lightning/src/ln/functional_tests.rs

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

0 commit comments

Comments
 (0)