-
Notifications
You must be signed in to change notification settings - Fork 525
Update closing_signed fee requirement #847
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
Changes from 2 commits
69a11c2
f029164
8683525
c990020
034486c
aaae6bc
92d2af0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -553,11 +553,24 @@ the other node then replies similarly, using a fee it thinks is fair. This | |
| exchange continues until both agree on the same fee or when one side fails | ||
| the channel. | ||
|
|
||
| In the modern method, the funder sends its permissable fee range, and the | ||
| non-funder has to pick a fee in this range. If it chooses the same value, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be clearer if the non-funder was explicitly mentioned here instead of "it" (ambiguous context imo).
Also it isn't guaranteed that things complete in three messages if the funder chooses to pick a different value, right (responder wants a fee too low, maybe below the current mempool high water mark)? Since the non-funder may not like that advertised fee. Instead, seems this is just best effort, and if the responder doesn't immediately reply with the same value, then things fall back to the "old" method?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Things never fall back to the "old" method? The funder can start over, so, yes, the text should be changed, but there's no fallback.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Roasbeef the case you describe is a spec violation. The non-funder either chooses a fee inside the advertised We only fall back to the old negotiation when the response doesn't contain a
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The flow from the node operator's point of view in that case is:
In the future we may want to automate that retry, but based on our users' feedback, they would really prefer having a human in the loop to decide whether they should adapt their |
||
| negotiation is complete after two messages, otherwise the funder will reply | ||
| with the same value (completing after three messages). | ||
|
|
||
| 1. type: 39 (`closing_signed`) | ||
| 2. data: | ||
| * [`channel_id`:`channel_id`] | ||
| * [`u64`:`fee_satoshis`] | ||
| * [`signature`:`signature`] | ||
| * [`closing_signed_tlvs`:`tlvs`] | ||
|
|
||
| 1. `tlv_stream`: `closing_signed_tlvs` | ||
| 2. types: | ||
| 1. type: 1 (`fee_range`) | ||
| 2. data: | ||
| * [`u64`:`min_fee_satoshis`] | ||
| * [`u64`:`max_fee_satoshis`] | ||
|
|
||
| #### Requirements | ||
|
|
||
|
|
@@ -566,12 +579,18 @@ The funding node: | |
| - SHOULD send a `closing_signed` message. | ||
|
|
||
| The sending node: | ||
| - MUST set `fee_satoshis` less than or equal to the | ||
| base fee of the final commitment transaction, as calculated in [BOLT #3](03-transactions.md#fee-calculation). | ||
| - SHOULD set the initial `fee_satoshis` according to its | ||
| estimate of cost of inclusion in a block. | ||
| - MUST set `signature` to the Bitcoin signature of the close | ||
| transaction, as specified in [BOLT #3](03-transactions.md#closing-transaction). | ||
| - If the channel does not use `option_anchor_outputs`: | ||
| - MUST set `fee_satoshis` less than or equal to the base fee of the final | ||
| commitment transaction, as calculated in [BOLT #3](03-transactions.md#fee-calculation). | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Our commitment transaction, or our counterparty's commitment transaction (I know this isn't new on this PR, I just realized it).
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a good point, it's more subtle than it seems. We use our commitment transaction in eclair, and I think it's what makes most sense from the sender's point of view: we must create a transaction that's cheaper than the alternative we can unilaterally broadcast (even though you'd also need to factor in csv delays into the choice of which one to broadcast). However, the receiver would probably want to receive a proposal that also pays less fees than his commit tx, so would it make more sense to use the min of both commit tx fees here?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given the recipient MUST fail/force-close if we're too high, min seems like the obvious choice. Are there any edge-cases where one party has a high dust limit, causing one side of the commitment transaction to be missing an output (skewing the fee pretty low) whereas both outputs would appear in the cooperative shutdown case? In that world you risk always having to force-close (but maybe that's what you want - at least if the side that gets to skip the counterparty's output is the initiator who pays fees).
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this edge case can meaningfully happen thanks to the channel reserve (which must be greater than the I'm happy to change this to specify that it should be the min of both commitments (even though this requirement will disappear anyway since it doesn't apply to anchor outputs channels).
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, should we drop this requirement for the channel funder? I don't see a reason why the node not paying the fee should care one bit if the channel opener wants to close with a higher feerate than the existing channel one.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's what I did in the first version of the PR, I had dropped this requirement completely, but in order to keep existing channel behavior I was asked to drop it only for anchor outputs. I'm happy to remove it for all channel types honestly, probably worth discussing again during the next spec meeting to see if we can convince @rustyrussell ;)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, its a compatibility issue with existing nodes, so not ideal, but its not a super critical one imo - a few extra force-closes instead of cooperative closes while nodes upgrade isn't the end of the world. If it resulted in force-closes of otherwise-functional channels it'd be much worse, but we're talking about closing the channel anyway. |
||
| - SHOULD set the initial `fee_satoshis` according to its estimate of cost of | ||
| inclusion in a block. | ||
| - SHOULD set `fee_range` according to the minimum and maximum fees it is | ||
| prepared to pay for a close transaction. | ||
| - if it is not the funder: | ||
|
Roasbeef marked this conversation as resolved.
|
||
| - SHOULD set `max_fee_satoshis` to at least the `max_fee_satoshis` received | ||
| - SHOULD set `min_fee_satoshis` to a fairly low value | ||
|
t-bast marked this conversation as resolved.
Outdated
|
||
| - MUST set `signature` to the Bitcoin signature of the close transaction, | ||
| as specified in [BOLT #3](03-transactions.md#closing-transaction). | ||
|
|
||
| The receiving node: | ||
| - if the `signature` is not valid for either variant of closing transaction | ||
|
|
@@ -580,31 +599,54 @@ The receiving node: | |
| - if `fee_satoshis` is equal to its previously sent `fee_satoshis`: | ||
| - SHOULD sign and broadcast the final closing transaction. | ||
| - MAY close the connection. | ||
| - otherwise, if `fee_satoshis` is greater than | ||
| the base fee of the final commitment transaction as calculated in | ||
| [BOLT #3](03-transactions.md#fee-calculation): | ||
| - if `fee_satoshis` matches its previously sent `fee_range`: | ||
| - SHOULD use `fee_satoshis` to sign and broadcast the final closing transaction | ||
| - SHOULD reply with a `closing_signed` with the same `fee_satoshis` value if it is different from its previously sent `fee_satoshis` | ||
|
t-bast marked this conversation as resolved.
|
||
| - MAY close the connection. | ||
| - otherwise, if `fee_satoshis` is greater than the base fee of the final | ||
| commitment transaction as calculated in [BOLT #3](03-transactions.md#fee-calculation) | ||
| and the channel does not use `option_anchor_outputs`: | ||
| - MUST fail the connection. | ||
| - if `fee_satoshis` is not strictly | ||
| between its last-sent `fee_satoshis` and its previously-received | ||
| `fee_satoshis`, UNLESS it has since reconnected: | ||
| - if the message contains a `fee_range`: | ||
| - if there is no overlap between that and its own `fee_range`: | ||
|
t-bast marked this conversation as resolved.
|
||
| - SHOULD fail the connection | ||
| - otherwise: | ||
| - if it is the funder: | ||
| - if `fee_satoshis` is not in the overlap between the sent and received `fee_range`: | ||
| - SHOULD fail the connection | ||
| - otherwise: | ||
|
t-bast marked this conversation as resolved.
|
||
| - MUST reply with the same `fee_satoshis`. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry to gravedig, but what is meant by overlap here? Is it the union of the two ranges or the intersection? If it's the intersection of the two ranges, then the statement a bit above
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, overlap means intersection. We can make the |
||
| - otherwise (it is not the funder): | ||
|
t-bast marked this conversation as resolved.
|
||
| - if it has already sent a `closing_signed`: | ||
| - if `fee_satoshis` is not the same as the value it sent: | ||
| - SHOULD fail the connection. | ||
| - otherwise: | ||
| - MUST propose a `fee_satoshis` in the overlap between received and (about-to-be) sent `fee_range`. | ||
| - otherwise, if `fee_satoshis` is not strictly between its last-sent `fee_satoshis` | ||
| and its previously-received `fee_satoshis`, UNLESS it has since reconnected: | ||
| - SHOULD fail the connection. | ||
| - if the receiver agrees with the fee: | ||
| - otherwise, if the receiver agrees with the fee: | ||
| - SHOULD reply with a `closing_signed` with the same `fee_satoshis` value. | ||
| - otherwise: | ||
| - MUST propose a value "strictly between" the received `fee_satoshis` | ||
| and its previously-sent `fee_satoshis`. | ||
| and its previously-sent `fee_satoshis`. | ||
|
|
||
| #### Rationale | ||
|
|
||
| The "strictly between" requirement ensures that forward | ||
| progress is made, even if only by a single satoshi at a time. To avoid | ||
| keeping state and to handle the corner case, where fees have shifted | ||
| When `fee_range` is not provided, the "strictly between" requirement ensures | ||
| that forward progress is made, even if only by a single satoshi at a time. | ||
| To avoid keeping state and to handle the corner case, where fees have shifted | ||
|
TheBlueMatt marked this conversation as resolved.
|
||
| between disconnection and reconnection, negotiation restarts on reconnection. | ||
|
|
||
| Note there is limited risk if the closing transaction is | ||
| delayed, but it will be broadcast very soon; so there is usually no | ||
| reason to pay a premium for rapid processing. | ||
|
|
||
| Note that the non-funder is not paying the fee, so there is no reason for it | ||
| to have a maximum feerate. It may want a minimum feerate, however, to ensure | ||
| that the transaction propagates. It can always use CPFP later to speed up | ||
| confirmation if necessary, so that minimum should be low. | ||
|
|
||
| ## Normal Operation | ||
|
|
||
| Once both nodes have exchanged `funding_locked` (and optionally [`announcement_signatures`](07-routing-gossip.md#the-announcement_signatures-message)), the channel can be used to make payments via Hashed Time Locked Contracts. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.