1
0
Fork 0
mirror of https://github.com/ACINQ/eclair.git synced 2025-02-21 14:04:10 +01:00

Ignore lnd's internal errors (#2659)

It seems like lnd sends this error whenever something wrong happens on
their side, regardless of whether the channel actually needs to be closed.
We ignore it to avoid paying the cost of a channel force-close, it's up
to them to broadcast their commitment if they wish.

See https://github.com/lightningnetwork/lnd/issues/7657 for example.
This commit is contained in:
Bastien Teinturier 2023-05-17 08:39:19 +02:00 committed by GitHub
parent fa985da59f
commit c73db8479c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 2 deletions

View file

@ -28,7 +28,7 @@ import fr.acinq.eclair.channel.fsm.Channel.UnhandledExceptionStrategy
import fr.acinq.eclair.channel.publish.TxPublisher.{PublishFinalTx, PublishReplaceableTx, PublishTx}
import fr.acinq.eclair.transactions.Transactions
import fr.acinq.eclair.transactions.Transactions.ClosingTx
import fr.acinq.eclair.wire.protocol.{AcceptChannel, ChannelReestablish, Error, OpenChannel}
import fr.acinq.eclair.wire.protocol.{AcceptChannel, ChannelReestablish, Error, OpenChannel, Warning}
import java.sql.SQLException
@ -134,7 +134,16 @@ trait ErrorHandlers extends CommonHandlers {
// if we were in the process of closing and already received a closing sig from the counterparty, it's always better to use that
handleMutualClose(bestUnpublishedClosingTx, Left(negotiating))
// NB: we publish the commitment even if we have nothing at stake (in a dataloss situation our peer will send us an error just for that)
case hasCommitments: ChannelDataWithCommitments => spendLocalCurrent(hasCommitments)
case hasCommitments: ChannelDataWithCommitments =>
if (e.toAscii == "internal error") {
// It seems like lnd sends this error whenever something wrong happens on their side, regardless of whether
// the channel actually needs to be closed. We ignore it to avoid paying the cost of a channel force-close,
// it's up to them to broadcast their commitment if they wish.
log.warning("ignoring remote 'internal error', probably coming from lnd")
stay() sending Warning(d.channelId, "ignoring your 'internal error' to avoid an unnecessary force-close")
} else {
spendLocalCurrent(hasCommitments)
}
// When there is no commitment yet, we just go to CLOSED state in case an error occurs.
case _: ChannelDataWithoutCommitments => goto(CLOSED)
case _: TransientChannelData => goto(CLOSED)

View file

@ -3342,6 +3342,14 @@ class NormalStateSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike with
alice2blockchain.expectNoMessage(1 second)
}
test("recv Error (ignored internal error from lnd)") { f =>
import f._
alice ! Error(channelId(alice), "internal error")
alice2bob.expectMsgType[Warning]
alice2blockchain.expectNoMessage(100 millis)
}
def testErrorAnchorOutputsWithHtlcs(f: FixtureParam): Unit = {
import f._