{"type":"rich","version":"1.0","title":"darosior [ARCHIVE] wrote","author_name":"darosior [ARCHIVE] (npub1pj…x22xp)","author_url":"https://yabu.me/npub1pj9022f74rzq7d5x7gnxje6wpsgk4r5jgeck8y5awd423ydhan3q7x22xp","provider_name":"njump","provider_url":"https://yabu.me","html":"📅 Original date posted:2022-03-12\n📝 Original message:The idea of a soft fork to fix dynamic fee bumping was recently put back on the table. It might\nsound radical, as what prevents today reasonable fee bumping for contracts with presigned\ntransactions (pinning) has to do with nodes' relay policy. But the frustration is understandable\ngiven the complexity of designing fee bumping with today's primitives. [0]\nRecently too, there was a lot of discussions around covenants. Covenants (conceptually, not talking\nabout any specific proposal) seem to open lots of new use cases and to be desired by (some?) Bitcoin\napplication developers and users.\nI think that fee bumping using covenants has attractive properties, and it requires a soft fork that\nis already desirable beyond (trying) to fix fee bumping. However i could not come up with a solution\nas neat for other protocols than vaults. I'd like to hear from others about 1) taking this route for\nfee bumping 2) better ideas on applying this to other protocols.\n\n\nIn a vault construction you have a UTxO which can only be spent by an Unvaulting transaction, whose\noutput triggers a timelock before the expiration of which a revocation transaction may be confirmed.\nThe revocation transaction being signed in advance (typically before sharing the signature for the\nUnvault transaction) you need fee bumping in order for the contract to actually be enforceable.\n\nNow, with a covenant you could commit to the revocation tx instead of presigning it. And using a\nTaproot tree you could commit to different versions of it with increasing feerate. Any network\nmonitor (the brooadcaster, a watchtower, ..) would be able to RBF the revocation transaction if it\ndoesn't confirm by spending using a leaf with a higher-feerate transaction being committed to.\n\nOf course this makes for a perfect DoS: it would be trivial for a miner to infer that you are using\na specific vault standard and guess other leaves and replace the witness to use the highest-feerate\nspending path. You could require a signature from any of the participants. Or, at the cost of an\nadditional depth, in the tree you could \"salt\" each leaf by pairing it with -say- an OP_RETURN leaf.\nBut this leaves you with a possible internal blackmail for multi-party contracts (although it's less\nof an issue for vaults, and not one for single-party vaults).\nWhat you could do instead is attaching an increasing relative timelock to each leaf (as the committed\nrevocation feerate increases, so does the timelock). You need to be careful to note wreck miner\nincentives here (see [0], [1], [2] on \"miner harvesting\"), but this enables the nice property of a\nfeerate which \"adapts\" to the block space market. Another nice property of this approach is the\nintegrated anti fee sniping protection if the revocation transaction pays a non-trivial amount of\nfees.\n\nPaying fees from \"shared\" funds instead of a per-watchtower fee-bumping wallet opened up the\nblackmail from the previous section, but the benefits of paying from internal funds shouldn't be\nunderstated.\nNo need to decide on an amount to be refilled. No need to bother the user to refill the fee-bumping\nwallet (before they can participate in more contracts, or worse before a deadline at which all\ncontracts are closed). No need for a potentially large amount of funds to just sit on a hot wallet\n\"just in case\". No need to duplicate this amount as you replicate the number of network monitors\n(which is critical to the security of such contracts).\nIn addition, note how modifying the feerate of the revocation transaction in place is less expensive\nthan adding a (pair of) new input (and output), let alone adding an entire new transaction to CPFP.\nAside, and less importantly, it can be made to work with today's relay rules (just use fee thresholds\nadapted to the current RBF thresholds, potentially with some leeway to account for policy changes).\nPaying from shared funds (in addition to paying from internal funds) also prevents pervert\nincentives for contracts with more than 2 parties. In case one of the parties breaches it, all\nremaining parties have an incentive to enforce the contract.. But only one would otherwise pay for\nit! It would open up the door to some potential sneaky techniques to wait for another party to pay\nfor the fees, which is at odd with the reactive security model.\n\nLet's examine how it could be concretely designed. Say you have a vault wallet software for a setup\nwith 5 participants. The revocation delay is 144 blocks. You assume revocation to be infrequent (if\none happens it's probably a misconfigured watchtower that needs be fixed before the next\nunvaulting), so you can afford infrequent overpayments and larger fee thresholds. Participants\nassume the vault will be spent within a year and assume a maximum possible feerate for this year of\n10ksat/vb.\nThey create a Taproot tree of depth 7. First leaf is the spending path (open to whomever the vault\npays after the 144 blocks). Then the leaf `i` for `i` in `[1, 127]` is a covenant to the revocation\ntransaction with a feerate `i * 79` sats/vb and a relative timelock of `i - 1` blocks.\nAssuming the covenant to the revocation transaction is 33 bytes [3], that's a witness of:\n    1 + 33     + 1 + 33 + 7 * 32 = 292 WU (73 vb)\n    ^^^^^^       ^^^^^^^^^^^^^^\n    witscript     control block\nfor any of the revocation paths. The revocation transaction is 1-input 1-output, so in total it's\n    10.5 +   41 + 73      + 43    = 167.5 vb\n    ^^^^    ^^^^^^^^^^^    ^^^^\n    header  input|witness  output\nThe transaction size is not what you'd necessarily want to optimize for first, still, it is smaller\nin this case than using other feebumping primitives and has a smaller footprint on the UTxO set. For\ninstance for adding a feebumping input and change output assuming all Taproot inputs and outputs\n(CPFP is necessarily even larger):\n    5 * 64 +  1 + 5 * (32 + 1) + 1 + 33 = 520 WU (105 vb)\n    ^^^^^^    ^^^^^^^^^^^^^^^    ^^^^^^\n    witness      witscript       control\n    10.5  +  41 + 105      + 41 + 16.5         + 2 * 43  = 300 vb\n    ^^^^     ^^^^^^^^        ^^^^^^^^^           ^^^^^^\n    header   input|witness   fb input|witness    outputs\n\u003eFrom there, you can afford more depths at the tiny cost of 8 more vbytes each. You might want them\nfor:\n- more granularity (if you can afford large enough timelocks)\n- optimizing for the spending path rather than the revocation one\n- adding a hashlock to prevent nuisance (with the above script a third party could malleate a\n  spending path into a revocation one). You can use the OP_RETURN trick from above to prevent that.\n\nUnfortunately, the timelocked-covenant approach to feebumping only applies to bumping the first\ntransaction of a chain (you can't pay for the parent with a timelock) so for instance it's not\nusable for HTLC transactions in Lightning to bump the parent commitment tx. The same goes for\nbumping the update tx in Coinpool.\nIt could be worked around by having a different covenant per participant (paying the fee from either\nof the participants' output) behind a signature check. Of course it requires funds to already be in\nthe contract (HTLC, Coinpool leaf) to pay for your own unilateral close, but if you don't have any\nfund in the contract it doesn't make sense to try to feebump it in the first place. The same goes\nfor small amounts: you'd only allocate up to the value of the contract (minus a dust preference) in\nfees in order to enforce it.\nThis is less nice for external monitors as it requires a private key (or another secret) to be\ncommitted to in advance) to be able to bump [4] and does not get rid of the \"who's gonna pay for the\nenforcement\" issue in \u003e2-parties contracts. Still, it's more optimal and usable than CPFP or adding\na pair of input/output for all the reasons mentioned above.\n\n\nThoughts?\nAntoine\n\n\n[0] https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-November/019614.html\n[1] https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-November/019615.html\n[2] https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-December/019627.html\n[3] That's obviously close to the CTV construction. But using another more flexible (and therefore\n    less optimized) construction would not be a big deal. It might in fact be necessary for more\n    elaborated (realistic?) usecases than the simple one detailed here.\n[4] https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-February/019879.html"}
