From fe834bc0c078158a0e5620d80a0de31b2bd25899 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 12 Aug 2020 16:03:35 +0200 Subject: [PATCH] rpcserver: don't allow closing restored channels To avoid the scenario where the user tries to force close a channel too early that was restored through SCB, we check the channel status in the RPC server already. If a restored channel cannot connect to its peer and mark it as local data loss the channel arbitrator would try to publish the commitment TX it does not have and crash. --- rpcserver.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/rpcserver.go b/rpcserver.go index 1cac4037..088f4a86 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -2072,6 +2072,19 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest, return err } + // We can't coop or force close restored channels or channels that have + // experienced local data loss. Normally we would detect this in the + // channel arbitrator if the channel has the status + // ChanStatusLocalDataLoss after connecting to its peer. But if no + // connection can be established, the channel arbitrator doesn't know it + // can't be force closed yet. + if channel.HasChanStatus(channeldb.ChanStatusRestored) || + channel.HasChanStatus(channeldb.ChanStatusLocalDataLoss) { + + return fmt.Errorf("cannot close channel with state: %v", + channel.ChanStatus()) + } + // Retrieve the best height of the chain, which we'll use to complete // either closing flow. _, bestHeight, err := r.server.cc.chainIO.GetBestBlock()