Hi z, Actually, the current anchors proposal already does this, since it enforces a CSV of 1 block before the HTLCs can be spent (the block after confirmation). So I think we already do this, meaning the malicious node is already forced to use an RBF-replaceable transaction. -- Laolu On Wed, Apr 22, 2020 at 4:05 PM Olaoluwa Osuntokun wrote: > Hi Z, > > > It seems to me that, if my cached understanding that `<0> > > OP_CHECKSEQUENCEVERIFY` is sufficient to require RBF-flagging, then > adding > > that to the hashlock branch (2 witness bytes, 0.5 weight) would be a > pretty > > low-weight mitigation against this attack. > > I think this works...so they're forced to spend the output with a non-final > sequence number, meaning it *must* signal RBF. In this case, now it's the > timeout-er vs the success-er racing based on fee rate. If the honest party > (the > one trying to time out the HTLC) bids a fee rate higher (need to also > account > for the whole absolute fee replacement thing), then things should generally > work out in their favor. > > -- Laolu > > > On Tue, Apr 21, 2020 at 11:08 PM ZmnSCPxj wrote: > >> Good morning Laolu, Matt, and list, >> >> >> > > * With `SIGHASH_NOINPUT` we can make the C-side signature >> > > `SIGHASH_NOINPUT|SIGHASH_SINGLE` and allow B to re-sign the B-side >> > > signature for a higher-fee version of HTLC-Timeout (assuming my >> cached >> > > understanding of `SIGHASH_NOINPUT` still holds). >> > >> > no_input isn't needed. With simply single+anyone can pay, then B can >> attach >> > a new input+output pair to increase the fees on their HTLC redemption >> > transaction. As you mention, they now enter into a race against this >> > malicious ndoe to bump up their fees in order to win over the other >> party. >> >> Right, right, that works as well. >> >> > >> > If the malicious node uses a non-RBF signalled transaction to sweep >> their >> > HTLC, then we enter into another level of race, but this time on the >> mempool >> > propagation level. However, if there exists a relay path to a miner >> running >> > full RBF, then B's higher fee rate spend will win over. >> >> Hmm. >> >> So basically: >> >> * B has no mempool, because it wants to reduce its costs and etc. >> * C broadcasts a non-RBF claim tx with low fee before A->B locktime (L+1). >> * B does not notice this tx because: >> 1. The tx is too low fee to be put in a block. >> 2. B has no mempool so it cannot see the tx being propagated over the >> P2P network. >> * B tries to broadcast higher-fee HTLC-timeout, but fails because it >> cannot replace a non-RBF tx. >> * After L+1, C contacts the miners off-band and offers fee payment by >> other means. >> >> It seems to me that, if my cached understanding that `<0> >> OP_CHECKSEQUENCEVERIFY` is sufficient to require RBF-flagging, then adding >> that to the hashlock branch (2 witness bytes, 0.5 weight) would be a pretty >> low-weight mitigation against this attack. >> >> So I think the combination below gives us good size: >> >> * The HTLC-Timeout signature from C is flagged with >> `OP_SINGLE|OP_ANYONECANPAY`. >> * Normally, the HTLC-Timeout still deducts the fee from the value of >> the UTXO being spent. >> * However, if B notices that the L+1 timeout is approaching, it can >> fee-bump HTLC-Timeout with some onchain funds, recreating its own signature >> but reusing the (still valid) C signature. >> * The hashlock branch in this case includes `<0> OP_CHECKSEQUENCEVERIFY`, >> preventing C from broadcasting a low-fee claim tx. >> >> This has the advantages: >> >> * B does not need a mempool still and can run in `blocksonly`. >> * The normal path is still the same as current behavior, we "only" add a >> new path where if the L+1 timeout is approaching we fee-bump the >> HTLC-Timeout. >> * Costs are pretty low: >> * No need for extra RBF carve-out txo. >> * Just two additional witness bytes in the hashlock branch. >> * No mempool rule changes needed, can be done with the P2P network of >> today. >> * Probably still resilient even with future changes in mempool rules, >> as long as typical RBF behaviors still remain. >> >> Is my understanding correct? >> >> Regards, >> ZmnSCPxj >> >> > >> > -- Laolu >> > >> > On Tue, Apr 21, 2020 at 9:13 PM ZmnSCPxj via bitcoin-dev < >> bitcoin-dev@lists.linuxfoundation.org> wrote: >> > >> > > Good morning Matt, and list, >> > > >> > > > RBF Pinning HTLC Transactions (aka "Oh, wait, I can steal >> funds, how, now?") >> > > > ============================= >> > > > >> > > > You'll note that in the discussion of RBF pinning we were >> pretty broad, and that that discussion seems to in fact cover >> > > > our HTLC outputs, at least when spent via (3) or (4). It does, >> and in fact this is a pretty severe issue in today's >> > > > lightning protocol [2]. A lightning counterparty (C, who >> received the HTLC from B, who received it from A) today could, >> > > > if B broadcasts the commitment transaction, spend an HTLC using >> the preimage with a low-fee, RBF-disabled transaction. >> > > > After a few blocks, A could claim the HTLC from B via the >> timeout mechanism, and then after a few days, C could get the >> > > > HTLC-claiming transaction mined via some out-of-band agreement >> with a small miner. This leaves B short the HTLC value. >> > > >> > > My (cached) understanding is that, since RBF is signalled using >> `nSequence`, any `OP_CHECKSEQUENCEVERIFY` also automatically imposes the >> requirement "must be RBF-enabled", including `<0> OP_CHECKSEQUENCEVERIFY`. >> > > Adding that clause (2 bytes in witness if my math is correct) to the >> hashlock branch may be sufficient to prevent C from making an RBF-disabled >> transaction. >> > > >> > > But then you mention out-of-band agreements with miners, which >> basically means the transaction might not be in the mempool at all, in >> which case the vulnerability is not really about RBF or relay, but sheer >> economics. >> > > >> > > The payment is A->B->C, and the HTLC A->B must have a larger timeout >> (L + 1) than the HTLC B->C (L), in abstract non-block units. >> > > The vulnerability you are describing means that the current time must >> now be L + 1 or greater ("A could claim the HTLC from B via the timeout >> mechanism", meaning the A->B HTLC has timed out already). >> > > >> > > If so, then the B->C transaction has already timed out in the past >> and can be claimed in two ways, either via B timeout branch or C hashlock >> branch. >> > > This sets up a game where B and C bid to miners to get their version >> of reality committed onchain. >> > > (We can neglect out-of-band agreements here; miners have the >> incentive to publicly leak such agreements so that other potential bidders >> can offer even higher fees for their versions of that transaction.) >> > > >> > > Before L+1, C has no incentive to bid, since placing any bid at all >> will leak the preimage, which B can then turn around and use to spend from >> A, and A and C cannot steal from B. >> > > >> > > Thus, B should ensure that *before* L+1, the HTLC-Timeout has been >> committed onchain, which outright prevents this bidding war from even >> starting. >> > > >> > > The issue then is that B is using a pre-signed HTLC-timeout, which is >> needed since it is its commitment tx that was broadcast. >> > > This prevents B from RBF-ing the HTLC-Timeout transaction. >> > > >> > > So what is needed is to allow B to add fees to HTLC-Timeout: >> > > >> > > * We can add an RBF carve-out output to HTLC-Timeout, at the cost of >> more blockspace. >> > > * With `SIGHASH_NOINPUT` we can make the C-side signature >> `SIGHASH_NOINPUT|SIGHASH_SINGLE` and allow B to re-sign the B-side >> signature for a higher-fee version of HTLC-Timeout (assuming my cached >> understanding of `SIGHASH_NOINPUT` still holds). >> > > >> > > With this, B can exponentially increase the fee as L+1 approaches. >> > > If B can get HTLC-Timeout confirmed before L+1, then C cannot steal >> the HTLC value at all, since the UTXO it could steal from has already been >> spent. >> > > >> > > In particular, it does not seem to me that it is necessary to change >> the hashlock-branch transaction of C at all, since this mechanism is enough >> to sidestep the issue (as I understand it). >> > > But it does point to a need to make HTLC-Timeout (and possibly >> symmetrically, HTLC-Success) also fee-bumpable. >> > > >> > > Note as well that this does not require a mempool: B can run in >> `blocksonly` mode and as each block comes in from L to L+1, if HTLC-Timeout >> is not confirmed, feebump HTLC-Timeout. >> > > In particular, HTLC-Timeout comes into play only if B broadcast its >> own commitment transaction, and B *should* be aware that it did so --- >> there is still no need for mempool monitoring here. >> > > >> > > Now, of course this only delays the war. >> > > Let us now consider what C can do to ensure that the bidding war will >> happen eventually. >> > > >> > > * C can bribe a miner to prevent HTLC-Timeout from confirming between >> L and L+1. >> > > * Or in other words, this is a censorship attack. >> > > * The Bitcoin censorship-resistance model is that censored >> transactions can be fee-bumped, which attracts non-censoring miners to try >> their luck at mining and evict the censoring miner. >> > > * Thus, letting B bump the fee on HTLC-Timeout is precisely the >> mechanism we need. >> > > * This sets up a bidding war between C requesting miners to >> censor, vs. B requesting miners to confirm, but that only sets the stage >> for a second bidding war later between C and B, thus C is at a >> disadvantage: it has to bribe miners to censor continuously from L to L+1 >> *and* additional bribe miners to confirm its transaction after L+1, whereas >> B can offer its bribe as being something that miners can claim now without >> waiting after L+1. >> > > >> > > The issue of course is the additional output that bloats the UTXO set >> and requires another transaction to claim later. >> > > And if we have `SIGHASH_NOINPUT`, it seems to me that >> Decker-Russell-Osuntokun sidesteps this issue as well, as any timed-out >> HTLC can be claimed with a fee-bumpable transaction directly without >> RBF-carve-out. >> > > (As well, it seems to me that, if both nodes support doing so, a >> Poon-Dryja channel can be upgraded, without onchain activity, to a >> Decker-Russell-Osuntokun channel: sign a transaction spending the funding >> tx to a txo that has been set up as Decker-Russell-Osuntokun, do not >> broadcast that transaction, then revoke the latest Poon-Dryja commitment >> transactions, then switch the mechanism over to Decker-Russell-Osuntokun; >> you still need to monitor for previous Poon-Dryja commitment transactions, >> but HTLCs now sidestep the issue under discussion here.) >> > > >> > > Regards, >> > > ZmnSCPxj >> > > _______________________________________________ >> > > bitcoin-dev mailing list >> > > bitcoin-dev@lists.linuxfoundation.org >> > > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev >> >> >>