Skip to content

During mutual close negotiation, Eclair might not send last closing_signed msg #1742

@SomberNight

Description

@SomberNight

During mutual close negotiation, Eclair sometimes does not send the last closing_signed msg.
Specifically I am talking about this part of BOLT-02:

https://github.com/lightningnetwork/lightning-rfc/blob/b201efe0546120c14bf154ce5f4e18da7243fe7a/02-peer-protocol.md#requirements-6

Closing Negotiation: closing_signed
Requirements
The receiving node:

  • if the receiver agrees with the fee:
    • SHOULD reply with a closing_signed with the same fee_satoshis value.

Consider a channel between Alice and Bob, with Bob running Eclair.
If Alice sends a closing_signed with a fee_satoshis Bob agrees with,
I've found that

  • sometimes Bob replies with a closing_signed with the same fee_satoshis value,
  • other times Bob does not reply and just broadcasts the on-chain tx.

I am looking at this part of the code:

if (lastLocalClosingFee.contains(nextClosingFee)) {
// next computed fee is the same than the one we previously sent (probably because of rounding), let's close now
handleMutualClose(signedClosingTx, Left(d.copy(bestUnpublishedClosingTx_opt = Some(signedClosingTx))))
} else if (nextClosingFee == remoteClosingFee) {
// we have converged!

def nextClosingFee(localClosingFee: Satoshi, remoteClosingFee: Satoshi): Satoshi = ((localClosingFee + remoteClosingFee) / 4) * 2


Consider scenario1:

  • Alice sends closing_signed with fee_satoshis = 504,
  • Bob sends closing_signed with fee_satoshis = 500,
  • Alice sends closing_signed with fee_satoshis = 503,
  • Now I think Bob will calculate nextClosingFee to be (500 + 503) // 4 * 2 == 500,
    which matches what he sent last, and will not reply, just broadcast the tx (with fee_satoshis = 503).

Ideally, Bob should send a final closing_signed with fee_satoshis = 503,
as this is what BOLT-02 says he should do.


Consider scenario2:

  • Alice sends closing_signed with fee_satoshis = 508,
  • Bob sends closing_signed with fee_satoshis = 500,
  • Alice sends closing_signed with fee_satoshis = 502,
  • Now I think Bob will calculate nextClosingFee to be (500 + 504) // 4 * 2 == 502,
    so Bob enters the "we have converged!" branch,
    replies with a closing_signed with fee_satoshis = 502,
    and broadcast the tx (with fee_satoshis = 502)

(so scenario2 works out as expected)


So my issue is that - like the comment in the code suggests - due to rounding errors, to an outside observer Eclair behaves probabilistically: sometimes it sends the last closing_signed messages, sometimes it does not.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions