5

I run lnd on my node and sometimes see messages like this:

[INF] CNCT: ChannelArbitrator(CHANPOINT): immediately failing htlc=HTLCID from remote commitment

The corresponding close transaction sent out by my node does not contain any HTLC output. I'd like to understand more about this situation, and what I can do to avoid this.

  • How does the HTLC end up in my peer's commit transaction?
  • Why does my node know about it, but doesn't have the HTLC in the local commitment transaction?
  • Why isn't it necessary to recover the HTLC funds as part of the close transaction?
  • What went wrong, i.e. how can I help avoid this kind of channel closes?

This is the corresponding code in lnd: https://github.com/lightningnetwork/lnd/blob/cd8a87c0daf569404f6bcf8e839524f0e639d881/contractcourt/channel_arbitrator.go#L1806

Related to Under what conditions would lightning channels be force closed automatically?

1
  • 1
    I don't know the reason. But I think the 'htlc from remote commitment' means the remote party initiated the htlc, so it's an inbound htlc basically. It's not necessarily in the remote commitment transaction. Also, in this piece of code you're referring to, that specific htlc is not necessarily the cause you're going on-chain. My guess is this HTLC is in a state after the update_add_htlc message and before revoke_and_ack. In that situation you don't have a HTLC in your local commitment transaction. Apr 17, 2022 at 10:35

1 Answer 1

2

Thanks a lot to Rene Pickhardt, who spent some time with me digging into this.

When my node A sends out an HTLC to my peer B, this is done using the update_add_htlc message defined in Bolt 02. Following this message, my node signs the remote's new commitment transaction (which contains the HTLC) and sends it to B as part of the commitment_signed message.

As soon as node B has access to this signed transaction, it could (in theory) broadcast the transaction including the HTLC output and, using the secret hash, spend the HTLC output.

Note that B may do this at any time, possibly long after the HTLC timeout.

If the outgoing HTLC corresponds to an incoming HTLC (i.e., my node forwarded funds from some other node X towards B), my node needs to fail the outgoing HTLC with absolute certainty before the incoming HTLC times out. If the incoming HTLC times out first, the incoming HTLC fails (and my node doesn't get the incoming funds from X), but the outgoing HTLC may still succeed if node B decides to broadcast the signed transaction (and, thus, my node would give away funds for free, as it won't get the amount back from node X).

In order to avoid this kind of situation, lnd force-closes the channel as described in the question so that the outgoing HTLC fails with absolute certainty, i.e. depriving node B of the chance to claim the HTLC output in the future.

Usually node B acknowledges the signed transaction and sends a signed transaction in return. In the situation described above, however, node B does not respond. The logs show failing link: unable to complete dance with error: remote unresponsive, indicating that node B didn't continue answering as expected.

It might help to check node B's health before sending update_add_htlc and commitment_signed, which apparently isn't something lnd currently does (see https://github.com/lightningnetwork/lnd/issues/6482).

As you can see in the lnd source code, this whole process is very similar to the case where node B also sends a new signed transaction (which contains the HTLC), and then lets the HTLC time out.

1
  • 2
    It was a fun debugging session / discussion. Happy to do it again (: Apr 20, 2022 at 19:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.