-
Notifications
You must be signed in to change notification settings - Fork 493
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
Zero-fee commitments using v3 transactions (feature 40/41) #1228
base: master
Are you sure you want to change the base?
Conversation
We introduce a new `channel_type` that leverages v3 transactions, pay-to-anchor outputs and ephemeral dust. With this change, commitment transactions don't pay any mining fee, which gets rid of `update_fee` and all of the related channel reserve issues. It also gets rid of the undesired channel force-closes that happen when the mempool feerate spikes and channel participants disagree on what feerate to use, which has been a major source of wasted on-chain space. It also offers better protection against pinning attacks and reduces the on-chain footprint compared to anchor output channels. We use a single anchor output whose amount is the sum of all trimmed outputs (and may thus be `0 sat`). We remove the 1-block relative delay used by anchor output channels: this allows using our channel outputs (main balance or pending HTLCs) to CPFP a remote commitment transaction (no need to add external inputs). v3 transactions and pay-to-anchor outputs have been standard since the release of Bitcoin Core v28.0. Ephemeral dust will become standard in the Bitcoin Core v29.0 release.
05-onchain.md
Outdated
5. _shared ephemeral anchor_: one output paying to the *local* or *remote* | ||
node's funding_pubkey. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description doesn't seem to match the fact that the shared anchor is using P2A.
Also, the "ephemeral" in the output name isn't used anywhere else. It may make sense to use just "shared anchor" for consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, this isn't consistent with the rest of the spec, I'll clean that up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 4de2873
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This wasn't fully addressed. It still refers to a keyed anchor instead of P2A.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damn, thanks 🦅 👁️, done in b0b1fa4
Hi @t-bast can you elaborate this a bit? |
Never mind. This delving post has the details, makes for a good supplemental reading: |
* locktime: `0` for HTLC-success, `cltv_expiry` for HTLC-timeout | ||
* txin count: 1 | ||
* `txin[0]` outpoint: `txid` of the commitment transaction and `output_index` of the matching HTLC output for the HTLC transaction | ||
* `txin[0]` sequence: `0` (set to `1` for `option_anchors`) | ||
* `txin[0]` sequence: `1` for `option_anchors`, `0xFFFFFFFD` for `zero_fee_commitments`, `0` otherwise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the difference between using 0
and 0xFFFFFFFD
here?
Neither imposes a bip68 timelock, and both explicitly opt-in to bip125 RBF.
I am just trying to understand the motivation for why the old-style txs were using 0
and why the newer style proposed here uses a different value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about that change at all, this is up for bikeshedding! We were previously using 0
just because we hadn't thought much about it, and 0
is a nice default value. But then we noticed that most wallets by default set nSequence
to 0xFFFFFFFD
, so we updated our closing transactions to use 0xFFFFFFFD
to benefit from a larger anonymity set (in #1205). I figured that since we're changing the transaction format, it would be a good opportunity to be consistent and use 0xFFFFFFFD
instead of 0
wherever we can. But HTLC transactions will always be recognized as HTLC transactions because of their unique script: we don't benefit from any anonymity set improvement, so maybe this is unnecessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, so there is no interesting technical difference I missed. Thanks.
I understand the potential privacy aspect, but I don't think it's worth the bikeshedding in this case, so feel free to mark this as resolved :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect anyone using TRUC tx will keep this 0 since it's not a meaningful signal, especially post-fullrbf world?
I don't think we have enough data to say exactly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's hard to figure out, I'll ask other implementers how they feel, but we most likely will just keep this to 0
like it is today (when there is no good reason to change, let's keep the existing stuff).
This will become more obvious when I add the test vectors! It is also already defined in Bolt 3, if the paragraph for this is unclear please put a comment on it with a suggestion on how I could make it clearer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach ACK.
Really eager to see this get implemented and used across the network. Also hope we can follow up soon with the changes needed to fix HTLC pinning.
02-peer-protocol.md
Outdated
- `max_accepted_htlcs` is greater than 483. | ||
- it considers `feerate_per_kw` too small for timely processing or unreasonably large. | ||
- `channel_type` includes `zero_fee_commitments` and: | ||
- `max_accepted_htlcs` is greater than 283. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
283 is more than 2x what I would expect.
Back-of-the-envelope:
TRUC limit = 40,000 wu
zero-fee commit weight ~= 780 + 172 * num_htlcs
780 + 172 * max_num_htlcs = 40,000
max_num_htlcs = 228
max_accepted_htlcs = 228 / 2 = 114
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're most likely right! I wanted to wait for my prototype implementation to test against bitcoind
to make sure the number matches what is supported, I will update once it's verified!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed this to 114 in 4de2873 while we wait for an official test against bitcoind
.
03-transactions.md
Outdated
The amounts for each output MUST be rounded down to whole satoshis. If this amount, minus the fees for the HTLC transaction, is less than the `dust_limit_satoshis` set by the owner of the commitment transaction, the output MUST NOT be produced (thus the funds add to fees). | ||
The amounts for each output MUST be rounded down to whole satoshis. | ||
If this amount, minus the fees for the HTLC transaction, is less than the `dust_limit_satoshis` set by the owner of the commitment transaction, the output MUST NOT be produced. | ||
If `zero_fee_commitments` is used, this amount is added to the `shared_anchor`, otherwise it adds to on-chain fees. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If `zero_fee_commitments` is used, this amount is added to the `shared_anchor`, otherwise it adds to on-chain fees. | |
In that case, the amount is added to the `shared_anchor` if `zero_fee_commitments` is used, otherwise the amount is added to on-chain fees. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 4de2873
05-onchain.md
Outdated
- MUST spend any `to_local_anchor` or `shared_anchor` output, providing sufficient fees | ||
as incentive to include the commitment transaction in a block. When using `nVersion=2`, | ||
special care must be taken when spending to a third-party, because this re-introduces | ||
the vulnerability that was addressed by adding the CSV delay to the non-anchor outputs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bringing up nVersion=2
here is a bit confusing and may give the reader the idea they can set nVersion=3
for to_local_anchor
spends to avoid this issue (which won't relay).
- MUST spend any `to_local_anchor` or `shared_anchor` output, providing sufficient fees | |
as incentive to include the commitment transaction in a block. When using `nVersion=2`, | |
special care must be taken when spending to a third-party, because this re-introduces | |
the vulnerability that was addressed by adding the CSV delay to the non-anchor outputs. | |
- MUST spend any `to_local_anchor` or `shared_anchor` output, providing sufficient fees | |
as incentive to include the commitment transaction in a block. For `to_local_anchor`, | |
special care must be taken when spending to a third-party, because this re-introduces | |
the pinning vulnerability that was addressed by adding the CSV delay to the non-anchor outputs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 4de2873
05-onchain.md
Outdated
@@ -515,7 +517,7 @@ A local node: | |||
using the revocation private key. | |||
- SHOULD extract the payment preimage from the transaction input witness, if | |||
it's not already known. | |||
- if `option_anchors` applies: | |||
- if `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is used for HTLC transactions: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- if `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is used for HTLC transactions: | |
- if `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is used for HTLC transactions (i.e. `option_anchors` or `zero_fee_commitments` applies): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 4de2873
05-onchain.md
Outdated
Note: when `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is used for HTLC transactions, | ||
the cheating node can pin spends of its HTLC-timeout/HTLC-success outputs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: when `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is used for HTLC transactions, | |
the cheating node can pin spends of its HTLC-timeout/HTLC-success outputs. | |
Note: when `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` is used for HTLC transactions (i.e. `option_anchors` or `zero_fee_commitments`), | |
the cheating node can pin spends of its HTLC-timeout/HTLC-success outputs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 4de2873
05-onchain.md
Outdated
If `SIGHASH_ALL` is used for HTLC transactions, then HTLC-timeout and | ||
HTLC-success transactions are complete transactions with (hopefully!) | ||
reasonable fees and must be used directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section describes when to use SIGHASH_ALL
vs SIGHASH_SINGLE|SIGHASH_ANYONECANPAY
. So we shouldn't assume the reader already knows which sighashes to use for each channel type.
If `SIGHASH_ALL` is used for HTLC transactions, then HTLC-timeout and | |
HTLC-success transactions are complete transactions with (hopefully!) | |
reasonable fees and must be used directly. | |
If `option_anchors` and `zero_fee_commitments` do not apply, then HTLC-timeout and | |
HTLC-success transactions are signed with SIGHASH_ALL and are complete transactions with (hopefully!) | |
reasonable fees and must be used directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 4de2873
We introduce a new
channel_type
that leverages v3 transactions, pay-to-anchor outputs and ephemeral dust. With this change, commitment transactions don't pay any mining fee, which gets rid ofupdate_fee
and all of the related channel reserve issues. It also gets rid of the undesired channel force-closes that happen when the mempool feerate spikes and channel participants disagree on what feerate to use, which has been a major source of wasted on-chain space.It also offers better protection against pinning attacks (thanks to package relay) and reduces the on-chain footprint compared to anchor output channels. We use a single anchor output whose amount is the sum of all trimmed outputs (and may thus be
0 sat
). We remove the 1-block relative delay used by anchor output channels: this allows using our channel outputs (main balance or pending HTLCs) to CPFP a remote commitment transaction (no need to add external inputs).v3 transactions and pay-to-anchor outputs have been standard since the release of Bitcoin Core v28.0. Ephemeral dust will become standard in the Bitcoin Core v29.0 release.
TODO: