Skip to content

Commit bf34a8b

Browse files
committed
event: drop peer on counterparty or on-chain close
When the counterparty drives closure or a commitment transaction confirms on chain, no further channel state can be recovered with the peer. Retaining them in the peer store would only spin the reconnection task forever. Remove the peer once their last channel with us reaches one of these terminal states: - `CounterpartyForceClosed` - `CounterpartyInitiatedCooperativeClosure` - `CommitmentTxConfirmed` `CommitmentTxConfirmed` covers the case where a remote commitment confirms while we are disconnected; LDK may also report our own commitment confirming under the same variant, but the channel is gone on chain in either case. `HolderForceClosed` is intentionally excluded so the reconnection loop can keep driving `channel_reestablish` recovery (handled in `Node::close_channel_internal`). `counterparty_node_id` is unwrapped with `expect` since LDK has always populated it on `ChannelClosed` from 0.0.117 onward, well before the minimum version this crate targets. If peer removal fails we now return `ReplayEvent` so the event is retried instead of being silently dropped.
1 parent 1b82103 commit bf34a8b

1 file changed

Lines changed: 40 additions & 1 deletion

File tree

src/event.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1613,10 +1613,49 @@ where
16131613
} => {
16141614
log_info!(self.logger, "Channel {} closed due to: {}", channel_id, reason);
16151615

1616+
// `counterparty_node_id` has been set on every `ChannelClosed` since LDK 0.0.117.
1617+
let counterparty_node_id = counterparty_node_id
1618+
.expect("counterparty_node_id is always set since LDK 0.0.117");
1619+
1620+
// Drop the peer once their last channel with us has reached a terminal
1621+
// state reconnection cannot recover. `CommitmentTxConfirmed` is included
1622+
// because LDK reports a remote (or our own) commitment confirming on-chain
1623+
// via this variant, leaving nothing for `channel_reestablish` to recover.
1624+
// `HolderForceClosed` is deliberately excluded so reconnection can still
1625+
// drive recovery (see `Node::close_channel_internal`).
1626+
// We exclude `channel_id` from the count because LDK emits `ChannelClosed`
1627+
// before removing it from its internal list.
1628+
let reconnect_unneeded = matches!(
1629+
reason,
1630+
ClosureReason::CounterpartyForceClosed { .. }
1631+
| ClosureReason::CounterpartyInitiatedCooperativeClosure
1632+
| ClosureReason::CommitmentTxConfirmed
1633+
);
1634+
1635+
if reconnect_unneeded {
1636+
let has_other_channels = self
1637+
.channel_manager
1638+
.list_channels_with_counterparty(&counterparty_node_id)
1639+
.iter()
1640+
.any(|c| c.channel_id != channel_id);
1641+
1642+
if !has_other_channels {
1643+
if let Err(e) = self.peer_store.remove_peer(&counterparty_node_id).await {
1644+
log_error!(
1645+
self.logger,
1646+
"Failed to remove peer {} from peer store: {}",
1647+
counterparty_node_id,
1648+
e
1649+
);
1650+
return Err(ReplayEvent());
1651+
}
1652+
}
1653+
}
1654+
16161655
let event = Event::ChannelClosed {
16171656
channel_id,
16181657
user_channel_id: UserChannelId(user_channel_id),
1619-
counterparty_node_id,
1658+
counterparty_node_id: Some(counterparty_node_id),
16201659
reason: Some(reason),
16211660
};
16221661

0 commit comments

Comments
 (0)