channel_notifier: keep chan in SCB on local foce close

In case we force close a channel from our end the funds can be time
locked for up to 2 weeks worst case. If something happens to our node in
that time, we don't have any information on that channel anymore because
currently the channel is removed from the channel backup file the moment
the commitment transaction confirms.
Instead we want to keep the channel around in the SCB file until we've
actually swept the time locked funds.

It looks like lnd even supports recovering from such a case if the peer
is still online and can tell us what commit height to use for deriving
the commit point. If the peer isn't around anymore then external tools
could be used to brute force the commit height.
This commit is contained in:
Oliver Gugger 2021-08-09 13:55:33 +02:00
parent 7e68cae8bd
commit 5917486dc9
No known key found for this signature in database
GPG Key ID: 8E4256593F177720

View File

@ -122,12 +122,52 @@ func (c *channelNotifier) SubscribeChans(startingChans map[wire.OutPoint]struct{
// channel to the sub-swapper.
case channelnotifier.ClosedChannelEvent:
chanPoint := event.CloseSummary.ChanPoint
closeType := event.CloseSummary.CloseType
// Because we see the contract as closed
// once our local force close TX
// confirms, the channel arbitrator
// already fires on this event. But
// because our funds can be in limbo for
// up to 2 weeks worst case we don't
// want to remove the crucial info we
// need for sweeping that time locked
// output before we've actually done so.
if closeType == channeldb.LocalForceClose {
ltndLog.Debugf("Channel %v "+
"was force closed by "+
"us, not removing "+
"from channel backup "+
"until fully resolved",
chanPoint)
continue
}
chanEvent := chanbackup.ChannelEvent{
ClosedChans: []wire.OutPoint{
chanPoint,
},
}
select {
case chanUpdates <- chanEvent:
case <-quit:
return
}
// A channel was fully resolved on chain. This
// should only really interest us if it was a
// locally force closed channel where we didn't
// remove the channel already when the close
// event was fired.
case channelnotifier.FullyResolvedChannelEvent:
chanEvent := chanbackup.ChannelEvent{
ClosedChans: []wire.OutPoint{
*event.ChannelPoint,
},
}
select {
case chanUpdates <- chanEvent:
case <-quit: