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


_______________________________________________
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev

Reply via email to