From: Bastien TEINTURIER <bastien@acinq.fr>
To: Antoine Riard <antoine.riard@gmail.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 10:55:42 +0200 [thread overview]
Message-ID: <CACdvm3NfHbfE1O8ajc+by0wk=tqM4L-XU0VUFD5qfxSU3ArFtQ@mail.gmail.com> (raw)
In-Reply-To: <CALZpt+HFyh3X9nBvMnQ8C8T_ijahDrNsCsz0Qk_ogS5zM_BPBA@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 17938 bytes --]
Hi Antoine and list,
Thanks for raising this. There's one step I'd like to understand further:
* Mallory can broadcast its Pinning Preimage Tx on offered HTLC #2 output
> on Alice's transaction,
> feerate is maliciously chosen to get in network mempools but never to
> confirm. Absolute fee must
> be higher than HTLC-timeout #2, a fact known to Mallory. There is no p2p
> race.
>
Can you detail how the "absolute fee" is computed here?
Doesn't that mean that if this had a higher fee than the htlc-timeout, and
the htlc-timeout fee was
chosen to confirm quickly (that's why we have an annoying `update_fee`),
the htlc-success will confirm
quickly (which makes the problem disappear)?
Because once the commit tx is confirmed, the "package" consists of only the
htlc-success, doesn't it?
I think the devil will be in the details here, so it's worth expanding on
the fee calculation imho.
Thanks!
Bastien
Le mer. 22 avr. 2020 à 10:01, Antoine Riard <antoine.riard@gmail.com> a
écrit :
> Personally, I would have wait a bit before to go public on this, like
> letting some implementations
> increasing their CLTV deltas, but anyway, it's here now.
>
> Mempool-pinning attacks were already discussed on this list [0], but what
> we found is you
> can _reverse_ the scenario, where it's not the malicious party delaying
> confirmation of honest
> party transactions but malicious deliberately stucking its own
> transactions in the mempool to avoid
> confirmation of timeout. And therefore gaming inter-link timelock to
> provoke an unbalanced
> settlement for the victim ("aka you pay forward, but don't get pay
> backward").
>
> How much attacks are practical is based on how you can leverage mempool
> rules to pin your own
> transaction. What you're looking for is a _mempool-obstruction_ trick,
> i.e a way to get honest party
> transaction being bounce off due to your transaction being already there.
>
> Beyond disabling RBF on your transaction (with current protocol, not
> anchor proposal), there is
> two likely candidates:
> * BIP 125 rule 3: "The replacement transaction pays an absolute fee of at
> least the sum paid by the original transactions."
> * BIP 125 rule 5: "The number of original transactions to be replaced and
> their descendant transactions which will be evicted from the mempool must
> not exceed a total of 100 transactions."
>
> Let's go through whole scenario:
> * Mallory and Eve are colluding
> * Eve and Mallory are opening channels with Alice, Mallory do a bit of
> rebalancing
> to get full incoming capacity, like receiving funds on an onchain address
> through another Alice
> link
> * Eve send a HTLC #1 to Mallory through Alice expirying at block 100
> * Eve send a second HTLC #2 to Mallory through Alice, expirying at block
> 110 on outgoing link
> (A<->M), 120 on incoming link (E<->A)
> * Before block 100, without cancellation from Mallory, Alice will
> force-close channel and broadcast
> her local commitment and HTLC-timeout to get back HTLC #1
> * Alice can't broadcast HTLC-timeout for HTLC #2 as it's only expires at
> 110
> * Mallory can broadcast its Pinning Preimage Tx on offered HTLC #2 output
> on Alice's transaction,
> feerate is maliciously chosen to get in network mempools but never to
> confirm. Absolute fee must
> be higher than HTLC-timeout #2, a fact known to Mallory. There is no p2p
> race.
> * As Alice doesn't watch the mempool, she is never going to learn the
> preimage to redeeem incoming
> HTLC #2
> * At block 110, Alice is going to broadcast HTLC-timeout #2, feerate may
> be higher but as absolute
> fee is lower, it's going to be rejected from network mempools as
> replacement for Pinning Preimage
> Tx (BIP 125 rule 3)
> * At block 120, Eve closes channel and HTLC-timeout HTLC #2
> * Mallory can RBF its Pinning Preimage Tx by a high-feerate one and get it
> confirmed
>
> New anchor_output proposal, by disabling RBF, forces attacker to bid on
> the absolute fee. It may
> be now a risk to loose the fee if Pinning Tx is confirming. You may extend
> your "pinning
> lease" by ejecting your malicious tx, like conflicting or trimming out of
> the mempool one of its
> parents. And then reannounce your preimage tx with a
> lower-feerate-but-still-high-fee before a
> new block and a honest HTLC-timeout rebroadcast.
>
> AFAICT, even with anchor_output deployed, even assuming empty mempools,
> success rate and economic
> rationality of attacks is finding such cheap, reliable "pinning lease
> extension" trick.
>
> I think any mempool watching mitigation is at best a cat-and-mouse hack.
> Contrary to node
> advancing towards a global blockchain view thanks to PoW, network mempools
> don't have a convergence
> guarantee. This means, in a distributed system like bitcoin, node don't
> see events in the same
> order, Alice may observe tx X, tx Y, tx Z and Bob may observe tx Z, tx X,
> tx Y. And order of events
> affects if a future event is going to be rejected or not, like if tx Z
> disable-RBF and tx X try to
> replace Z, Alice accepts X and Bob rejects it. And this divergence may
> perserve until a new block.
>
> Practically, it means an attacker can provoke a local conflict to bounce
> off HTLC preimage tx out
> of your mempool while broadcasting preimage tx without conflict to the
> rest of the network by
> tweaking tx-relay protocol and so easily manipulating order of events for
> every node. A local
> conflict is easy to provoke, just make tx A double-spent by both
> HTLC-preimage-tx and non-RBF-tx-B.
> Announce txA+txB to mempool victim and txA+HTLC-preimage-tx to rest of
> network. When rest of
> network announce HTLC-preimage-tx, it's going to rejected by your mempool.
>
> Provoking local conflict assumes of course _interlayer_ mapping by an
> attacker, i.e mapping your LN
> node to your full-node(s). Last time, we check, there was 982 match by IP
> for 4,500 LN/52,000
> full-node. Mapping heuristics is an ongoing research subject and sadly
> seems affordable.
>
> Yes a) you can enable full-RBF on your local node but blinding conflicting
> may still be with higher
> feerate as everything is attacker malleable b) you may want to catch tx
> and extract preimage
> on the p2p wire, but processing raw transaction would be such a DoS
> vector...
>
> Overall, I think we all agree on the long term direction to get a
> Contracting-Protocols-Enhanced
> mempool with a multiparty-safe-API, bundled with package relay deployment.
> Even if there is current
> move toward this direction, this may take longer than expected as with any
> critical-safety
> component in Core.
>
> A temporary fix could be to resuscitate old work to ensure peering through
> a full-RBF propagation path,
> but p2p implications are hard to gauge, like wouldn't guarantee p2p
> censorship resistance of this...
>
> It's quite a tangled issue, with a good deal of both bitcoin and lightning
> knowledge so feel free
> to verify and double-check more than usual
>
> Cheers
>
> [0]
> https://lists.linuxfoundation.org/pipermail/lightning-dev/2019-October/002240.html
>
> Le mer. 22 avr. 2020 à 02:08, ZmnSCPxj via bitcoin-dev <
> bitcoin-dev@lists.linuxfoundation.org> a écrit :
>
>> 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
>>
> _______________________________________________
> Lightning-dev mailing list
> Lightning-dev@lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/lightning-dev
>
[-- Attachment #2: Type: text/html, Size: 20067 bytes --]
next prev parent reply other threads:[~2020-04-22 8:55 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-04-21 2:43 [bitcoin-dev] RBF Pinning with Counterparties and Competing Interest 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 [this message]
2020-04-22 23:05 ` Olaoluwa Osuntokun
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='CACdvm3NfHbfE1O8ajc+by0wk=tqM4L-XU0VUFD5qfxSU3ArFtQ@mail.gmail.com' \
--to=bastien@acinq.fr \
--cc=antoine.riard@gmail.com \
--cc=bitcoin-dev@lists.linuxfoundation.org \
--cc=lightning-dev@lists.linuxfoundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
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