Re: [bitcoin-dev] Why Full-RBF Makes DoS Attacks on Multiparty Protocols Significantly More Expensive
On 2023-01-09 12:18, Peter Todd via bitcoin-dev wrote: [The quote:] "Does fullrbf offer any benefits other than breaking zeroconf business practices?" ...has caused a lot of confusion by implying that there were no benefits. [...] tl;dr: without full-rbf people can intentionally and unintentionally DoS attack multi-party protocols by double-spending their inputs with low-fee txs, holding up progress until that low-fee tx gets mined. Hi Peter, I'm confused. Isn't this an easily solvable issue without full-RBF? Let's say Alice, Bob, Carol, and Mallory create a coinjoin transaction. Mallory either intentionally or unintentionally creates a conflicting transaction that does not opt-in to RBF. You seem to be proposing that the other participants force the coinjoin to complete by having the coinjoin transaction replace Mallory's conflicting transaction, which requires a full-RBF world. But isn't it also possible in a non-full-RBF world for Alice, Bob, and Carol to simply create a new coinjoin transaction which does not include any of Mallory's inputs so it doesn't conflict with Mallory's transaction? That way their second coinjoin transaction can confirm independently of Mallory's transaction. Likewise, if Alice and Mallory attempt an LN dual funding and Mallory creates a conflict, Alice can just create an alternative dual funding with Bob rather than try to use full-RBF to force Mallory's earlier dual funding to confirm. ## Transaction Pinning Exploiting either rule is expensive. I think this transaction pinning attack against coinjoins and dual fundings is also solved in a non-full-RBF world by the honest participants just creating a non-conflicting transaction. That said, if I'm missing something and these attacks do actually apply, then it might be worth putting price figures on the attack in terms most people will understand. The conflicting inputs attack you described in the beginning as being solved by full-RBF costs about $0.05 USD at $17,000/BTC. The transaction pinning attack you imply is unsolved by full-RBF costs about $17.00. If both attacks apply, any protocol which is vulnerable to a $17.00 attack still seems highly vulnerable to me, so it doesn't feel like a stretch to say that full-RBF lacks significant benefits for those protocols. Thanks, -Dave ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
[bitcoin-dev] Why Full-RBF Makes DoS Attacks on Multiparty Protocols Significantly More Expensive
I was reminded recently that while Suhas Daftuar cited tx-pinning as a reason to remove full-rbf, he neglected to mention that tx-pinning greatly increases the cost of attacks on multi-party protocols. Him (rhetorically?) asking(4): "Does fullrbf offer any benefits other than breaking zeroconf business practices?" ...has caused a lot of confusion by implying that there were no benefits. So I'm writing this to set the record straight and provide an easily cited explanation as to why full-rbf - even with tx-pinning - is a valuable improvement for multi-party protocols like coinjoins that rely on transactions containing multiple inputs exclusively controlled(1) by different parties. tl;dr: without full-rbf people can intentionally and unintentionally DoS attack multi-party protocols by double-spending their inputs with low-fee txs, holding up progress until that low-fee tx gets mined. This could take days, weeks, or even worse. Modulo intentional tx-pinning, full-RBF fixes this by ensuring that a higher fee transaction gets mined in a reasonable amount of time so the protocol makes forward progress. And as for tx-pinning, exploiting it is very expensive, so full-rbf still makes the situation much better than the status quo. # The Double-Spend DoS Attack on Multi-Party, Multi-Input, Transactions If a protocol constructs transactions containing multiple inputs exclusively controlled by different parties, those parties can intentionally and unintentionally double-spend those inputs in alternate transactions. For example, in a Wasabi coinjoin any one of the hundreds of participants could sign and broadcast a transaction spending their input. If they do that at the right time, as much as ~100% of the hashing power may see the double-spend first, prior to the intended coinjoin transaction. This in fact does happen regularly in production to Wasabi coinjoins, probably due to people accidentally running different wallets at the same time using the same seed, as well as people importing their seeds into alternative wallets. By itself this isn't a significant problem: Wasabi coinjoins are a two phase protocol, and, like any multi-step, multi-party protocol, they have to deal with the fact that participants in the protocol may fail to complete all the steps necessary for a transaction to be completed. It's very common for one or more parties in a Wasabi coinjoin to fail to complete both steps of the protocol, and a majority of Wasabi coinjoin rounds fail. Wasabi deals with this economically by (temporarily or ~permanently) blacklisting UTXOs that failed to complete a round, making DoS attacks expensive by forcing the attacker to tie up funds/create new UTXOs. Similarly, in use-cases such as multi-party-funded Lightning channels(5), an attacker can always DoS attack the protocol by participating in a channel open, and then failing to allow payments to be routed through it. The solution is again to use economics to ensure the attack is sufficiently costly. However, under the right circumstances double-spends are an unusually powerful DoS attack on multi-party, multi-input, transaction. When mempool demand is high, low fee transactions can take arbitrarily long to get mined. Bitcoin has seen periods of mempool demand where low-fee transactions would take *months* to get mined. Transaction expiry does not solve this problem, as anyone can rebroadcast transactions at any time. In these circumstances without transaction replacement a multi-party transaction such as a Wasabi coinjoin could be held up indefinitely by a low-fee double-spend. ## How Full-RBF Mitigates the Double-Spend DoS Attack Modulo tx-pinning, full-rbf mitigates the double-spend DoS attack in a very straightforward way: the low fee transaction is replaced by the higher fee transaction, resulting in the latter getting mined in a reasonable amount of time and the protocol making forward progress. Note that the converse is not a useful attack: if the attacker broadcasts a high-fee double spend, higher than the intended multi-party transaction, the transaction will get mined in a reasonable amount of time, costing the attacker money and the defender nothing beyond wasted time. Multi-party protocols always have the property that attackers can spend money to DoS attack by creating more UTXOs/identities/etc, so this isn't any worse than the status quo! ## Transaction Pinning So what about transaction pinning? The term actually refers to a few different techniques that can make it difficult/expensive to fee-bump a transaction. We're interested in the techniques relevant to replacements, namely exploitation of: 1. BIP-125 RBF Rule #3: a replacement transaction is required to pay the higher absolute fee (not just fee rate) than the sum of fees paid by all transactions being replaced. 2. BIP-125 RBF Rule #5: the number of transactions replaced at one time must not exceed 100. Note that this rule only exists due to limitations of the existing
Re: [bitcoin-dev] OP_VAULT: a new vault proposal
Hey Greg, I think what you're trying to get at here is that the OP_UNVAULT scriptPubKey *must* be a bare script so that the OP_VAULT spend logic can verify that we're spending an OP_VAULT output into a compatible OP_UNVAULT output, and that's true. The OP_UNVAULT scriptPubKey also must contain the target hash because that has is used when validating that spend to ensure that the final unvault target matches what was advertised when the OP_UNVAULT output was created. So I'm not sure what problem you're trying to solve by putting the target hash on the OP_VAULT spend witness stack. If it were placed there, it wouldn't be accessible during OP_UNVAULT spend AFAICT. I agree it would be nice to figure out a way to allow the OP_UNVAULT scriptPubKey to not be bare, which may require moving the target hash out of it, but we'd have to figure out a mechanism to properly forward the target hash for validation. Best, James On Mon, Jan 9, 2023 at 2:32 PM Greg Sanders wrote: > Hi James and co, > > Currently there is no way to make this compatible with scripthashes of any > kind, since the script interpreter has no insight into the OP_UNVAULT > outputs' "execution script", and one of the arguments of OP_UNVAULT is > freeform, resulting in an unpredictable output scriptpubkey. > > I think the fix is just requiring a single additional witness data item > during OP_VAULT spend(for unvault path), mandating the > to be included in the witness stack as an input to > OP_VAULT opcode, and transaction introspection then checks to make sure the > witness item and the corresponding output script template matches the > expected. > > This would only be necessary for the unvaulting path, and not for the > recovery path. > > Cheers, > Greg > > On Mon, Jan 9, 2023 at 2:10 PM rot13maxi via bitcoin-dev < > bitcoin-dev@lists.linuxfoundation.org> wrote: > >> Hey James, >> >> Really cool proposal. I’ve been thinking a lot lately about script paths >> for inheritance. In a lot of the “have a relative time lock that allows a >> different key to spend coins, or allows a smaller threshold of a multisig >> to spend” schemes, you have the problem of needing to “refresh” all of your >> coins when the timelock is close to maturation. In a lot of the “use >> multisig with ephemeral keys to emulate covenants” schemes, you have to >> pre-commit to the terminal destination well in advance of the spend-path >> being used, which leads to all kinds of thorny questions about security and >> availability of *those* keys. In other words, you either have to have >> unbound destinations but a timer that needs resetting, or you have unbound >> time but fixed destinations. This design gets you the best of both because >> the destination SPKs aren’t committed to until the unvaulting process >> starts. This (or something like this with destination binding at >> unvault-time) would be an incredibly useful tool for inheritance designs in >> wallets. >> >> I need to think a bit more about the recovery path not having any real >> encumbrances on it. Maybe in practice if you’re worried about DoS, you have >> UTXOs that commit to multiple vault paths that have tweaked recovery >> destinations or something, or maybe it really is the right move to say that >> if recovery is triggered, you probably do want it for all of your inflight >> unvaultings. >> >> Looking forward to reading this a few more times and talking more about >> it. >> >> Thanks! >> rijndael >> >> >> On Mon, Jan 9, 2023 at 11:07 AM, James O'Beirne via bitcoin-dev < >> bitcoin-dev@lists.linuxfoundation.org> wrote: >> >> For the last few years, I've been interested in vaults as a way to >> substantially derisk custodying Bitcoin, both at personal and commercial >> scales. Instead of abating with familiarity, as enthusiasm sometimes >> does, my conviction that vaults are an almost necessary part of bitcoin's >> viability has only grown over the years. >> >> Since people first started discussing vaults, it's been pretty clear that >> some kind of covenant-enabling consensus functionality is necessary to >> provide the feature set necessary to make vault use practical. >> >> Earlier last year I experimented with using OP_CTV[1], a limited covenant >> mechanism, to implement a "minimum-viable" vault design. I found that the >> inherent limitations of a precomputed covenant scheme left the resulting >> vault implementation wanting, even though it was an improvement over >> existing strategies that rely on presigned transactions and (hopefully) >> ephemeral keys. >> >> But I also found proposed "general" covenant schemes to be >> unsuitable for this use. The bloated scriptPubKeys, both in size and >> complexity, that would result when implementing something like a vault >> weren't encouraging. Also importantly, the social-consensus quagmire >> regarding which covenant proposal to actually deploy feels at times >> intractable. >> >> As a result, I wanted to explore a middle way: a design solely concerned >>
Re: [bitcoin-dev] OP_VAULT: a new vault proposal
Hi James and co, Currently there is no way to make this compatible with scripthashes of any kind, since the script interpreter has no insight into the OP_UNVAULT outputs' "execution script", and one of the arguments of OP_UNVAULT is freeform, resulting in an unpredictable output scriptpubkey. I think the fix is just requiring a single additional witness data item during OP_VAULT spend(for unvault path), mandating the to be included in the witness stack as an input to OP_VAULT opcode, and transaction introspection then checks to make sure the witness item and the corresponding output script template matches the expected. This would only be necessary for the unvaulting path, and not for the recovery path. Cheers, Greg On Mon, Jan 9, 2023 at 2:10 PM rot13maxi via bitcoin-dev < bitcoin-dev@lists.linuxfoundation.org> wrote: > Hey James, > > Really cool proposal. I’ve been thinking a lot lately about script paths > for inheritance. In a lot of the “have a relative time lock that allows a > different key to spend coins, or allows a smaller threshold of a multisig > to spend” schemes, you have the problem of needing to “refresh” all of your > coins when the timelock is close to maturation. In a lot of the “use > multisig with ephemeral keys to emulate covenants” schemes, you have to > pre-commit to the terminal destination well in advance of the spend-path > being used, which leads to all kinds of thorny questions about security and > availability of *those* keys. In other words, you either have to have > unbound destinations but a timer that needs resetting, or you have unbound > time but fixed destinations. This design gets you the best of both because > the destination SPKs aren’t committed to until the unvaulting process > starts. This (or something like this with destination binding at > unvault-time) would be an incredibly useful tool for inheritance designs in > wallets. > > I need to think a bit more about the recovery path not having any real > encumbrances on it. Maybe in practice if you’re worried about DoS, you have > UTXOs that commit to multiple vault paths that have tweaked recovery > destinations or something, or maybe it really is the right move to say that > if recovery is triggered, you probably do want it for all of your inflight > unvaultings. > > Looking forward to reading this a few more times and talking more about > it. > > Thanks! > rijndael > > > On Mon, Jan 9, 2023 at 11:07 AM, James O'Beirne via bitcoin-dev < > bitcoin-dev@lists.linuxfoundation.org> wrote: > > For the last few years, I've been interested in vaults as a way to > substantially derisk custodying Bitcoin, both at personal and commercial > scales. Instead of abating with familiarity, as enthusiasm sometimes > does, my conviction that vaults are an almost necessary part of bitcoin's > viability has only grown over the years. > > Since people first started discussing vaults, it's been pretty clear that > some kind of covenant-enabling consensus functionality is necessary to > provide the feature set necessary to make vault use practical. > > Earlier last year I experimented with using OP_CTV[1], a limited covenant > mechanism, to implement a "minimum-viable" vault design. I found that the > inherent limitations of a precomputed covenant scheme left the resulting > vault implementation wanting, even though it was an improvement over > existing strategies that rely on presigned transactions and (hopefully) > ephemeral keys. > > But I also found proposed "general" covenant schemes to be > unsuitable for this use. The bloated scriptPubKeys, both in size and > complexity, that would result when implementing something like a vault > weren't encouraging. Also importantly, the social-consensus quagmire > regarding which covenant proposal to actually deploy feels at times > intractable. > > As a result, I wanted to explore a middle way: a design solely concerned > with making the best vault use possible, with covenant functionality as a > secondary consideration. In other words, a proposal that would deliver > the safety benefits of vaults to users without getting hung up on > trying to solve the general problem of covenants. > > At first this design, OP_VAULT, was just sort of a pipe dream. But as I > did more thinking (and eventually implementing) I became more convinced > that, even if it isn't considered for soft-fork, it is a worthwhile > device to serve as a standard benchmark against which other proposals > might be judged. > > I wrote a paper that summarizes my findings and the resulting proposal: > https://jameso.be/vaults.pdf > > along with an accompanying draft implementation: > https://github.com/bitcoin/bitcoin/pull/26857 > > I might work on a BIP if there's interest. > > James > > [1]: https://github.com/jamesob/simple-ctv-vault > > ___ > bitcoin-dev mailing list > bitcoin-dev@lists.linuxfoundation.org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev >
Re: [bitcoin-dev] OP_VAULT: a new vault proposal
Hey James, Really cool proposal. I’ve been thinking a lot lately about script paths for inheritance. In a lot of the “have a relative time lock that allows a different key to spend coins, or allows a smaller threshold of a multisig to spend” schemes, you have the problem of needing to “refresh” all of your coins when the timelock is close to maturation. In a lot of the “use multisig with ephemeral keys to emulate covenants” schemes, you have to pre-commit to the terminal destination well in advance of the spend-path being used, which leads to all kinds of thorny questions about security and availability of *those* keys. In other words, you either have to have unbound destinations but a timer that needs resetting, or you have unbound time but fixed destinations. This design gets you the best of both because the destination SPKs aren’t committed to until the unvaulting process starts. This (or something like this with destination binding at unvault-time) would be an incredibly useful tool for inheritance designs in wallets. I need to think a bit more about the recovery path not having any real encumbrances on it. Maybe in practice if you’re worried about DoS, you have UTXOs that commit to multiple vault paths that have tweaked recovery destinations or something, or maybe it really is the right move to say that if recovery is triggered, you probably do want it for all of your inflight unvaultings. Looking forward to reading this a few more times and talking more about it. Thanks! rijndael On Mon, Jan 9, 2023 at 11:07 AM, James O'Beirne via bitcoin-dev wrote: > For the last few years, I've been interested in vaults as a way to > substantially derisk custodying Bitcoin, both at personal and commercial > scales. Instead of abating with familiarity, as enthusiasm sometimes > does, my conviction that vaults are an almost necessary part of bitcoin's > viability has only grown over the years. > > Since people first started discussing vaults, it's been pretty clear that > some kind of covenant-enabling consensus functionality is necessary to > provide the feature set necessary to make vault use practical. > > Earlier last year I experimented with using OP_CTV[1], a limited covenant > mechanism, to implement a "minimum-viable" vault design. I found that the > inherent limitations of a precomputed covenant scheme left the resulting > vault implementation wanting, even though it was an improvement over > existing strategies that rely on presigned transactions and (hopefully) > ephemeral keys. > > But I also found proposed "general" covenant schemes to be > unsuitable for this use. The bloated scriptPubKeys, both in size and > complexity, that would result when implementing something like a vault > weren't encouraging. Also importantly, the social-consensus quagmire > regarding which covenant proposal to actually deploy feels at times > intractable. > > As a result, I wanted to explore a middle way: a design solely concerned > with making the best vault use possible, with covenant functionality as a > secondary consideration. In other words, a proposal that would deliver > the safety benefits of vaults to users without getting hung up on > trying to solve the general problem of covenants. > > At first this design, OP_VAULT, was just sort of a pipe dream. But as I > did more thinking (and eventually implementing) I became more convinced > that, even if it isn't considered for soft-fork, it is a worthwhile > device to serve as a standard benchmark against which other proposals > might be judged. > > I wrote a paper that summarizes my findings and the resulting proposal: > https://jameso.be/vaults.pdf > > along with an accompanying draft implementation: > https://github.com/bitcoin/bitcoin/pull/26857 > > I might work on a BIP if there's interest. > > James > [1]: https://github.com/jamesob/simple-ctv-vault___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
[bitcoin-dev] OP_VAULT: a new vault proposal
For the last few years, I've been interested in vaults as a way to substantially derisk custodying Bitcoin, both at personal and commercial scales. Instead of abating with familiarity, as enthusiasm sometimes does, my conviction that vaults are an almost necessary part of bitcoin's viability has only grown over the years. Since people first started discussing vaults, it's been pretty clear that some kind of covenant-enabling consensus functionality is necessary to provide the feature set necessary to make vault use practical. Earlier last year I experimented with using OP_CTV[1], a limited covenant mechanism, to implement a "minimum-viable" vault design. I found that the inherent limitations of a precomputed covenant scheme left the resulting vault implementation wanting, even though it was an improvement over existing strategies that rely on presigned transactions and (hopefully) ephemeral keys. But I also found proposed "general" covenant schemes to be unsuitable for this use. The bloated scriptPubKeys, both in size and complexity, that would result when implementing something like a vault weren't encouraging. Also importantly, the social-consensus quagmire regarding which covenant proposal to actually deploy feels at times intractable. As a result, I wanted to explore a middle way: a design solely concerned with making the best vault use possible, with covenant functionality as a secondary consideration. In other words, a proposal that would deliver the safety benefits of vaults to users without getting hung up on trying to solve the general problem of covenants. At first this design, OP_VAULT, was just sort of a pipe dream. But as I did more thinking (and eventually implementing) I became more convinced that, even if it isn't considered for soft-fork, it is a worthwhile device to serve as a standard benchmark against which other proposals might be judged. I wrote a paper that summarizes my findings and the resulting proposal: https://jameso.be/vaults.pdf along with an accompanying draft implementation: https://github.com/bitcoin/bitcoin/pull/26857 I might work on a BIP if there's interest. James [1]: https://github.com/jamesob/simple-ctv-vault ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Refreshed BIP324
On Fri, Jan 06, 2023 at 09:12:50AM +1000, Anthony Towns via bitcoin-dev wrote: > On Thu, Jan 05, 2023 at 10:06:29PM +, Pieter Wuille via bitcoin-dev wrote: > > Oh, yes. I meant this as an encoding scheme, not as a (replacement for) the > > negotiation/coordination mechanism. There could still be an initial > > assignment for 1-byte encodings, and/or an explicit mechanism to negotiate > > other assignment, and/or nothing at all for now. > The current implementation for 324 does the aliasing > as part of V2TransportDeserializer::GetMessage and > V2TransportSerializer::prepareForTransport. That makes a lot of sense, > [...] So I think you can make this setup work with a negotiated assignment of shortids, perhaps starting off something like: https://github.com/ajtowns/bitcoin/commit/6b8edd754bdcb582e293e4f5d0b41297711bdbb7 That has a 242 element array per peer giving the mappings (which is just ~250 bytes per peer) for deserialization, which seems workable. [0] It also has a single global map for serialization, so we'll always shorten CFILTER to shortid 39 for every peer that supports shortids, even, eg, for a peer who's told us they'll send CFILTER as shortid 99 and that we should interpret shortid 39 from them as NEWFEATUREX. That has three advantages: * each peer can choose a mapping that minimises their own outbound traffic, even potentially for asymmetric connections, and don't need to coordinate with the other peer to decide a common optimal mapping that they both use across their connection * you don't have to have different serialization tables per-peer, reducing memory usage / implementation complexity * you can leave V2TransportSerializer as a `const` object, and not have to introduce additional locking logic to be able to update its state... I'm not seeing a good way to introduce shortids for future one-shot negotiation messages though (like VERSION, VERACK, SENDADDRV2, WTXIDRELAY, SENDTXRCNCL): * if you explicitly announce the mapping first, you're just wasting bytes ("99=FOOBAR; 99 baz quux" vs just "FOOBAR baz quux") * if you negotiate the tables you support between VERSION/VERACK and then choose a mutually supported table after VERACK, that's too late for pre-VERACK negotation messages * announcing the tables you support as part of the VERSION message would work, but seems a bit klunky Also, if you did want to shift to a new table, you'd probably want to always support sending/receiving {37, 44, 46, 47, 36} messages? I guess I still kind-of think it'd make more sense to just reserve shortids for post-VERACK messages that are going to be sent more than once per connection... At that point, even if you don't have any table in common with your peer, just following VERACK with an immediate announcement of each shortid you want to use and its meaning would still make reasonable sense. If we included the ability to define your own shortids concurrently with bip324 rollout, then I think nodes could always have a static set of shortids they use for all their peers for outbound messages, which, as above, seems like it would make for simpler implementations. ie, you might send: VERSION SHORTIDTBLS ["","awesomeshortids"] WTXIDRELAY SENDADDRV2 SENDPACKAGES 1 VERACK SHORTID "" [(52,"getpkgtxns"), (53, "pkgtxns"), (54, "ancpkginfo")] ...but you'd do all that long form, and only switch to shortids for messages after you've declared exactly what your shortids are going to be. (where "" is the table name for bip324's table, and "awesomeshortids" is an updated table that includes the package relay commands already, perhaps) Cheers, aj [0] m_deserializer is used from the SocketHandler thread in CNode::ReceiveMsgBytes(), but the p2p protocol is managed from the MessageHandler thread; with multiple messages potentially deserialized into vRecvMsg() at once -- but that means that if the first message redefines shortid decoding, and the second message uses one of the redefined shortids, it will have already been decoded incorrectly. So that would need some futzing about still. ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev