-
Notifications
You must be signed in to change notification settings - Fork 492
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
Anchor outputs #688
Anchor outputs #688
Conversation
27217d8
to
c963d54
Compare
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.
On update_fee
I lean to remove it. A hurdle to use CPFP is now to operate a ready-to-use utxo mempool to feed your CPFP, the size being scaled on the number of open channels (worst-case all channels closed at same time and you can't share utxo, at least with current version of package relay). Even if we are going to be better a CPFP management with time, you need a basic version to anchor ouputs being useful today. And if it works you don't need anymore update_fee
which is also a safety mechanism to get unilateral commitment tx getting confirmed (mutual closing being covered with its own negotiation phase) but less-reliable as it's a source of unexpected unilateral close due to fee negotiation disagreement. It could be argue that's less onchain footprint compare to CPFP but in case of unilateral close it's really likely you need another wawe of txn to clean pending HTLCs.
On anchor_output
and updating all scripts with OP_CSV, I lean to having only one ouput being spendable by both party and avoid OP_CSV infecting. IMO, from the mempool viewpoint, there is no such thing as an attacker stucking low-feerate childs, if they got inside it means at time of their insertion their feerate was above the rollingMinimumFeeRate
required and in fact they can't be distinguish from a savy honest user starting to reuse the CPFP output for a honest chain of txn (like a tree of CPFPs to bump multiple commitment txn). Worst-case you can still carve-out and replace the branch of txn, yes you will have to pay to cover their bandwidth, but it may be something you have to do if your first, honest CPFP doesn't work as expected. I think it's worthy to dig more into the mempool policy before to update most of the LN scripts.
To further Antoine’s comments about bit, update_fee needs to go (preferably now, though maybe there’s an argument to make it separate?). It’s not possible to implement it in any way sensibly. Not only are you speculating on future fee rates, but you’re speculating on future fee rates *at the time you need them*. Even worse, you’re somehow expecting to negotiate an impossible-to-speculate value with a counterparty you don’t trust.
… On Nov 4, 2019, at 01:46, Antoine Riard ***@***.***> wrote:
@ariard commented on this pull request.
On update_fee I lean to remove it. A hurdle to use CPFP is now to operate a ready-to-use utxo mempool to feed your CPFP, the size being scaled on the number of open channels (worst-case all channels closed at same time and you can't share utxo, at least with current version of package relay). Even if we are going to be better a CPFP management with time, you need a basic version to anchor ouputs being useful today. And if it works you don't need anymore update_fee which is also a safety mechanism to get unilateral commitment tx getting confirmed (mutual closing being covered with its own negotiation phase) but less-reliable as it's a source of unexpected unilateral close due to fee negotiation disagreement. It could be argue that's less onchain footprint compare to CPFP but in case of unilateral close it's really likely you need another wawe of txn to clean pending HTLCs.
On anchor_output and updating all scripts with OP_CSV, I lean to having only one ouput being spendable by both party and avoid OP_CSV infecting. IMO, from the mempool viewpoint, there is no such thing as an attacker stucking low-feerate childs, if they got inside it means at time of their insertion their feerate was above the rollingMinimumFeeRate required and in fact they can't be distinguish from a savy honest user starting to reuse the CPFP output for a honest chain of txn (like a tree of CPFP to bump multiple commitment txn). Worst-case you can still carve-out and replace the branch of txn, yes you will have to pay to cover their bandwidth, but it may be something you have to do if your first, honest CPFP doesn't work as expected. I think it's worthy to dig more into the mempool before to update most of the LN scripts.
In 02-peer-protocol.md:
> @@ -385,9 +395,8 @@ The recipient:
#### Rationale
-We decide on `option_static_remotekey` at this point when we first have to generate the commitment
-transaction. Even if a later reconnection does not negotiate this parameter, this channel will continue to use `option_static_remotekey`; we don't support "downgrading".
-This simplifies channel state, particularly penalty transaction handling.
+We decide on `option_static_remotekey` or `option_anchor_outputs` at this point when we first have to generate the commitment
+transaction. Even if a later reconnection does not negotiate this parameter, this channel will continue to use `option_static_remotekey` or `option_anchor_outputs`; we don't support "downgrading".
Past funding_signed, there isn't a new negotiation phase (like open_channel/accept_channel, so talking about negotiation there is a bit confusing, if peer stop including anchor outputs in commitment txn, sigs transmitted will be incorrect and we should close the channel anyway ?
In 02-peer-protocol.md:
> @@ -583,6 +599,13 @@ 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
between disconnection and reconnection, negotiation restarts on reconnection.
+In the `option_anchor_outputs` case, the fees on the commitment
If we still allow update_fee, isn't the feerate of the commitment transaction already accurate and so simplified commitment transaction also pay a premium ?
In 02-peer-protocol.md:
> @@ -802,7 +825,12 @@ is destined, is described in [BOLT #4](04-onion-routing.md).
A sending node:
- MUST NOT offer `amount_msat` it cannot pay for in the
remote commitment transaction at the current `feerate_per_kw` (see "Updating
-Fees") while maintaining its channel reserve.
+Fees") while maintaining its channel reserve
+ - if `option_anchor_outputs` applies to this commitment transaction and the sending
+ node is the funder:
+ - MUST be able to additionally pay for `to_local_anchor` and
+ `to_remote_anchor` above its reserve. The anchor value should assumed to be
+ the maximum of the dust limits that have been negotiated by both parties.
While it has been proposed a constant value on the mailing list, can't we use initiator dust limit ? He is the one paying it and so incentivized to limit its inflation.
Addendum: it seems that it was you're proposing if we read diff in BOLT 3 "also substract two times the local dust_limit_satoshis from the funder"
In 02-peer-protocol.md:
> @@ -1106,6 +1138,10 @@ it's simplest to only allow it to set fee levels; however, as the same
fee rate applies to HTLC transactions, the receiving node must also
care about the reasonableness of the fee.
+With `option_anchor_outputs`, `feerate_per_kw` is not as critical anymore to
+guarantuee confirmation, but it still needs to be able to satisfy the min relay
"it still needs to be able to satisfy the min relay fee" IIRC with current package relay PoC min relay fee will be evaluated as part of package total fee too
In 03-transactions.md:
> + OP_CSV
+ OP_DROP
+ <remote_pubkey>
+ OP_CHECKSIG
+
+The output is spent by a transaction with `nSequence` field set to `to_remote_self_delay` (which can only be valid after that duration has passed) and witness:
+
+ <remote_sig>
+
+Otherwise, this output is a simple P2WPKH to `remotepubkey`.
+
+
+#### `to_local_anchor` and `to_remote_anchor` Output (option_anchor_outputs)
+
+This output can be spent by the local and remote nodes respectively to provide incentive to mine the transaction, using child-pays-for-parent. For simplicity, both
+anchor outputs are always added. The only case where this adds some unnecessary weight is if the initiator closes right after opening (no `to_local` output). The
Isn't the to_remote output which is absent in case of under the dust limit push_msat ? Also is that hard to trim the anchor output if the party doesn't have a balance? I think it may worth it to avoid utxo set pollution..
In 03-transactions.md:
>
-These pubkeys are simply generated by addition from their base points:
+These pubkeys are simply generated by addition from their base points. For newer
Assuming a privacy third-party watchtower, does anyone has a sketch of the encrypted blobs sent for each update and the scope of services (just punishment or also timing-out HTLCs...) ? It may help to anchor the discussion on this particular spec change (or at least we conscientiously diminish watchtowers future privacy expectations)
In 05-onchain.md:
> @@ -557,6 +569,18 @@ Thus, 483 bidirectional HTLCs (containing both `to_local` and
Note: even if the `to_remote` output is not swept, the resulting
`max_num_htlcs` is 967; which yields the same unidirectional limit of 483 HTLCs.
+# Generation of HTLC Transactions
+
+If `option_anchor_outputs` does not apply to the commitment transaction, then HTLC-timeout and HTLC-success transactions are complete transactions with (hopefully!) reasonable fees and must be used directly.
+
+Otherwise, the use of `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` on the HTLC signatures received from the peer allows HTLC transactions to be combined with other transactions.
+
+## Requirements
+
+A node which broadcasts an HTLC-success or HTLC-timeout transaction for a commitment transaction for which `option_anchor_outputs` applies:
+ - MUST contribute sufficient fee to ensure timely inclusion in a block.
+ - MAY combine it with other transactions.
nit: you can precise "MAY combine it with other non-HTLC-timeout/HTLC-success" as all of them are going to pre-sign the same index value
In 09-features.md:
> @@ -36,6 +36,7 @@ The following `globalfeatures` bits are currently assigned by this specification
| Bits | Name | Description | Link |
|------|-------------------|--------------------------------------------------------------------|---------------------------------------|
| 8/9 | `var_onion_optin` | This node requires/supports variable-length routing onion payloads | [Routing Onion Specification][bolt04] |
+| 14/15| `option_anchor_outputs` | Anchor outputs | [BOLT #3](03-transactions.md) |
nit: name could be option_bring_your_fees or option_dynamic_fee_adjustement to encompass changes on HTLC txn and underscores the use of CPFP.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
c963d54
to
573d8e2
Compare
How can we remove |
So your saying that replacing the branch is not bad enough to justify always creating two anchor outputs and adding the CSV timelocks to everything? What is your view on this @TheBlueMatt, as the author of bitcoin/bitcoin#15681? With just a single output that is spendable only by both parties initially, there is still the question how an outsiders learns the spending script to sweep up abandoned utxos. On the ML, @rustyrussell proposed in https://lists.linuxfoundation.org/pipermail/lightning-dev/2019-October/002270.html to have one anchor reveal the key for the other anchor. In the case of just a single anchor, something else is required. Or don't worry about the abandoned utxos and see it as a motivation to fix (or not fix) this issue on the base layer? |
Right, I think this is totally a valid point, but I'm not sure it's really worth it. Today, if you open a channel today, the best a node can do is predict future fees on the basis of current fees, implying update_fee of close to 1 sat/byte (maybe with some headroom). This is obviously bogus, and has the same issues as a static value (namely, that fees may spike and then you're screwed), with all the complication of figuring out how to negotiate fees. The only reason I see for keeping update_fee is if we make it effectively static but use it as a cheap upgrade mechanism - current nodes can use a static update_fee of roughly the mempool minfee max that we've seen at any point, and then future nodes can, via an update, switch to minimum relay fee plus a delta once we have package relay on the network. Still, I'm not sure exactly what the semantics of that are, so it may make sense to just skip it. |
If mempool works as expected on RBFing the subpackage (but best would be to write a test against it with worst-case scenario to assert it) the only advantage of adding CSV timelock is to save on bandwidth fees replacement (which just have to be superior, no minimal delta required). Adding OP_CSV to every script is a new cost too, and this one is going to be encumbered for everyone everytimes, not just in worst-case of someone building a low-feerate branch on anchor output. Can the output be a anyone-can-spend, if a third-party wants to pay for my fees that's nice and it's too low I still can overbid on it ? I think this third-party could be a watchtower without introducing new burden on key management. I don't see of we can fix it at the base layer if outputs can't be garbage-collected by anyone.
Yes, even if it's half-broken that's the only way to have a non-fine-grained but best enough feerate to get in the mempool and then trigger a carve-out to un-stuck. My thought was hopefully to get package-relay for 0.20 before this proposal get spec out and deployed. At the end of the day, are people fine if we need a |
I don't think that's correct. If there are at least two HTLCs that the closing party can spend immediately, then he can spend from the first HTLC to create a max-sized child transaction and spend from the second HTLC to create a carve-out. Then a third output that's anyone-can-spend is useless because it can't be relayed until the parent transaction confirms (and because it can't be relayed, it can't be RBF'd either). I think you need the "1 CSV" delays on all non-anchor outputs. |
Ah yes I think you're right, and there is no way to force So we're stuck between:
Going further, @harding can't we tag the carve-output to be sure it's the anyone-can-spend RBFable at will ? Like restraining carve-out to only the first output in the transaction and as commitment txn are dual-party-signed it can't be tweaked ? |
I really don’t think the cost of two extra outputs is worth the debate - just stick with the 1 CSV and Rusty’s construction (latest from the ML) to reveal the anchor into an anyonecanspend after 1 CSV.
…> On Nov 4, 2019, at 14:23, Antoine Riard ***@***.***> wrote:
If there are at least two HTLCs that the closing party can spend immediately, then he can spend from the first HTLC to create a max-sized child transaction and spend from the second HTLC to create a carve-out.
Ah yes I think you're right, and there is no way to force SIGHASH_SINGLE|SIGHASH_ANYONE_CANPAY on this HTLC spending transactions to RBF them against your attacker will ?
So we're stuck between:
adding 1 CSV delay to all non-anchor outputs and one single anyone-can-spend output where party can CPFP biding against each other ?
modifying mempool rules to allow per-output carve-out (but too much DoSy as you described on mailing list?)
Going further, @harding can't we tag the carve-output to be sure it's the anyone-can-spend RBFable at will ? Like restraining carve-out to only the first output in the transaction and as commitment txn are dual-party-signed it can't be tweaked ?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
There might be a better way to do carve-out or something else that hasn't been discussed yet, but it took carve-out over a year to be discussed, PR'd, reviewed, merged, and deployed (assuming nothing goes horribly wrong and it doesn't get yanked last minute from Bitcoin Core 0.19), so I think it's probably best to focus this PR on figuring out how to best use carve-out as-is. After that, my personal preference in LN-supporting work on full node relay policy would be getting package relay deployed so that bring-your-own-fees can work pretty much as intended (package relay would support many other things too). |
62a7a28
to
24be2a2
Compare
Would it be safe to add the restriction "if output is OP_TRUE then only allow one (small) unconfirmed descendant"? I cannot imagine such outputs being useful in any situation where you want to chain a large number of transaction. But as you say these changes take a lot of time to get through, so I think we should stick with what we have for now. |
I think the discussion so far can be summarized as:
For the anchor construction we have two options that stick out:
I lean towards 1), mostly because it is simpler, and this is most likely not the last time we will change the commitment format. |
I don't see any fundamental safety problems in a few minutes of thinking about it[1], but if you do that, I think you pretty much guarantee that every CPFP of the commitment transaction will pay at least 10,000 sat in fees:
If the rolling minimum feerates increase, Mallory can always ensure that the honest participants have to pay at least At the low feerates we've seen for the past 18 months, I suspect the proposed approach with carve-out outputs that can only be spent by the channel participants while the commitment tx is in the mempool is probably cheaper than a minimum of 10,000 sats plus the cost of the commit tx (but I reckon that y'all probably have better data and intuition about that than I do). Note that, for your anchor construction (2) described above, you'd probably be using P2WSH(OP_TRUE) if you wanted to deploy it today. That has only the current package size limit of 100,000 vbytes, so Mallory could force Alice to pay a minimum of about 100,000 sats per commitment. That seem pretty high to me compared to the small fixed costs of the currently-proposed carve-out construction. [1] I think the following conditions would need to be explicit: (1) the OP_TRUE would have to in the scriptPubKey (i.e. no P2SH(OP_TRUE) or P2WSH(OP_TRUE)); what we might call "bare OP_TRUE". The reason is that Bitcoin Core currently relays the P2SH/P2WSH variants and so changing how it handles those cases could disrupt someone existing use of them, so we'd at least have to be much more careful. Bitcoin Core doesn't currently relay bare OP_TRUE (AFAIK), so allowing it to relay it at least in some cases is loosening the relay rules and so shouldn't affect anyone's existing operations. (2) If the transaction has multiple OP_TRUE outputs, only one should be allowed to be spent as an exception to other mempool rules (like carve-out) or otherwise you allow a huge amount of mempool spam; I think you were implying this, but I wanted to make it explicit. |
Huh? I'm very confused. I don't see anyone in this thread suggesting we keep update_fee? I pointed out, above, that we don't have a way of dynamically determining a commitment transaction fee that will propagate either, so I think that argument is largely bogus. |
Argument is that since we cannot pick a static value to ensure propagation, we need a way to change the commitment fee. Path of least resistance seems to just stick with status quo. It is not making the problem worse, negotiating a fee that propagates sounds like a strictly easier problem than a fee that readily confirms. Removing |
(I'm assuming you meant (1)): Good observation, my assumption here was that it is unlikely that somebody would perform this attack, and in that unlikely case we would just pay the higher fee. But as you point out, the attacker is not only restricted to the channel counterparties, but all nodes watching the mempool, so someone could trivially make the life sad for every LN user. (Now I'm leaning towards construction (2) from above) |
Hmm, can you respond to my above point? Specifically, I don't believe that we can pick a value to ensure propagation dynamically, either, so the argument is somewhat moot. |
Seems like the only safety measure we have to avoid a channel-party/third-party inflating at no cost any CPFP is by circuit-breaking each party ability to spend in different outputs. We can still avoid the OP_CSV cost by restraining carve-out to some pattern-matching like OP_TRUE or tagged output (implemented here to see how it looks like) but that would be still a hack. Long-term solution for N-party would be to force any tx chaining on the tagged carve-out output to pay a competitive feerate... So 2 anchor outputs anyone-can-spend-after-delay to sweep them seems to be the best solution we can get engineer for now. On |
Yep, we agree that any value (being dynamic or static) cannot give any guarantee about future propagation. And since we don't have a solution, I argue there's nothing we can do at this point. (hence no change to |
24be2a2
to
0b21232
Compare
Another question came to mind: do we want to remove the anchors during mutual close? This is a bit under-specified currently. The spec says that the closing transaction has It would be a bit of a waste to keep the anchors IMHO (the final main outputs can be used to bump fees). WDYT? |
The lnd implementation indeed removes the anchor outputs from the coop close tx, but the 660 sats goes directly to miner fees. Maybe this is not specified properly in the PR? We don't add it back to the funder amount, but I think in this case it doesn't really matter if you do it: Since you must agree on a final fee that is taken from the funder regardless, whether you add the value back to the funder output before calculating the final fee or account for it during fee calculation shouldn't make a difference? |
There is one difference, that not adding back the anchor values sets a fee floor of 660 to the mutual close. |
Great I think this is the most important behavior to preserve (otherwise exchanged signatures won't match). Since the spec already says in Bolt 3 that the closing transaction has |
Yes, it's like many of the fee simplifications, though this isn't technically part of the fee (I proposed originally it should be, but the fee is used for other things like the maximum fee for the close tx so it's simpler to add it). I always include it. |
I've been able to create channels between eclair and lnd that use anchor outputs, and correctly update commitment and htlc txs. I think lnd's behavior is wrong when creating the closing tx; lnd sends a See complete logs here (closing tx line 1429): https://pastebin.com/d7F1VQx1 Let me know what you think @halseth @rustyrussell |
Yes, that is what lnd does. I agree it can be confusing if not explicitly spelled out. We can either make it clear that the proposed fee will come in addition to the "anchor fee", or as you propose include the 660 sats in the proposed fee. Either approach is okay by me (but the latter would need a change in the fee calculation for the current lnd anchor type. |
I think that we should use the fact that So I'd be more in favor of lnd explicitly adding the 660 sats to |
No, we shouldn't add anchor fee to the closing. Firstly, it's silly. Secondly, the spec was carefully written to avoid this:
(Note: no +660 here!) In construction it says:
Which is a bit roundabout, and should simply say: But it's clear: 660 is an additional fee. Now, in bolt 2 it describes closing:
See, "base fee". That's fairly clearly defined; though maybe we should highlight it to make sure people know it's a Specific Thing? And elsewhere the terms "base fee and anchor fees" are always used. |
@rustyrussell Or are you saying that "660 is an additional fee" only for commitment transactions, not coop closes? |
The latter. To be technically correct, definition of base fee is unchanged, and that's what closing uses as max fee. |
As specified by lightning/bolts#688. Signed-off-by: Rusty Russell <[email protected]>
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.
ACK a26575c
I'll be on vacation during the next spec meeting, but interop testing has been completed between eclair (ACINQ/eclair#1501) and lnd (https://github.com/halseth/lnd/tree/anchors-spec) and everything worked correctly.
As specified by lightning/bolts#688. Signed-off-by: Rusty Russell <[email protected]>
As specified by lightning/bolts#688. Signed-off-by: Rusty Russell <[email protected]>
As specified by lightning/bolts#688. Signed-off-by: Rusty Russell <[email protected]>
This commit extends the specification with a new commitment format that adds two anchor outputs to the commitment transaction. Anchor outputs are a safety feature that allows a channel party to unilaterally increase the fee of the commitment transaction using CPFP and ensure timely confirmation on the chain. There is no cooperation required from the remote party.
a26575c
to
1739746
Compare
Squashed commits |
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.
LGTM 🧬
This PR is a continuation of #513.
Summary of changes:
Refer to
pushme
outputs asanchor
outputs, to prevent confusion withpush_msat
on theopen_channel
message.Add
1 OP_CHECKSEQUENCEVERIFY
to theto_remote
output. This ensures that the carve-out [mempool] Allow one extra single-ancestor transaction per package bitcoin/bitcoin#15681 works as intended.Add
1 OP_CHECKSEQUENCEVERIFY OP_DROP
to the non-revocation clause of the HTLC outputs. Reason: to make the carve-out work.Anchor output type: locked to the (untweaked) funding pubkey and spendable by anyone after the commit tx confirms to prevent utxo set pollution.
Within each version of the commitment transaction, both anchors always have a fixed value of 330 sats and are paid for by the initiator.
Leave
update_fee
mechanism in place. Initially the anchor outputs are mainly a safety mechanism to get the commitment transaction confirmed. Later the network can start operating at lower negotiated fees and rely more heavily on cpfp.For co-op close, the commitment tx fee remains a ceiling and parties can negotiate downward if desired.
HTLC timeout/success transactions are signed with
SIGHASH_SINGLE|SIGHASH_ANYONECANPAY
to allow attachment of an additional input to increase fee.