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.
During mutual close negotiation, Eclair sometimes does not send the last
closing_signedmsg.Specifically I am talking about this part of BOLT-02:
https://github.com/lightningnetwork/lightning-rfc/blob/b201efe0546120c14bf154ce5f4e18da7243fe7a/02-peer-protocol.md#requirements-6
Consider a channel between Alice and Bob, with Bob running Eclair.
If Alice sends a
closing_signedwith afee_satoshisBob agrees with,I've found that
closing_signedwith the samefee_satoshisvalue,I am looking at this part of the code:
eclair/eclair-core/src/main/scala/fr/acinq/eclair/channel/Channel.scala
Lines 1223 to 1227 in c37eb1a
eclair/eclair-core/src/main/scala/fr/acinq/eclair/channel/Helpers.scala
Line 443 in c37eb1a
Consider scenario1:
closing_signedwithfee_satoshis = 504,closing_signedwithfee_satoshis = 500,closing_signedwithfee_satoshis = 503,nextClosingFeeto 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_signedwithfee_satoshis = 503,as this is what BOLT-02 says he should do.
Consider scenario2:
closing_signedwithfee_satoshis = 508,closing_signedwithfee_satoshis = 500,closing_signedwithfee_satoshis = 502,nextClosingFeeto be(500 + 504) // 4 * 2 == 502,so Bob enters the "we have converged!" branch,
replies with a
closing_signedwithfee_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_signedmessages, sometimes it does not.