<oembed><type>rich</type><version>1.0</version><title>Lloyd Fournier [ARCHIVE] wrote</title><author_name>Lloyd Fournier [ARCHIVE] (npub1kh…y05yp)</author_name><author_url>https://yabu.me/npub1khlhcuz0jrjwa0ayznq2q9agg4zvxfvx5x7jljrvwnpfzngrcf0q7y05yp</author_url><provider_name>njump</provider_name><provider_url>https://yabu.me</provider_url><html>📅 Original date posted:2021-06-06&#xA;📝 Original message:Hi Antione,&#xA;&#xA;Thanks for bringing up this important topic. I think there might be another&#xA;class of solutions over input based, CPFP and sponsorship. I&#39;ll call them&#xA;tx mutation schemes. The idea is that you can set a key that can increase&#xA;the fee by lowering a particular output after the tx is signed without&#xA;invalidating the signature. The premise is that anytime you need to bump&#xA;the fee of a transaction you must necessarily have funds in an output that&#xA;are going to you and therefore you can sacrifice some of them to increase&#xA;the fee. This is obviously destructive to txids so child presigned&#xA;transactions will have to use ANYPREVOUT as in your proposal. The advantage&#xA;is that it does not require keeping extra inputs around to bump the fee.&#xA;&#xA;So imagine a new opcode OP_CHECKSIG_MUTATED &lt;output index&gt; &lt;publickey&gt;&#xA;&lt;value&gt; &lt;signature&gt;.&#xA;This would check that &lt;signature&gt; is valid against &lt;publickey&gt; if the&#xA;current transaction had the output at &lt;output index&gt; reduced by &lt;value&gt;. To&#xA;make this more efficient, if the public key is one byte: 0x02 it references&#xA;the taproot *external key* (similar to how ANYPREVOUT uses 0x01 to refer to&#xA;internal key[1]).&#xA;Now for our protocol we want both parties (p1 and p2) to be able to fee&#xA;bump a commitment transaction. They use MuSig to sign the commitment tx&#xA;under the external key with a decent fee for the current conditions. But in&#xA;case it proves insufficient they have added the following two leaves to&#xA;their key in the funding output as a backup so that p1 and p2 can&#xA;unilaterally bump the fee of anything they sign spending from the funding&#xA;output:&#xA;&#xA;1. OP_CHECKSIG_MUTATED(0, 0x02, &lt;fee-bump-value&gt;, &lt;original-signature&gt;)&#xA;OP_CHECKSIGADD(p1-fee-bump-key, &lt;p1-fee-bump-signature&gt;)  OP_2&#xA;OP_NUMEQUALVERIFY&#xA;2. OP_CHECKSIG_MUTATED(1, 0x02, &lt;fee-bump-value&gt;, &lt;original-signature&gt;)&#xA;OP_CHECKSIGADD(p2-fee-bump-key, &lt;p2-fee-bump-signature&gt;) OP_2&#xA;OP_NUMEQUALVERIFY&#xA;&#xA;where &lt;...&gt; indicates the thing comes from the witness stack.&#xA;So to bump the fee of the commit tx after it has been signed either party&#xA;takes the &lt;original-signature&gt; and adds a signature under their&#xA;fee-bump-key for the new tx and reveals their fee bump leaf.&#xA;&lt;original-signature&gt; is checked against the old transaction while the fee&#xA;bumped transaction is checked against the fee bump key.&#xA;&#xA;I know I have left out how to change mempool eviction rules to accommodate&#xA;this kind of fee bumping without DoS or pinning attacks but hopefully I&#xA;have demonstrated that this class of solutions also exists.&#xA;&#xA;[1] https://github.com/ajtowns/bips/blob/bip-anyprevout/bip-0118.mediawiki&#xA;&#xA;Cheers,&#xA;&#xA;LL&#xA;&#xA;&#xA;&#xA;On Fri, 28 May 2021 at 07:13, Antoine Riard via bitcoin-dev &lt;&#xA;bitcoin-dev at lists.linuxfoundation.org&gt; wrote:&#xA;&#xA;&gt; Hi,&#xA;&gt;&#xA;&gt; This post is pursuing a wider discussion around better fee-bumping&#xA;&gt; strategies for second-layer protocols. It draws out a comparison between&#xA;&gt; input-based and CPFP fee-bumping techniques, and their apparent trade-offs&#xA;&gt; in terms of onchain footprint, tx-relay bandwidth rebroadcast, batching&#xA;&gt; opportunity and mempool flexibility.&#xA;&gt;&#xA;&gt; Thanks to Darosior for reviews, ideas and discussions.&#xA;&gt;&#xA;&gt; ## Child-Pay-For-Parent&#xA;&gt;&#xA;&gt; CPFP is a mature fee-bumping technique, known and used for a while in the&#xA;&gt; Bitcoin ecosystem. However, its usage in contract protocols with&#xA;&gt; distrusting counterparties raised some security issues. As mempool&#39;s chain&#xA;&gt; of unconfirmed transactions are limited in size, if any output is spendable&#xA;&gt; by any contract participant, it can be leveraged as a pinning vector to&#xA;&gt; downgrade odds of transaction confirmation [0].&#xA;&gt;&#xA;&gt; That said, contract transactions interested to be protected under the&#xA;&gt; carve-out logic require to add a new output for any contract participant,&#xA;&gt; even if ultimately only one of them serves as an anchor to attach a CPFP.&#xA;&gt;&#xA;&gt; ## Input-Based&#xA;&gt;&#xA;&gt; I think input-based fee-bumping has been less studied as fee-bumping&#xA;&gt; primitive for L2s [1]. One variant of input-based fee-bumping usable today&#xA;&gt; is the leverage of the SIGHASH_ANYONECANPAY/SIGHASH_SINGLE malleability&#xA;&gt; flags. If the transaction is the latest stage of the contract, a bumping&#xA;&gt; input can be attached just-in-time, thus increasing the feerate of the&#xA;&gt; whole package.&#xA;&gt;&#xA;&gt; However, as of today, input-based fee-bumping doesn&#39;t work to bump first&#xA;&gt; stages of contract transactions as it&#39;s destructive of the txid, and as&#xA;&gt; such breaks chain of pre-signed transactions. A first improvement would be&#xA;&gt; the deployment of the SIGHASH_ANYPREVOUT softfork proposal. This new&#xA;&gt; malleability flag allows a transaction to be signed without reference to&#xA;&gt; any specific previous output. That way,  spent transactions can be&#xA;&gt; fee-bumped without altering validity of the chain of transactions.&#xA;&gt;&#xA;&gt; Even assuming SIGHASH_ANYPREVOUT, if the first stage contract transaction&#xA;&gt; includes multiple outputs (e.g the LN&#39;s commitment tx has multiple HTLC&#xA;&gt; outputs), SIGHASH_SINGLE can&#39;t be used and the fee-bumping input value&#xA;&gt; might be wasted. This edge can be smoothed by broadcasting a preliminary&#xA;&gt; fan-out transaction with a set of outputs providing a range of feerate&#xA;&gt; points for the bumped transaction.&#xA;&gt;&#xA;&gt; This overhead could be smoothed even further in the future with more&#xA;&gt; advanced sighash malleability flags like SIGHASH_IOMAP, allowing&#xA;&gt; transaction signers to commit to a map of inputs/outputs [2]. In the&#xA;&gt; context of input-based, the overflowed fee value could be redirected to an&#xA;&gt; outgoing output.&#xA;&gt;&#xA;&gt; ## Onchain Footprint&#xA;&gt;&#xA;&gt; CPFP: One anchor output per participant must be included in the commitment&#xA;&gt; transaction. To this anchor must be attached a child transaction with 2&#xA;&gt; inputs (one for the commitment, one for the bumping utxo) and 1 output.&#xA;&gt; Onchain footprint: 2 inputs + 3 outputs.&#xA;&gt;&#xA;&gt; Input-based (today): If the bumping utxo is offering an adequate feerate&#xA;&gt; point in function of network mempools congestion at time of broadcast, only&#xA;&gt; 1 input. If a preliminary fan-out transaction to adjust feerate point must&#xA;&gt; be broadcasted first, 1 input and 2 outputs more must be accounted for.&#xA;&gt; Onchain footprint: 2 inputs + 3 outputs.&#xA;&gt;&#xA;&gt; Input-based (SIGHASH_ANYPREVOUT+SIGHASH_IOMAP): As long as the bumping&#xA;&gt; utxo&#39;s value is wide enough to cover the worst-case of mempools congestion,&#xA;&gt; the bumped transaction can be attached 1 input and 1 output. Onchain&#xA;&gt; footprint: 1 input + 1 output.&#xA;&gt;&#xA;&gt; ## Tx-Relay Bandwidth Rebroadcast&#xA;&gt;&#xA;&gt; CPFP: In the context of multi-party protocols, we should assume bounded&#xA;&gt; rationality of the participants w.r.t to an unconfirmed spend of the&#xA;&gt; contract utxo across network mempools. Under this assumption, the bumped&#xA;&gt; transaction might have been replaced by a concurrent state. To guarantee&#xA;&gt; efficiency of the CPFP the whole chain of transactions should be&#xA;&gt; rebroadcast, perhaps wasting bandwidth consumption for a still-identical&#xA;&gt; bumped transaction [3]. Rebroadcast footprint: the whole chain of&#xA;&gt; transactions.&#xA;&gt;&#xA;&gt; Input-based (today): In case of rebroadcast, the fee-bumping input is&#xA;&gt; attached to the root of the chain of transactions and as such breaks the&#xA;&gt; chain validity in itself. Beyond the rebroadcast of the updated root under&#xA;&gt; replacement policy, the remaining transactions must be updated and&#xA;&gt; rebroadcast. Rebroadcast footprint: the whole chain of transactions.&#xA;&gt;&#xA;&gt; Input-based(SIGHASH_ANYPREVOUT+SIGHASH_IOMAP): In case of rebroadcast, the&#xA;&gt; fee-bumping is attached to the root of the chain of transactions but it&#xA;&gt; doesn&#39;t break the chain validity in itself. Assuming a future mempool&#xA;&gt; acceptance logic to authorize in-place substitution, the rest of the chain&#xA;&gt; could be preserved. Rebroadcast footprint: the root of the chain of&#xA;&gt; transactions.&#xA;&gt;&#xA;&gt; ## Fee-Bumping Batching&#xA;&gt;&#xA;&gt; CPFP: In the context of multi-party protocols, in optimistic scenarios, we&#xA;&gt; can assume aggregation of multiple chains of transactions. For e.g, a LN&#xA;&gt; operator is desirous to non-cooperatively close multiple channels at the&#xA;&gt; same time and would like to combine their fee-bumping. With CPFP, one&#xA;&gt; anchor output and one bumping input must be consumed per aggregated chain,&#xA;&gt; even if the child transaction fields can be shared. Batching perf: 1&#xA;&gt; input/1 output per aggregated chain.&#xA;&gt;&#xA;&gt; Input-based (today): Unless the contract allows interactivity, multiple&#xA;&gt; chains of transactions cannot be aggregated. One bumping input must be&#xA;&gt; attached per chain, though if a preliminary fan-out transaction is relied&#xA;&gt; on to offer multiple feerate points, transaction fields can be shared.&#xA;&gt; Batching perf: 1 input/1 output per aggregated chain.&#xA;&gt;&#xA;&gt; Input-based (SIGHASH_ANYPREVOUT+SIGHASH_IOMAP): Multiple chains of&#xA;&gt; transactions might be aggregated together *non-interactively*. One bumping&#xA;&gt; input and outgoing output can be attached to the aggregated root. Batching&#xA;&gt; perf: 1 input/1 output per aggregation.&#xA;&gt;&#xA;&gt; ## Fee-Bumping Mempool Flexibility&#xA;&gt;&#xA;&gt; CPFP: In the context of multi-party protocols, one of your counterparties&#xA;&gt; might build a branch of transactions from one of the root outputs thus&#xA;&gt; saturating the in-mempool package limits. To avoid these shenanigans, LN&#xA;&gt; channels are relying on the carve-out mechanism. Though, the carve-out&#xA;&gt; mechanism includes its own limitation and doesn&#39;t scale beyond 2 contract&#xA;&gt; participants.&#xA;&gt;&#xA;&gt; Input-based: The root of the chain of transaction is the package&#39;s oldest&#xA;&gt; ancestor, so package limits don&#39;t restrain its acceptance and it works&#xA;&gt; whatever the number of contract participants.&#xA;&gt;&#xA;&gt; To conclude, this post scores 2 fee-bumping primitives for multi-party&#xA;&gt; protocols on a range of factors. It hopes to unravel the ground for a real&#xA;&gt; feerate performance framework of second-layers protocols .&#xA;&gt;&#xA;&gt; Beyond that, few points can be highlighted a) future soft forks allow&#xA;&gt; significant onchain footprint savings, especially in case of batching, b)&#xA;&gt; future package relay bandwidth efficiency should account for rebroadcast&#xA;&gt; frequency of CPFPing multi-party protocols. On this latter point one&#xA;&gt; follow-up might be to evaluate differing package relay *announcement*&#xA;&gt; schemes in function of odds of non-cooperative protocol broadcast/odds of&#xA;&gt; concurrent broadcast/rebroadcast frequencies.&#xA;&gt;&#xA;&gt; Thoughts ?&#xA;&gt;&#xA;&gt; Cheers,&#xA;&gt; Antoine&#xA;&gt;&#xA;&gt; [0]&#xA;&gt; https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-November/016518.html&#xA;&gt; [1] Beyond the revault architecture :&#xA;&gt; https://github.com/revault/practical-revault/blob/master/revault.pdf&#xA;&gt; [2] Already proposed a while back :&#xA;&gt; https://bitcointalk.org/index.php?topic=252960.0&#xA;&gt; [3] In theory, an already-relayed transaction shouldn&#39;t pass Core&#39;s&#xA;&gt; `filterInventoryKnown`. In practice, if the transaction is announced as&#xA;&gt; part of a package_id, the child might have changed, not the parent, leading&#xA;&gt; to a redundant relay of the latter.&#xA;&gt; _______________________________________________&#xA;&gt; bitcoin-dev mailing list&#xA;&gt; bitcoin-dev at lists.linuxfoundation.org&#xA;&gt; https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev&#xA;&gt;&#xA;-------------- next part --------------&#xA;An HTML attachment was scrubbed...&#xA;URL: &lt;http://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20210607/49ff1a08/attachment.html&gt;</html></oembed>