Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bolt2: fee_range clarification #1013

Open
Crypt-iQ opened this issue Jul 26, 2022 · 10 comments · May be fixed by #1016
Open

bolt2: fee_range clarification #1013

Crypt-iQ opened this issue Jul 26, 2022 · 10 comments · May be fixed by #1016

Comments

@Crypt-iQ
Copy link
Contributor

I am a little confused about the fee_range requirements for coop close.

I asked some clarifying questions of @t-bast in #847 (comment):

"Yes, fee_range allows the funder to update its fee_range if the fundee doesn't respond or sent a warning."

I didn't realize until now that the funder may update its fee_range even if the fundee did not send a warning. I think this could lead to the following issue:

A's PoV

A                      B

fr=[100, 200], fs=150
----closing_signed---->

fr=[200, 300], fs=275
----closing_signed----> (A doesn't hear back soon enough and updates the range)

fr=[150, 250], fs=175
<---closing_signed----- (spec says A should fail here since 175 is not in the overlap)

B's PoV

A                      B

fr=[100, 200], fs=150
----closing_signed---->

fr=[150, 250], fs=175
<---closing_signed----- (B sends acceptable message back)

fr=[200, 300], fs=275
----closing_signed----> (spec says B should fail since 175 wasn't received)
  • A fails since there is an overlap between A's range [200, 300] and B's range [150, 250] of [200, 250], but 175 isn't in the overlap:

    • if the message contains a fee_range:
      • if there is no overlap between that and its own fee_range:
        • SHOULD send a warning
        • MUST fail the channel if it doesn't receive a satisfying fee_range after a reasonable amount of time
      • otherwise:
        • if it is the funder:
          • if fee_satoshis is not in the overlap between the sent and received fee_range:
            • MUST fail the channel
  • B fails since there is an overlap between A's range [200, 300] and B's range [150, 250] of [200, 250], but 175 should have been received from A since B has already sent closing_signed.

    • if the message contains a fee_range:
      • if there is no overlap between that and its own fee_range:
        • SHOULD send a warning
        • MUST fail the channel if it doesn't receive a satisfying fee_range after a reasonable amount of time
      • otherwise:
        • otherwise (it is not the funder):
          • if it has already sent a closing_signed:
            • if fee_satoshis is not the same as the value it sent:
              • MUST fail the channel
@t-bast
Copy link
Collaborator

t-bast commented Jul 27, 2022

You're right, that case would lead to a force-close. It can happen in theory, but I'd argue it likely won't happen in practice: A will send its second range after a while if it believes that B is unresponsive. It's very unlikely that B will decide to respond to an old messages exactly at the same time. So there is indeed a potential race condition, but we're very unlikely to hit it.

Nevertheless, as discussed on the PR, we can change this to be a turn-based protocol by adding a new message to explicitly reject a fee range (e.g. reject_closing_fee_range) and require B to always respond to closing_signed with either its own closing_signed or reject_closing_fee_range. Having a turn-based protocol is probably a good idea, at the time I didn't want to introduce a new message but it is probably required if we want musig2 to work.

@Crypt-iQ
Copy link
Contributor Author

I also don't think it's likely and depends on implementations "unresponsive timers" and maybe connection issues. I think making it turn-based by using a special message instead of a warning would fix this but I'd have to think a bit more about it.

@t-bast
Copy link
Collaborator

t-bast commented Aug 2, 2022

Here is a high-level proposal for an updated turn-based closing flow:

  • initiator A starts with closing_signed and provides a fee_range
  • non-initiator B responds with either:
    • closing_signed with a fee contained in A's fee_range: happy path, we can now broadcast the cooperative close tx
    • a new closing_fee_range_mismatch odd message if A's fee_range is unacceptable: this new message contains B's acceptable fee_range

Then A's behavior should be left open to implementations. A can now either force-close or sending another closing_signed that matches B's proposed fee_range, but we want to make sure we don't accidentally re-implement the fee negotiation loop we wanted to get rid of!

On the eclair side, here is what I plan to offer to node operators. When they initiate the mutual close and provide a fee range, they can also provide a boolean flag force_close_on_fee_range_mismatch. If true, we will automatically force-close if we receive closing_fee_range_mismatch. If false, when we receive closing_fee_range_mismatch, we will log it to a special file containing important node operator notifications (which is usually forwarded to telegram bots or something similar). The node operator can then manually decide to either accept the proposed fee_range, do nothing or force-close.

When the mutual close is initiated by our peer (ie we're not funder and won't pay the on-chain fee), we will accept whatever fee_range they provide unless it's below the current dynamic minimum mempool fee. If it is below that value, we will send closing_fee_range_mismatch and wait for another closing_signed with an updated fee_range.

Would that work for you? We can decide later (when actually implementing it) whether it needs a feature bit or not. It technically doesn't need one, but I don't mind adding one if others feel it's useful or better to make explicit.

@Crypt-iQ
Copy link
Contributor Author

Crypt-iQ commented Aug 2, 2022

I like the proposal.

@t-bast
Copy link
Collaborator

t-bast commented Aug 3, 2022

I think your users could also try again later if force_close_on_fee_range_mismatch is true instead of force closing immediately? Just a suggestion, don't know all the details.

True, maybe we can instead have a field force_close_on_fee_range_mismatch_after = N hours and if the node operator retries before the timeout is reached, that lets them propose a new fee_range. I'll discuss this with node operators to see what they'd like.

@TheBlueMatt
Copy link
Collaborator

I don't really understand why this is a (material) concern. If A is gonna send a new closing_signed, A should handle this. If you don't want to handle it, disconnect and reconnect :). More realistically, basically every node should send a warning now, so you can just treat the no-warning-received case as "peer has gone away".

@Crypt-iQ
Copy link
Contributor Author

after what time can you determine that your peer hasn't sent the warning? the wording of the spec says that the warning is optional (SHOULD). the spec says to fail the channel here. also having a turn-based fee_range is needed for simple-taproot-channels unless an overhaul of coop closing is done where only sigs are sent at the end

@TheBlueMatt
Copy link
Collaborator

Its optional primarily for backwards compatibility reasons - warnings were not merged when the new closing stuff was merged. I think we could just switch it to MUST (which, actually, isn't that much of a backwards compatibility concern - if a peer "takes forever" to respond you have to handle that another way anyway).

Ultimately the intent here is that retrying with a new fee range will not be something that's even remotely quick - it either requires a user manually responding to a warning message (that includes human-readable text explaining that the peer doesn't like our fees) or the node deciding "enough" time has passed (probably on the order of many blocks where its feerate estimates have changed).

@Crypt-iQ
Copy link
Contributor Author

Yes it can be changed to a MUST. I know that it's not going to happen, but the way the spec is written doesn't really convey the intent behind the change (waiting a while and whatnot)

@Crypt-iQ
Copy link
Contributor Author

Crypt-iQ commented Oct 17, 2022

Should the sender of warning give a hint about the range like too high or too low in TLV? Otherwise, the funder will be guessing.

Also is it possible that a warning is sent from B -> A regarding the same channel but unrelated to coop close? If so, it could confuse A.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants