Skip to content

Commit b83fd74

Browse files
committed
Don't send init closing_signed too early after final HTLC removal
If we remove an HTLC (or fee update), commit, and receive our counterparty's `revoke_and_ack`, we remove all knowledge of said HTLC (or fee update). However, the latest local commitment transaction that we can broadcast still contains the HTLC (or old fee), thus we are not eligible for initiating the `closing_signed` negotiation if we're shutting down and are generally expecting a counterparty `commitment_signed` immediately. Because we don't have any tracking of these updates in the `Channel` (only the `ChannelMonitor` is aware of the HTLC being in our latest local commitment transaction), we'd previously send a `closing_signed` too early, causing LDK<->LDK channels with an HTLC pending towards the channel initiator at the time of `shutdown` to always fail to cooperatively close. To fix this race, we add an additional unpersisted bool to `Channel` and use that to gate sending the initial `closing_signed`.
1 parent afdcd1c commit b83fd74

File tree

2 files changed

+114
-1
lines changed

2 files changed

+114
-1
lines changed

lightning/src/ln/channel.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,19 @@ pub(super) struct ChannelContext<SP: Deref> where SP::Target: SignerProvider {
739739
#[cfg(not(test))]
740740
closing_fee_limits: Option<(u64, u64)>,
741741

742+
/// If we remove an HTLC (or fee update), commit, and receive our counterparty's
743+
/// `revoke_and_ack`, we remove all knowledge of said HTLC (or fee update). However, the latest
744+
/// local commitment transaction that we can broadcast still contains the HTLC (or old fee),
745+
/// thus we are not eligible for initiating the `closing_signed` negotiation if we're shutting
746+
/// down and are generally expecting a counterparty `commitment_signed` immediately.
747+
///
748+
/// To ensure we don't send a `closing_signed` too early, we track this state here, waiting
749+
/// until we see a `commitment_signed` before doing so.
750+
///
751+
/// We don't bother to persist this - we anticipate this state won't last longer than a few
752+
/// milliseconds, so any accidental force-closes here should be exceedingly rare.
753+
expecting_peer_cs: bool,
754+
742755
/// The hash of the block in which the funding transaction was included.
743756
funding_tx_confirmed_in: Option<BlockHash>,
744757
funding_tx_confirmation_height: u32,
@@ -3030,6 +3043,7 @@ impl<SP: Deref> Channel<SP> where
30303043
};
30313044

30323045
self.context.cur_holder_commitment_transaction_number -= 1;
3046+
self.context.expecting_peer_cs = false;
30333047
// Note that if we need_commitment & !AwaitingRemoteRevoke we'll call
30343048
// build_commitment_no_status_check() next which will reset this to RAAFirst.
30353049
self.context.resend_order = RAACommitmentOrder::CommitmentFirst;
@@ -3296,6 +3310,7 @@ impl<SP: Deref> Channel<SP> where
32963310
// Take references explicitly so that we can hold multiple references to self.context.
32973311
let pending_inbound_htlcs: &mut Vec<_> = &mut self.context.pending_inbound_htlcs;
32983312
let pending_outbound_htlcs: &mut Vec<_> = &mut self.context.pending_outbound_htlcs;
3313+
let expecting_peer_cs = &mut self.context.expecting_peer_cs;
32993314

33003315
// We really shouldnt have two passes here, but retain gives a non-mutable ref (Rust bug)
33013316
pending_inbound_htlcs.retain(|htlc| {
@@ -3304,6 +3319,7 @@ impl<SP: Deref> Channel<SP> where
33043319
if let &InboundHTLCRemovalReason::Fulfill(_) = reason {
33053320
value_to_self_msat_diff += htlc.amount_msat as i64;
33063321
}
3322+
*expecting_peer_cs = true;
33073323
false
33083324
} else { true }
33093325
});
@@ -3363,6 +3379,7 @@ impl<SP: Deref> Channel<SP> where
33633379
if let OutboundHTLCState::LocalAnnounced(_) = htlc.state {
33643380
log_trace!(logger, " ...promoting outbound LocalAnnounced {} to Committed", &htlc.payment_hash);
33653381
htlc.state = OutboundHTLCState::Committed;
3382+
*expecting_peer_cs = true;
33663383
}
33673384
if let &mut OutboundHTLCState::AwaitingRemoteRevokeToRemove(ref mut outcome) = &mut htlc.state {
33683385
log_trace!(logger, " ...promoting outbound AwaitingRemoteRevokeToRemove {} to AwaitingRemovedRemoteRevoke", &htlc.payment_hash);
@@ -3383,6 +3400,7 @@ impl<SP: Deref> Channel<SP> where
33833400
log_trace!(logger, " ...promoting outbound fee update {} to Committed", feerate);
33843401
self.context.feerate_per_kw = feerate;
33853402
self.context.pending_update_fee = None;
3403+
self.context.expecting_peer_cs = true;
33863404
},
33873405
FeeUpdateState::RemoteAnnounced => { debug_assert!(!self.context.is_outbound()); },
33883406
FeeUpdateState::AwaitingRemoteRevokeToAnnounce => {
@@ -4123,6 +4141,19 @@ impl<SP: Deref> Channel<SP> where
41234141
return Ok((None, None));
41244142
}
41254143

4144+
// If we're waiting on a monitor persistence, that implies we're also waiting to send some
4145+
// message to our counterparty (probably a `revoke_and_ack`). In such a case, we shouldn't
4146+
// initiate `closing_signed` negotiation until we're clear of all pending messages.
4147+
if (self.context.channel_state & (ChannelState::MonitorUpdateInProgress as u32)) != 0 {
4148+
return Ok((None, None));
4149+
}
4150+
4151+
// If we're waiting on a counterparty `commitment_signed` to clear some updates from our
4152+
// local commitment transaction, we can't yet initiate `closing_signed` negotiation.
4153+
if self.context.expecting_peer_cs {
4154+
return Ok((None, None));
4155+
}
4156+
41264157
let (our_min_fee, our_max_fee) = self.calculate_closing_fee_limits(fee_estimator);
41274158

41284159
assert!(self.context.shutdown_scriptpubkey.is_some());
@@ -5694,6 +5725,7 @@ impl<SP: Deref> OutboundV1Channel<SP> where SP::Target: SignerProvider {
56945725

56955726
last_sent_closing_fee: None,
56965727
pending_counterparty_closing_signed: None,
5728+
expecting_peer_cs: false,
56975729
closing_fee_limits: None,
56985730
target_closing_feerate_sats_per_kw: None,
56995731

@@ -6332,6 +6364,7 @@ impl<SP: Deref> InboundV1Channel<SP> where SP::Target: SignerProvider {
63326364

63336365
last_sent_closing_fee: None,
63346366
pending_counterparty_closing_signed: None,
6367+
expecting_peer_cs: false,
63356368
closing_fee_limits: None,
63366369
target_closing_feerate_sats_per_kw: None,
63376370

@@ -7425,6 +7458,7 @@ impl<'a, 'b, 'c, ES: Deref, SP: Deref> ReadableArgs<(&'a ES, &'b SP, u32, &'c Ch
74257458

74267459
last_sent_closing_fee: None,
74277460
pending_counterparty_closing_signed: None,
7461+
expecting_peer_cs: false,
74287462
closing_fee_limits: None,
74297463
target_closing_feerate_sats_per_kw,
74307464

lightning/src/ln/shutdown_tests.rs

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
//! Tests of our shutdown and closing_signed negotiation logic.
1111
1212
use crate::sign::{EntropySource, SignerProvider};
13+
use crate::chain::ChannelMonitorUpdateStatus;
1314
use crate::chain::transaction::OutPoint;
14-
use crate::events::{Event, MessageSendEvent, MessageSendEventsProvider, ClosureReason};
15+
use crate::events::{Event, HTLCDestination, MessageSendEvent, MessageSendEventsProvider, ClosureReason};
1516
use crate::ln::channelmanager::{self, PaymentSendFailure, PaymentId, RecipientOnionFields, ChannelShutdownState, ChannelDetails};
1617
use crate::routing::router::{PaymentParameters, get_route};
1718
use crate::ln::msgs;
@@ -1209,3 +1210,81 @@ fn simple_target_feerate_shutdown() {
12091210
check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
12101211
check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
12111212
}
1213+
1214+
1215+
#[test]
1216+
fn htlc_removal_no_early_closing_signed() {
1217+
// Previously, if we have a pending inbound HTLC on a channel which has initiated shutdown,
1218+
// we'd send our initial closing_signed immediately after receiving the peer's last RAA to
1219+
// remove the HTLC, but before receiving their final commitment_signed for a commitment without
1220+
// the HTLC. This caused at least LDK peers to force-close as we initiated closing_signed prior
1221+
// to the channel actually being fully empty of HTLCs.
1222+
let chanmon_cfgs = create_chanmon_cfgs(2);
1223+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
1224+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
1225+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
1226+
1227+
let chan_id = create_announced_chan_between_nodes(&nodes, 0, 1).2;
1228+
1229+
send_payment(&nodes[0], &[&nodes[1]], 1_000_000);
1230+
let payment_hash = route_payment(&nodes[1], &[&nodes[0]], 10_000).1;
1231+
1232+
nodes[1].node.close_channel(&chan_id, &nodes[0].node.get_our_node_id()).unwrap();
1233+
let node_0_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id());
1234+
nodes[0].node.close_channel(&chan_id, &nodes[1].node.get_our_node_id()).unwrap();
1235+
let node_1_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id());
1236+
1237+
nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &node_0_shutdown);
1238+
nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &node_1_shutdown);
1239+
1240+
nodes[0].node.fail_htlc_backwards(&payment_hash);
1241+
expect_pending_htlcs_forwardable_and_htlc_handling_failed!(nodes[0], [HTLCDestination::FailedPayment { payment_hash }]);
1242+
let updates = get_htlc_update_msgs(&nodes[0], &nodes[1].node.get_our_node_id());
1243+
check_added_monitors(&nodes[0], 1);
1244+
1245+
nodes[1].node.handle_update_fail_htlc(&nodes[0].node.get_our_node_id(), &updates.update_fail_htlcs[0]);
1246+
nodes[1].node.handle_commitment_signed(&nodes[0].node.get_our_node_id(), &updates.commitment_signed);
1247+
check_added_monitors(&nodes[1], 1);
1248+
let (bs_raa, bs_cs) = get_revoke_commit_msgs(&nodes[1], &nodes[0].node.get_our_node_id());
1249+
1250+
nodes[0].node.handle_revoke_and_ack(&nodes[1].node.get_our_node_id(), &bs_raa);
1251+
check_added_monitors(&nodes[0], 1);
1252+
1253+
// At this point the Channel on nodes[0] has no record of any HTLCs but the latest
1254+
// broadcastable commitment does contain the HTLC (but only the ChannelMonitor knows this).
1255+
// Thus, the channel should not yet initiate closing_signed negotiation (but previously did).
1256+
assert_eq!(nodes[0].node.get_and_clear_pending_msg_events(), Vec::new());
1257+
1258+
chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
1259+
nodes[0].node.handle_commitment_signed(&nodes[1].node.get_our_node_id(), &bs_cs);
1260+
check_added_monitors(&nodes[0], 1);
1261+
assert_eq!(nodes[0].node.get_and_clear_pending_msg_events(), Vec::new());
1262+
1263+
expect_channel_shutdown_state!(nodes[0], chan_id, ChannelShutdownState::ResolvingHTLCs);
1264+
assert_eq!(nodes[0].node.get_and_clear_pending_msg_events(), Vec::new());
1265+
let (outpoint, latest_update, _) = nodes[0].chain_monitor.latest_monitor_update_id.lock().unwrap().get(&chan_id).unwrap().clone();
1266+
nodes[0].chain_monitor.chain_monitor.force_channel_monitor_updated(outpoint, latest_update);
1267+
1268+
let as_raa_closing_signed = nodes[0].node.get_and_clear_pending_msg_events();
1269+
assert_eq!(as_raa_closing_signed.len(), 2);
1270+
1271+
if let MessageSendEvent::SendRevokeAndACK { msg, .. } = &as_raa_closing_signed[0] {
1272+
nodes[1].node.handle_revoke_and_ack(&nodes[0].node.get_our_node_id(), &msg);
1273+
check_added_monitors(&nodes[1], 1);
1274+
expect_payment_failed!(nodes[1], payment_hash, true);
1275+
} else { panic!("Unexpected message {:?}", as_raa_closing_signed[0]); }
1276+
1277+
if let MessageSendEvent::SendClosingSigned { msg, .. } = &as_raa_closing_signed[1] {
1278+
nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &msg);
1279+
} else { panic!("Unexpected message {:?}", as_raa_closing_signed[1]); }
1280+
1281+
let bs_closing_signed = get_event_msg!(nodes[1], MessageSendEvent::SendClosingSigned, nodes[0].node.get_our_node_id());
1282+
nodes[0].node.handle_closing_signed(&nodes[1].node.get_our_node_id(), &bs_closing_signed);
1283+
let (_, as_2nd_closing_signed) = get_closing_signed_broadcast!(nodes[0].node, nodes[1].node.get_our_node_id());
1284+
nodes[1].node.handle_closing_signed(&nodes[0].node.get_our_node_id(), &as_2nd_closing_signed.unwrap());
1285+
let (_, node_1_none) = get_closing_signed_broadcast!(nodes[1].node, nodes[0].node.get_our_node_id());
1286+
assert!(node_1_none.is_none());
1287+
1288+
check_closed_event!(nodes[0], 1, ClosureReason::CooperativeClosure, [nodes[1].node.get_our_node_id()], 100000);
1289+
check_closed_event!(nodes[1], 1, ClosureReason::CooperativeClosure, [nodes[0].node.get_our_node_id()], 100000);
1290+
}

0 commit comments

Comments
 (0)