Subject: Re: [bitcoin-dev] New transaction policies (nVersion=3) for contracting protocols

From: Greg Sanders <[email-masked]>
Date: Mon, 26 Sep 2022 12:01:54 -0400

Bastien,

> This may be already covered by the current package RBF logic, in that
scenario we are simply replacing [ParentTx, ChildTx1] with
[ParentTx, ChildTx2] that pays more fees, right?

For clarification, package RBF is ParentTx*s*(plural), and
ChildTx(singular), so it might be a bit more complicated than we're
thinking, and currently the V3 proposal would first de-duplicate the
ParentTx based on what is in the mempool, then look at the "rest" of the
transactions as a package, then individually. Not the same, not sure how
different. I'll defer to experts.

Best,
Greg

On Mon, Sep 26, 2022 at 11:48 AM Bastien TEINTURIER via bitcoin-dev <
[email-masked]> wrote:

> Thanks Gloria for this great post.
>
> This is very valuable work for L2 contracts, and will greatly improve
> their security model.
>
> > "Only 1 anchor output? What if I need to bump counterparty's commitment
> tx in mempool?"
> > You won't need to fee-bump a counterparty's commitment tx using CPFP.
> > You would just package RBF it by attaching a high-feerate child to
> > your commitment tx.
>
> Note that we can also very easily make that single anchor spendable by
> both participants (or even anyone), so if you see your counterparty's
> commitment in your mempool, you can bump it without publishing your
> own commitment, which is quite desirable (your own commitment tx has
> CSV delays on your outputs, whereas your counterparty's commitment tx
> doesn't).
>
> > "Is this a privacy issue, i.e. doesn't it allow fingerprinting LN
> transactions based on nVersion?"
>
> I agree with you, this isn't worse than today, unilateral closes will
> probably always be identifiable on-chain.
>
> > Would kind of be nice if package RBF would detect a "sibling output
> spend"
> > conflict, and knock it out of the mempool via the other replacement
> rules?
> > Getting rid of the requirement to 1 block csv lock every output would be
> > quite nice from a smart contracting composability point of view.
>
> +1, that would be very neat!
>
> This may be already covered by the current package RBF logic, in that
> scenario we are simply replacing [ParentTx, ChildTx1] with
> [ParentTx, ChildTx2] that pays more fees, right?
>
> > 1) I do think that we should seriously consider allowing OP_TRUE to
> become
> > a standard script type as part of this policy update. If pinning is
> solved,
> > then there's no reason to require all those extra bytes for "binding" an
> > anchor to a specific wallet/user. We can save quite a few bytes by having
> > the input be empty of witness data.
> > 2) If we allow for a single dust-value(0 on up) output which is
> immediately
> > spent by the package, anchors become even easier to to design. No value
> has
> > to be "sapped" from contract participants to make an anchor output.
> There's
> > more complications for this, such as making sure the parent transaction
> is
> > dropped if the child spend is dropped, but maybe it's worth the squeeze.
>
> I also think both of these could be quite useful. This would probably
> always
> be used in combination with a parent transaction that pays 0 fees, so the
> 0-value output would always be spent in the same block.
>
> But this means we could end up with 0-value outputs in the utxo set, if for
> some reason the parent tx is CPFP-ed via another output than the 0-value
> one,
> which would be a utxo set bloat issue. But I'd argue that we're probably
> already creating utxo set bloat with the 330 sat anchor outputs (especially
> since we use two of them, but only one is usually spent), so it would
> probably be *better* than what we're doing today.
>
> Thanks,
> Bastien
>
> Le lun. 26 sept. 2022 à 03:22, Antoine Riard via bitcoin-dev <
> [email-masked]> a écrit :
>
>> Hi Gloria,
>>
>> Thanks for the progress on package RBF, few early questions.
>>
>> > 2. Any descendant of an unconfirmed V3 transaction must also be V3.
>>
>> > 3. An unconfirmed V3 transaction cannot have more than 1 descendant.
>>
>> If you're a miner and you receive a non-V3, second descendant of an
>> unconfirmed V3 transaction, if the offered fee is in the top mempool
>> backlog, I think you would have an interest to accept such a transaction.
>>
>> So I'm not sure if those two rules are compatible with miners
>> incentives...
>>
>> > 4. A V3 transaction that has an unconfirmed V3 ancestor cannot be
>> >    larger than 1000 virtual bytes.
>>
>> If I understand correctly the 1000 vb upper bound rational, it would be
>> to constraint the pinning counterparty to attach a high fee to a child due
>> to the limited size, if they would like this transaction to be stuck in the
>> network mempools. By doing so  this child has high odds to confirm.
>>
>> I still wonder if this compatible with miner incentives in period of
>> empty mempools, in the sense that if you've already a V3 transaction of
>> size 100Kvb offering 2 sat/vb, it's more interesting than a V3 replacement
>> candidate of size 1000 vb offering 10 sat/vb. It could be argued the former
>> should be conserved.
>>
>> (That said, the hard thing with any replacement strategy we might evict a
>> parent transaction *now* to which is attached a high-feerate child *latter*
>> making for a utxo considered the best ancestor set. Maybe in the long-term
>> miners should keep every transaction ever accepted...)
>>
>> > (Lower bound) the smaller this limit, the fewer UTXOs a child may use
>> > to fund this fee-bump. For example, only allowing the V3 child to have
>> > 2 inputs would require L2 protocols to manage a wallet with high-value
>> > UTXOs and make batched fee-bumping impossible. However, as the
>> > fee-bumping child only needs to fund fees (as opposed to payments),
>> > just a few UTXOs should suffice.
>>
>> Reminder for L2 devs, batched fee-bumping of time-sensitive confirmations
>> of commitment transactions is unsafe, as the counterparty could enter in a
>> "cat-and-mouse" game to replace one of the batch element at each block to
>> delay confirmation of the remaining elements in the batch, I think.
>>
>> On the other hand, I wonder if we wouldn't want a higher bound. LN
>> wallets are likely to have one big UTXO in their fee-bumping reserve pool,
>> as the cost of acquiring UTXO is non-null and in the optimistic case, you
>> don't need to do unilateral closure. Let's say you close dozens of channels
>> at the same time, a UTXO pool management strategy might be to fan-out the
>> first spends UTXOs in N fan-out outputs ready to feed the remaining
>> in-flight channels.
>>
>> > 1. The rule around unconfirmed inputs was
>> > originally "A package may include new unconfirmed inputs, but the
>> > ancestor feerate of the child must be at least as high as the ancestor
>> > feerates of every transaction being replaced."
>>
>> Note, I think we would like this new RBF rule to also apply to single
>> transaction package, e.g second-stage HTLC transactions, where a
>> counterparty pins a HTLC-preimage by abusing rule 3. In that case, the
>> honest LN node should be able to broadcast a "at least as high ancestor
>> feerate" HTLC-timeout transaction. With `option_anchor_outputs" there is no
>> unconfirmed ancestor to replace, as the commitment transaction, whatever
>> the party it is originating from, should already be confirmed.
>>
>> > "Is this a privacy issue, i.e. doesn't it allow fingerprinting LN
>> transactions based on nVersion?"
>>
>> As of today, I think yes you can already fingerprint LN transactions on
>> the  spec-defined amount value of the anchor outputs, 330 sats. There is
>> always one of them on post-anchor commitment transactions. And sadly I
>> would say we'll always have tricky fingerprints leaking from unilateral LN
>> closures such as HTLC/PTLC timelocks...
>>
>> > "Can a V2 transaction replace a V3 transaction and vice versa?"
>>
>> IIUC, a V3 package could replace a V2 package, with the benefit of the
>> new package RBF rules applied. I think this would be a significant
>> advantage for LN, as for the current ~85k of opened channels, the old V2
>> states shouldn't be pinning vectors. Currently, commitment transactions
>> signal replaceability.
>>
>> Le ven. 23 sept. 2022 à 11:26, Gloria Zhao via bitcoin-dev <
>> [email-masked]> a écrit :
>>
>>> Hi everyone,
>>>
>>> I'm writing to propose a very simple set of mempool/transaction relay
>>> policies intended to aid L2/contract protocols. I realized that
>>> the previously proposed Package Mempool Accept package RBF [1]
>>> had a few remaining problems after digging into the RBF logic more [2].
>>> This additional set of policies solves them without requiring a huge RBF
>>> overhaul.
>>>
>>> I've written an implementation (and docs) for Bitcoin Core:
>>> https://github.com/bitcoin/bitcoin/pull/25038
>>>
>>> (You may notice that this proposal incorporates feedback on the PR -
>>> thanks Suhas Daftuar, Gregory Sanders, Bastien Teinturier, Anthony Towns,
>>> and others.)
>>>
>>> If you are interested in using package RBF/relay to bump presigned
>>> transactions, I think you may be interested in reviewing this proposal.
>>> This should solve Rule 3 pinning and perhaps allow us
>>> to get rid of CPFP carve-out (yay!). I'm keen to hear if people find
>>> the 1-anchor-output, 1000vB child limit too restrictive. Also, if you
>>> find a
>>> pinning attack or something that makes it unusable for you, I would
>>> really really like to know.
>>>
>>> Note that transactions with nVersion=3 ("V3 transactions") are
>>> currently non-standard in Bitcoin Core. That means **anything that was
>>> standard before this policy change would still be standard
>>> afterwards.** If you don't want your transactions to be subject to
>>> these rules, just continue whatever you're doing and don't use
>>> nVersion=3. AFAICT this shouldn't break anything, but let me know if
>>> this would be disruptive for you?
>>>
>>> **New Policies:**
>>>
>>> This includes:
>>> - a set of additional policy rules applying to V3 transactions
>>> - modifications to package RBF rules
>>>
>>> **V3 transactions:**
>>>
>>> Existing standardness rules apply to V3 (e.g. min/max tx weight,
>>> standard output types, cleanstack, etc.). The following additional
>>> rules apply to V3:
>>>
>>> 1. A V3 transaction can be replaced, even if it does not signal BIP125
>>>    replaceability. (It must also meet the other RBF rules around fees,
>>> etc. for replacement to happen).
>>>
>>> 2. Any descendant of an unconfirmed V3 transaction must also be V3.
>>>
>>> *Rationale*: Combined with Rule 1, this gives us the property of
>>> "inherited" replaceability signaling when descendants of unconfirmed
>>> transactions are created. Additionally, checking whether a transaction
>>> signals replaceability this way does not require mempool traversal,
>>> and does not change based on what transactions are mined. It also
>>> makes subsequent rules about descendant limits much easier to check.
>>>
>>> *Note*: The descendant of a *confirmed* V3 transaction does not need to
>>> be V3.
>>>
>>> 3. An unconfirmed V3 transaction cannot have more than 1 descendant.
>>>
>>> *Rationale*: (Upper bound) the larger the descendant limit, the more
>>> transactions may need to be replaced. This is a problematic pinning
>>> attack, i.e., a malicious counterparty prevents the transaction from
>>> being replaced by adding many descendant transactions that aren't
>>> fee-bumping.
>>>
>>> (Lower bound) at least 1 descendant is required to allow CPFP of the
>>> presigned transaction. The contract protocol can create presigned
>>> transactions paying 0 fees and 1 output for attaching a CPFP at
>>> broadcast time ("anchor output"). Without package RBF, multiple anchor
>>> outputs would be required to allow each counterparty to fee-bump any
>>> presigned transaction. With package RBF, since the presigned
>>> transactions can replace each other, 1 anchor output is sufficient.
>>>
>>> 4. A V3 transaction that has an unconfirmed V3 ancestor cannot be
>>>    larger than 1000 virtual bytes.
>>>
>>> *Rationale*: (Upper bound) the larger the descendant size limit, the
>>> more vbytes may need to be replaced. With default limits, if the child
>>> is e.g. 100,000vB, that might be an additional 100,000sats (at
>>> 1sat/vbyte) or more, depending on the feerate.
>>>
>>> (Lower bound) the smaller this limit, the fewer UTXOs a child may use
>>> to fund this fee-bump. For example, only allowing the V3 child to have
>>> 2 inputs would require L2 protocols to manage a wallet with high-value
>>> UTXOs and make batched fee-bumping impossible. However, as the
>>> fee-bumping child only needs to fund fees (as opposed to payments),
>>> just a few UTXOs should suffice.
>>>
>>> With a limit of 1000 virtual bytes, depending on the output types, the
>>> child can have 6-15 UTXOs, which should be enough to fund a fee-bump
>>> without requiring a carefully-managed UTXO pool. With 1000 virtual
>>> bytes as the descendant limit, the cost to replace a V3 transaction
>>> has much lower variance.
>>>
>>> *Rationale*: This makes the rule very easily "tacked on" to existing
>>> logic for policy and wallets. A transaction may be up to 100KvB on its
>>> own (`MAX_STANDARD_TX_WEIGHT`) and 101KvB with descendants
>>> (`DEFAULT_DESCENDANT_SIZE_LIMIT_KVB`). If an existing V3 transaction
>>> in the mempool is 100KvB, its descendant can only be 1000vB, even if
>>> the policy is 10KvB.
>>>
>>> **Package RBF modifications:**
>>>
>>> 1. The rule around unconfirmed inputs was
>>> originally "A package may include new unconfirmed inputs, but the
>>> ancestor feerate of the child must be at least as high as the ancestor
>>> feerates of every transaction being replaced."
>>>
>>> The package may still include new unconfirmed inputs. However,
>>> the new rule is modified to be "The minimum between package feerate
>>> and ancestor feerate of the child is not lower than the individual
>>> feerates of all directly conflicting transactions and the ancestor
>>> feerates of all original transactions."
>>>
>>> *Rationale*: We are attempting to ensure that the replacement
>>> transactions are not less incentive-compatible to mine. However, a
>>> package/transaction's ancestor feerate is not perfectly representative
>>> of its incentive compatibility; it may overestimate (some subset of
>>> the ancestors could be included by itself if it has other high-feerate
>>> descendants or are themselves higher feerate than this
>>> package/transaction). Instead, we use the minimum between the package
>>> feerate and ancestor feerate of the child as a more conservative value
>>> than what was proposed originally.
>>>
>>> 2. A new rule is added, requiring that all package transactions with
>>> mempool conflicts to be V3. This also means the "sponsoring"
>>> child transaction must be V3.
>>>
>>> *Note*: Combined with the V3 rules, this means the package must be
>>> a child-with-parents package. Since package validation is only
>>> attempted if the transactions do not pay sufficient fees to be
>>> accepted on their own, this effectively means that only V3
>>> transactions can pay to replace their ancestors' conflicts, and only
>>> V3 transactions' replacements may be paid for by a descendant.
>>>
>>> *Rationale*: The fee-related rules are economically rational for
>>> ancestor packages, but not necessarily other types of packages.
>>> A child-with-parents package is a type of ancestor package. It
>>> may be fine to allow any ancestor package, but it's more difficult
>>> to account for all of the possibilities. For example, it gets much
>>> harder to see that we're applying the descendant limits correctly if
>>> the package has a gnarly, many-generation, non-tree shape. I'm also
>>> not sure if this policy is 100% incentive-compatible if the sponsor
>>> is not a direct descendant of the sponsee.
>>>
>>> Please see doc/policy/version3_transactions.md and
>>> doc/policy/packages.md in the PR for the full set of rules.
>>>
>>> **Intended usage for LN:**
>>>
>>> Commitment transactions should be V3 and have 1 anchor output. They
>>> can be signed with 0 fees (or 1sat/vbyte) once package relay is deployed
>>> on a significant portion of the network. If the commitment tx must
>>> be broadcast, determine the desired feerate at broadcast time and
>>> spend the anchor output in a high feerate transaction. I'm going to
>>> call the broadcasted commitment tx "the parent" and the attached
>>> fee-bumping tx "the child."
>>>
>>> - This child must be V3.
>>> - This child must be at most 1000vB. Note this restricts the
>>>   number of inputs you can use to fund the fee bump. Depending
>>> on the output types, this is around 6-15.
>>> - One child may fund fees for multiple commitment tx ("batched
>>>   fee-bumping").
>>> - To do a second fee-bump to add more fees, replace the
>>>   *child* with a higher-feerate tx. Do not try to attach a grandchild.
>>>
>>> Otherwise, never try to spend from an unconfirmed V3 transaction. The
>>> descendant limits for V3 transactions are very restrictive.
>>>
>>> **Expected Questions:**
>>>
>>> "Does this fix Rule 3 Pinning?"
>>> Yes. The V3 descendant limit restricts both you and your counterparty.
>>> Assuming nodes adopted this policy, you may reasonably assume that you
>>> only need to replace the commitment transaction + up to 1000vB.
>>>
>>> "Only 1 anchor output? What if I need to bump counterparty's commitment
>>> tx in mempool?"
>>> You won't need to fee-bump a counterparty's commitment tx using CPFP.
>>> You would just package RBF it by attaching a high-feerate child to
>>> your commitment tx.
>>>
>>> "Is this a privacy issue, i.e. doesn't it allow fingerprinting LN
>>> transactions based on nVersion?"
>>> Indeed it may be unrealistic to assume V3 transactions will be in
>>> widespread use outside of L2. IIUC, unilateral closes are already
>>> obvious LN transactions because of the HTLC inputs. For e.g.
>>> cooperative closes and opens, I think it makes sense to continue using
>>> V2. So, unless I'm missing something, this shouldn't make it worse.
>>>
>>> "So a V3 transaction that doesn't signal BIP125 replaceability is
>>> replaceable? Is that a backward compatibility issue?"
>>> Yes it's replaceable. It's not an issue AFAICT because,
>>> under previous policy, the V3 transaction wouldn't have been
>>> in the mempool in the first place.
>>>
>>> "Can a V2 transaction replace a V3 transaction and vice versa?"
>>> Yes, otherwise someone can use V3 transactions to censor V2
>>> transactions spending shared inputs. Note if the
>>> original V3 transaction has an unconfirmed V3 parent, this would
>>> violate the "inherited V3" rule and would be rejected.
>>>
>>> Thanks for reading! Feedback and review would be much appreciated.
>>>
>>> [1]:
>>> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September/019464.html
>>> [2]:
>>> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019817.html
>>>
>>> Best,
>>> Gloria
>>> _______________________________________________
>>> bitcoin-dev mailing list
>>> [email-masked]
>>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>>
>> _______________________________________________
>> bitcoin-dev mailing list
>> [email-masked]
>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>
> _______________________________________________
> bitcoin-dev mailing list
> [email-masked]
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>