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