public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
From: Olaoluwa Osuntokun <laolu32@gmail•com>
To: ZmnSCPxj <ZmnSCPxj@protonmail•com>
Cc: Bitcoin Protocol Discussion
	<bitcoin-dev@lists•linuxfoundation.org>,
	lightning-dev <lightning-dev@lists•linuxfoundation.org>
Subject: Re: [bitcoin-dev] [Lightning-dev] RBF Pinning with Counterparties and Competing Interest
Date: Wed, 22 Apr 2020 16:05:17 -0700	[thread overview]
Message-ID: <CAO3Pvs_+Nps5Qmx2UN539+Y-2j=z0YHcKiWfHE8V0+cHn=MTkQ@mail.gmail.com> (raw)
In-Reply-To: <_ilRrLKoKyX8r9KRUw13Gx2H8LJxLleELolnZigAtS0-tXG2BDNU7RXBr7M3a467UMN9GS2MwiZcwwmRZgXHraxRIV_y5c_Zz3ZTNbKSlqg=@protonmail.com>

[-- Attachment #1: Type: text/plain, Size: 10536 bytes --]

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 <ZmnSCPxj@protonmail•com> 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
>
>
>

[-- Attachment #2: Type: text/html, Size: 12016 bytes --]

  parent reply	other threads:[~2020-04-22 23:05 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-21  2:43 [bitcoin-dev] " Matt Corallo
2020-04-22  4:12 ` [bitcoin-dev] [Lightning-dev] " ZmnSCPxj
2020-04-22  4:18   ` Olaoluwa Osuntokun
2020-04-22  6:08     ` ZmnSCPxj
2020-04-22  8:01       ` Antoine Riard
2020-04-22  8:55         ` Bastien TEINTURIER
2020-04-22 23:05       ` Olaoluwa Osuntokun [this message]
2020-04-22 23:11         ` Olaoluwa Osuntokun
2020-04-22 16:56   ` Matt Corallo
2020-04-22  4:13 ` [bitcoin-dev] " Olaoluwa Osuntokun
2020-04-22 11:51   ` David A. Harding
2020-04-27 21:26     ` Rusty Russell
2020-04-22 16:50   ` Matt Corallo
2020-04-22 23:13     ` Olaoluwa Osuntokun
2020-04-22 23:20       ` Matt Corallo
2020-04-22 23:27         ` Olaoluwa Osuntokun
2020-04-23  1:10           ` Matt Corallo
2020-04-23  4:50             ` [bitcoin-dev] [Lightning-dev] " ZmnSCPxj
2020-04-23  6:21               ` Matt Corallo
2020-04-23 12:46                 ` ZmnSCPxj
2020-04-23 22:47                   ` Matt Corallo
2020-06-19  7:44                     ` Bastien TEINTURIER
2020-06-19 19:58                       ` David A. Harding
2020-06-19 20:52                         ` David A. Harding
2020-06-20  8:54                           ` Bastien TEINTURIER
2020-06-20 10:36                             ` David A. Harding
2020-06-20 16:01                               ` ZmnSCPxj
2020-06-21  2:10                                 ` ZmnSCPxj
2020-06-22  7:35                               ` Bastien TEINTURIER
2020-06-22  8:15                                 ` ZmnSCPxj
2020-06-22  8:25                                   ` Bastien TEINTURIER
2020-06-24  8:32                                     ` Matt Corallo
2020-04-23  1:18           ` [bitcoin-dev] " Jeremy
2020-04-22 18:24 ` David A. Harding
2020-04-22 19:03   ` Antoine Riard
2020-04-22 20:28     ` David A. Harding
2020-04-22 22:53 Matt Corallo
2020-04-23  9:59 ` David A. Harding
2020-04-23 12:52   ` [bitcoin-dev] [Lightning-dev] " ZmnSCPxj

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAO3Pvs_+Nps5Qmx2UN539+Y-2j=z0YHcKiWfHE8V0+cHn=MTkQ@mail.gmail.com' \
    --to=laolu32@gmail$(echo .)com \
    --cc=ZmnSCPxj@protonmail$(echo .)com \
    --cc=bitcoin-dev@lists$(echo .)linuxfoundation.org \
    --cc=lightning-dev@lists$(echo .)linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox