Skip to content

Commit

Permalink
Ignore lnd's internal errors
Browse files Browse the repository at this point in the history
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 lightningnetwork/lnd#7657 for example.
  • Loading branch information
t-bast committed May 16, 2023
1 parent fa985da commit 9089e49
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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._

Expand Down

0 comments on commit 9089e49

Please sign in to comment.