<oembed><type>rich</type><version>1.0</version><author_name>npub1q86n5vtxkwerzwfqza3hwls8pl8764244464talfqy2vpj0qaz6q38qwta</author_name><author_url>https://nostr.ae/npub1q86n5vtxkwerzwfqza3hwls8pl8764244464talfqy2vpj0qaz6q38qwta</author_url><provider_name>njump</provider_name><provider_url>https://nostr.ae</provider_url><html>📅 Original date posted:2020-09-18&#xA;📝 Original message:Hi Bitcoin Devs,&#xA;&#xA;&#xA;I&#39;d like to share with you a draft proposal for a mechanism to replace&#xA;CPFP and RBF for&#xA;increasing fees on transactions in the mempool that should be more&#xA;robust against attacks.&#xA;&#xA;A reference implementation demonstrating these rules is available&#xA;[here](https://github.com/bitcoin/bitcoin/compare/master...JeremyRubin:subsidy-tx)&#xA;for those who&#xA;prefer to not read specs.&#xA;&#xA;Should the mailing list formatting be bungled, it is also available as&#xA;a gist [here](https://gist.github.com/JeremyRubin/92a9fc4c6531817f66c2934282e71fdf).&#xA;&#xA;Non-Destructive TXID Dependencies for Fee Sponsoring&#xA;====================================================&#xA;&#xA;This BIP proposes a general purpose mechanism for expressing&#xA;non-destructive (i.e., not requiring&#xA;the spending of a coin) dependencies on specific transactions being in&#xA;the same block that can be&#xA;used to sponsor fees of remote transactions.&#xA;&#xA;Motivation&#xA;==========&#xA;&#xA;The mempool has a variety of protections and guards in place to ensure&#xA;that miners are economic and&#xA;to protect the network from denial of service.&#xA;&#xA;The rough surface of these policies has some unintended consequences&#xA;for second layer protocol&#xA;developers. Applications are either vulnerable to attacks (such as&#xA;transaction pinning) or must go&#xA;through great amounts of careful protocol engineering to guard against&#xA;known mempool attacks.&#xA;&#xA;This is insufficient because if new attacks are found, there is&#xA;limited ability to deploy fixes for&#xA;them against deployed contract instances (such as open lightning&#xA;channels). What is required is a&#xA;fully abstracted primitive that requires no special structure from an&#xA;underlying transaction in&#xA;order to increase fees to confirm the transactions.&#xA;&#xA;Consensus Specification&#xA;=======================&#xA;&#xA;If a transaction&#39;s last output&#39;s scripPubKey is of the form OP_VER&#xA;followed by n*32 bytes, where&#xA;n&gt;1, it is interpreted as a vector of TXIDs (Sponsor Vector). The&#xA;Sponsor Vector TXIDs  must also be&#xA;in the block the transaction is validated in, with no restriction on&#xA;order or on specifying a TXID&#xA;more than once. This can be accomplished simply with the following patch:&#xA;&#xA;&#xA;```diff&#xA;+&#xA;+    // Extract all required fee dependencies&#xA;+    std::unordered_set&lt;uint256, SaltedTxidHasher&gt; dependencies;&#xA;+&#xA;+    const bool dependencies_enabled = VersionBitsState(pindex-&gt;pprev,&#xA;chainparams.GetConsensus(),&#xA;Consensus::DeploymentPos::DEPLOYMENT_TXID_DEPENDENCY,&#xA;versionbitscache) == ThresholdState::ACTIVE;&#xA;+    if (dependencies_enabled) {&#xA;+        for (const auto&amp; tx : block.vtx) {&#xA;+            // dependency output is if the last output of a txn is&#xA;OP_VER followed by a sequence of 32*n&#xA;+            // bytes&#xA;+            // vout.back() must exist because it is checked in CheckBlock&#xA;+            const CScript&amp; dependencies_script = tx-&gt;vout.back().scriptPubKey;&#xA;+            // empty scripts are valid, so be sure we have at least one byte&#xA;+            if (dependencies_script.size() &amp;&amp; dependencies_script[0]&#xA;== OP_VER) {&#xA;+                const size_t size = dependencies_script.size() - 1;&#xA;+                if (size % 32 == 0 &amp;&amp; size &gt; 0) {&#xA;+                    for (auto start = dependencies_script.begin() +1,&#xA;stop = start + 32; start &lt; dependencies_script.end(); start = stop,&#xA;stop += 32) {&#xA;+                        uint256 txid;&#xA;+                        std::copy(start, stop, txid.begin());&#xA;+                        dependencies.emplace(txid);&#xA;+                    }&#xA;+                }&#xA;+                // No rules applied otherwise, open for future upgrades&#xA;+            }&#xA;+        }&#xA;+        if (dependencies.size() &gt; block.vtx.size()) {&#xA;+            return&#xA;state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,&#xA;&#34;bad-dependencies-too-many-target-txid&#34;);&#xA;+        }&#xA;+    }&#xA;+&#xA;     for (unsigned int i = 0; i &lt; block.vtx.size(); i++)&#xA;     {&#xA;         const CTransaction &amp;tx = *(block.vtx[i]);&#xA;+        if (!dependencies.empty()) {&#xA;+            dependencies.erase(tx.GetHash());&#xA;+        }&#xA;&#xA;         nInputs += tx.vin.size();&#xA;&#xA;@@ -2190,6 +2308,9 @@ bool CChainState::ConnectBlock(const CBlock&amp;&#xA;block, BlockValidationState&amp; state,&#xA;         }&#xA;         UpdateCoins(tx, view, i == 0 ? undoDummy :&#xA;blockundo.vtxundo.back(), pindex-&gt;nHeight);&#xA;     }&#xA;+    if (!dependencies.empty()) {&#xA;+        return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,&#xA;&#34;bad-dependency-missing-target-txid&#34;);&#xA;+    }&#xA;```&#xA;&#xA;### Design Motivation&#xA;The final output of a transaction is an unambiguous location to attach&#xA;metadata to a transaction&#xA;such that the data is available for transaction validation. This data&#xA;could be committed to anywhere,&#xA;with added implementation complexity, or in the case of Taproot&#xA;annexes, incompatibility with&#xA;non-Taproot addresses (although this is not a concern for sponsoring a&#xA;transaction that does not use&#xA;Taproot).&#xA;&#xA;A bare scriptPubKey prefixed with OP_VER is defined to be invalid in&#xA;any context, and is trivially&#xA;provably unspendable and therefore pruneable.&#xA;&#xA;If there is another convenient place to put the TXID vector, that&#39;s fine too.&#xA;&#xA;As the output type is non-standard, unupgraded nodes will by default&#xA;not include Transactions&#xA;containing them in the mempool, limiting risk of an upgrade via this mechanism.&#xA;&#xA;Policy Specification&#xA;====================&#xA;&#xA;The mechanism proposed above is a general specification for&#xA;inter-transaction dependencies.&#xA;&#xA;In this BIP, we only care to ensure a subset of behavior sufficient to&#xA;replace CPFP and RBF for fee&#xA;bumping.&#xA;&#xA;Thus we restrict the mempool policy such that:&#xA;&#xA;1. No Transaction with a Sponsor Vector may have any child spends; and&#xA;1. No Transaction with a Sponsor Vector may have any unconfirmed parents; and&#xA;1. The Sponsor Vector must have exactly 1 entry; and&#xA;1. The Sponsor Vector&#39;s entry must be present in the mempool; and&#xA;1. Every Transaction may have exactly 1 sponsor in the mempool; except&#xA;1. Transactions with a Sponsor Vector may not be sponsored.&#xA;&#xA;&#xA;The mempool treats ancestors and descendants limits as follows:&#xA;&#xA;1. Sponsors are counted as children transactions for descendants; but&#xA;1. Sponsoring transactions are exempted from any limits saturated at&#xA;the time of submission.&#xA;&#xA;This ensures that within a given package, every child transaction may&#xA;have a sponsor, but that the&#xA;mempool prefers to not accept new true children while there are&#xA;parents that can be cleared.&#xA;&#xA;To prevent garbage sponsors, we also require that:&#xA;&#xA;1. The Sponsor&#39;s feerate must be greater than the Sponsored&#39;s ancestor fee rate&#xA;&#xA;We allow one Sponsor to replace another subject to normal replacement&#xA;policies, they are treated as&#xA;conflicts.&#xA;&#xA;&#xA;### Design Motivation&#xA;&#xA;There are a few other ways to use OP_VER sponsors that are not&#xA;included. For instance, one could&#xA;make child chains that are only valid if their parent is in the same&#xA;block (this is incompatible&#xA;with CTV, exercise left to reader). These use cases are in a sense&#xA;incidental to the motivation&#xA;of this mechanism, and add a lot of implementation complexity.&#xA;&#xA;What is wanted is a minimal mechanism that allows arbitrary&#xA;unconnected third parties to attach&#xA;fees to an arbitrary transaction. The set of rules given tightly&#xA;bounds how much extra work the&#xA;mempool might have to do to account for the new sponsors in the worst&#xA;case, while providing a &#34;it&#xA;always works&#34; API for end users that is not subject to traditional&#xA;issues around pinning.&#xA;&#xA;Eventually, rational miners may wish to permit multiple sponsor&#xA;targets, or multiple sponsoring&#xA;transactions, but they are not required for the mechanism to work.&#xA;This is a benefit of the&#xA;minimality of the consensus rule, it is compatible with future policy&#xA;should it be implemented.&#xA;&#xA;&#xA;#### Attack Analysis of new Policy&#xA;&#xA;In the worst case the new policy can lead to a 1/2 reduction in the&#xA;number of children allowed&#xA;(e.g., if there are 13 children submitted, then 12 sponsors, the 25&#xA;child limit will saturate&#xA;before) and a 2x increase in the maximum children (e.g., if there are&#xA;25 children submitted, and&#xA;then each are sponsored). Importantly, even in the latter attack&#xA;scenario, the DoS surface is not&#xA;great because the sponsor transactions have no children nor parents.&#xA;&#xA;#### Package Relay/Orphan Pool&#xA;&#xA;Future policy work might be able to insert sponsors into a special&#xA;sponsor pool with an eviction&#xA;policy that would enable sponsors to be queried and tracked for&#xA;transactions that have too low fee&#xA;to enter the mempool in the first place. This is treated as a separate&#xA;concern, as any strides on&#xA;package relay generally should be able to support sponsors trivially.&#xA;&#xA;Reference Implementation&#xA;========================&#xA;A reference implementation demonstrating these rules is available&#xA;[here](https://github.com/bitcoin/bitcoin/compare/master...JeremyRubin:subsidy-tx).&#xA;This is a best&#xA;effort implementation, but has not been carefully audited for&#xA;correctness and likely diverges from&#xA;this document in ways that should either be reflected in this document&#xA;or amended in the code.&#xA;&#xA;&#xA;Best,&#xA;&#xA;Jeremy&#xA;&#xA;&#xA;&#xA;--&#xA;@JeremyRubin &lt;https://twitter.com/JeremyRubin&gt;&#xA;&lt;https://twitter.com/JeremyRubin&gt;&#xA;-------------- next part --------------&#xA;An HTML attachment was scrubbed...&#xA;URL: &lt;http://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20200918/5e8e4a42/attachment.html&gt;</html></oembed>