Skip to content

Commit 16a1380

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 5e6e32a commit 16a1380

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
@@ -1611,10 +1611,49 @@ where
16111611
} => {
16121612
log_info!(self.logger, "Channel {} closed due to: {}", channel_id, reason);
16131613

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

0 commit comments

Comments
 (0)