Return-Path: <pete@petertodd.org>
Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137])
 by lists.linuxfoundation.org (Postfix) with ESMTP id 67BBBC0037
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sat, 27 Jan 2024 07:26:05 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
 by smtp4.osuosl.org (Postfix) with ESMTP id 2F21F41FDC
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sat, 27 Jan 2024 07:26:05 +0000 (UTC)
DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org 2F21F41FDC
Authentication-Results: smtp4.osuosl.org; dkim=pass (2048-bit key,
 unprotected) header.d=messagingengine.com header.i=@messagingengine.com
 header.a=rsa-sha256 header.s=fm3 header.b=ZpPMxnOt
X-Virus-Scanned: amavisd-new at osuosl.org
X-Spam-Flag: NO
X-Spam-Score: -2.6
X-Spam-Level: 
X-Spam-Status: No, score=-2.6 tagged_above=-999 required=5
 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1,
 RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001]
 autolearn=ham autolearn_force=no
Received: from smtp4.osuosl.org ([127.0.0.1])
 by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id XtgKcUCMOayG
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sat, 27 Jan 2024 07:26:02 +0000 (UTC)
X-Greylist: delayed 392 seconds by postgrey-1.37 at util1.osuosl.org;
 Sat, 27 Jan 2024 07:26:01 UTC
DKIM-Filter: OpenDKIM Filter v2.11.0 smtp4.osuosl.org E794241FCE
Received: from fhigh6-smtp.messagingengine.com
 (fhigh6-smtp.messagingengine.com [103.168.172.157])
 by smtp4.osuosl.org (Postfix) with ESMTPS id E794241FCE
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Sat, 27 Jan 2024 07:26:01 +0000 (UTC)
Received: from compute2.internal (compute2.nyi.internal [10.202.2.46])
 by mailfhigh.nyi.internal (Postfix) with ESMTP id 4479211400A6;
 Sat, 27 Jan 2024 02:19:28 -0500 (EST)
Received: from mailfrontend2 ([10.202.2.163])
 by compute2.internal (MEProxy); Sat, 27 Jan 2024 02:19:28 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=
 messagingengine.com; h=cc:content-type:content-type:date:date
 :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to
 :message-id:mime-version:references:reply-to:subject:subject:to
 :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=
 fm3; t=1706339968; x=1706426368; bh=Txrnwp9TZqOsShXJbynyaKYkf2O8
 2cInzGm+k3oGMnQ=; b=ZpPMxnOtU3/wjuZdepZW3G9Qy9mQxlRnZtxwyAB1/6FQ
 vueOGAHMoE1IRAetWSYAScmq+2cBw29j0MH6jjFzeV2bKIXnMlUFkpF6EWqWQlXG
 cxr6dv8qagvCTM5kuWaO+mOgLs84oyVZueNUyGDcVHnwJpZruZyeliRraDuLzlVu
 44lvKxq95FfUH/QnPsy+BVh04QGml27PTemk4mmsX7LI3SEUcMYRM0OKWXe7GaHV
 tTszSBKOZHTFmYPIrGP2NgjcyMRN6aC9jpmvIojwRz4rJ7sJtx0RIz5Cfnb0n5qK
 sOlW2/YcPiEBmoGrQ1IIGxtXWiNaB/yUrCd/uWZoTw==
X-ME-Sender: <xms:f660ZT4fcMRjkLM4IddP2l9piXH94FAmAZP-xmJbt00XwV3vGIyvNA>
 <xme:f660ZY4d7ThbLN5Y9i1EbMjKorpvo7Y_9VyJQ5HMg9zF82XcFFo43dt9KZZAgPwpb
 kiuqnwvqwEglTnFq70>
X-ME-Received: <xmr:f660ZaeBy588WqZccuwusL7MsSI-2wBu_ALBt9pSVklRMZvq7FVYdeBQ8Ts>
X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvkedrvdelkedguddtgecutefuodetggdotefrod
 ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh
 necuuegrihhlohhuthemuceftddtnecunecujfgurhepfffhvffukfhfgggtuggjsehgtd
 erredttdejnecuhfhrohhmpefrvghtvghrucfvohguugcuoehpvghtvgesphgvthgvrhht
 ohguugdrohhrgheqnecuggftrfgrthhtvghrnhepledtteevueevhfdvfeevfeevffehud
 fhffetgeehtddtvefgveejteevjeevjefhnecuffhomhgrihhnpehpvghtvghrthhouggu
 rdhorhhgpdhsthgrtghkvghrrdhnvgifshdpghgvthhnvgifrgguughrvghsshdrthhone
 cuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepphgvthgv
 sehpvghtvghrthhouggurdhorhhg
X-ME-Proxy: <xmx:f660ZUKq-Xw9lhcQoSpE_oCvQjH-_am0ChJcOp-JztShhsJlLBcOcQ>
 <xmx:f660ZXKOYPI6tLr7LCSBpO9ppl_C9Mqq16UXG_518d2IO7_-BxBPvQ>
 <xmx:f660ZdyuFaG_GRToiEkj44B6xVUPpxj_mNkf-FxZuyAiFy3rGNH2BA>
 <xmx:gK60ZdinJm4VllZJjPYFjxtb2w10ojfaUQ39aypdtj2IpyEORPmK7Q>
Feedback-ID: i525146e8:Fastmail
Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sat,
 27 Jan 2024 02:19:26 -0500 (EST)
Received: by localhost (Postfix, from userid 1000)
 id A20E75F84B; Sat, 27 Jan 2024 07:19:22 +0000 (UTC)
Date: Sat, 27 Jan 2024 07:19:22 +0000
From: Peter Todd <pete@petertodd.org>
To: Murch <murch@murch.one>,
 Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>
Message-ID: <ZbSueoReTvEmm1s9@petertodd.org>
References: <Zalsq+Nq7RRr/CAR@petertodd.org>
 <9a89eca8-61fd-4156-825d-c9b718dc3034@murch.one>
MIME-Version: 1.0
Content-Type: multipart/signed; micalg=pgp-sha512;
 protocol="application/pgp-signature"; boundary="+FlKIbswhidnlpem"
Content-Disposition: inline
In-Reply-To: <9a89eca8-61fd-4156-825d-c9b718dc3034@murch.one>
Subject: Re: [bitcoin-dev] One-Shot Replace-By-Fee-Rate
X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org>
List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>, 
 <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>, 
 <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
X-List-Received-Date: Sat, 27 Jan 2024 07:26:05 -0000


--+FlKIbswhidnlpem
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Mon, Jan 22, 2024 at 01:12:45PM -0500, Murch via bitcoin-dev wrote:
> Hi Peter,
>=20
> On 1/18/24 13:23, Peter Todd via bitcoin-dev wrote:
> > Reposting this blog post here for discussion:
> >
> > https://petertodd.org/2024/one-shot-replace-by-fee-rate
>=20
> I saw your proposal mentioned on Stacker News and read it with interest. =
In
> response, I described a replacement cycle that can be used to broadcast t=
he
> same five transactions repeatedly:
>=20
> https://stacker.news/items/393182
>=20
> The gist is that by using two confirmed inputs and five transactions, you
> can use RBFr to reduce the absolute fee while raising the feerate to top
> block levels, then immediately use the current RBF rules to introduce a
> high-feerate transaction that beats the RBFr transaction but is hampered =
by
> a low-feerate parent and not attractive for mining, then use RBF to repla=
ce
> its low-feerate parent, then use the RBFr transaction again to reduce the
> absolute feerate. Due to the asymmetric replacements, the same transactio=
ns
> can replace each other in that order in every cycle. Please refer to the
> linked write-up for details, I=E2=80=99ve included weights, fees, and a t=
ransaction
> graph to make my example comprehensible.
>=20
> Among those five transactions, the only transaction attractive for block
> inclusion would be the small RBFr transaction with a
> bottom-of-the-next-block feerate. Today, if it were mined it would amount=
 to
> fees of around 4000 sats every few blocks to make the entire network relay
> transactions of more than 205,000=E2=80=AFvB every few seconds. Given tha=
t my
> example is minimal, it should be possible to further increase bandwidth
> cost.
>=20
> Assuming that I did not make a mistake, i.e. all the replacements are via=
ble
> and my scenario is compatible with your proposal, the described One-Shot
> Replace-By-Fee-Rate proposal would not be safe for deployment on the
> network.

I actually tried this attack out, and it fails at step #4 due to the Rule #=
6,
PaysMoreThanConflicts, check.

While on stacker.news you stated that:

    tx_HS has 5000 vB and pays 21 s/vB, but since it spends an output from a
    low-feerate parent, it=E2=80=99s mining score is only 1.95=E2=80=AFs/vB.

and

    You RBF tx_LL and tx_HS with tx_LM that has 100,000 vB and pays 3.05=E2=
=80=AFs/vB (fee:
    305,000 s) by spending the outputs C1 and C2. This is permitted, since =
only
    tx_LL is a direct conflict, so the feerate of tx_HS does not have to be=
 beat
    directly.

tx_HS _is_ considered to be a direct conflict, and its raw fee-rate _does_ =
have
to be beat directly. While ts_HS does spend an unconfirmed output, it appea=
rs
that the fee-rate PaysMoreThanConflicts uses to calculate if ts_HS can be
beaten is ts_HS's raw fee-rate. So looks like your understanding was incorr=
ect
on these two points.

FYI here is the actual test script I used to test this attack. You can run =
it
using Bitcoin v26.0 with the -acceptnonstdtxn -mempoolfullrbf=3D1 command l=
ine
arguments, with python-bitcoinlib v0.12.2 installed.

#!/usr/bin/env python3

import bitcoin
bitcoin.SelectParams('regtest')

import bitcoin.rpc
import sys

=66rom bitcoin.core import *
=66rom bitcoin.core.script import *
=66rom bitcoin.wallet import *

proxy =3D bitcoin.rpc.Proxy()

my_addr =3D proxy.getnewaddress().to_scriptPubKey()

coins =3D proxy.listunspent(1)

print(coins[0:2])

txo1 =3D coins[0]['outpoint']
txo1_amount =3D coins[0]['amount']
txo2 =3D coins[1]['outpoint']
txo2_amount =3D coins[1]['amount']

print(txo1)
print(txo2)

for i in range(0, 1):
    # Step 2
    tx_ll =3D CTransaction(
        [CTxIn(txo1)],
        [CTxOut(txo1_amount - 100000, my_addr),
         CTxOut(0, CScript([OP_RETURN, b'x' * 90000]))])

    r =3D proxy.signrawtransactionwithwallet(tx_ll)
    assert(r['complete'])
    tx_ll_signed =3D r['tx']

    print('tx_ll =3D %s' % b2lx(proxy.sendrawtransaction(tx_ll_signed)))

    tx_ls =3D CTransaction(
        [CTxIn(COutPoint(tx_ll.GetTxid(), 0))],
        [CTxOut(txo1_amount - 100000 - 300, my_addr)])
    r =3D proxy.signrawtransactionwithwallet(tx_ls)
    assert(r['complete'])
    tx_ls_signed =3D r['tx']

    print('tx_ls =3D %s' % b2lx(proxy.sendrawtransaction(tx_ls_signed)))

    # Step 3
    tx_hs =3D CTransaction(
        [CTxIn(COutPoint(tx_ll.GetTxid(), 0)),
         CTxIn(txo2)],
        [CTxOut((txo1_amount - 100000) + txo2_amount - 4000, my_addr)])

    r =3D proxy.signrawtransactionwithwallet(tx_hs)
    assert(r['complete'])
    tx_hs_signed =3D r['tx']

    print('tx_hs =3D %s ' % b2lx(proxy.sendrawtransaction(tx_hs_signed)))


    # Step 4
    tx_lm =3D CTransaction(
        [CTxIn(txo1),
         CTxIn(txo2)],
        [CTxOut(txo1_amount + txo2_amount - 300000, my_addr),
         CTxOut(0, CScript([OP_RETURN, b'x' * 90000]))])

    r =3D proxy.signrawtransactionwithwallet(tx_lm)
    assert(r['complete'])
    tx_lm_signed =3D r['tx']

    print('tx_lm =3D %s' % b2lx(proxy.sendrawtransaction(tx_lm_signed)))

--+FlKIbswhidnlpem
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEE0RcYcKRzsEwFZ3N5Lly11TVRLzcFAmW0rnkACgkQLly11TVR
LzdVzg/+KPUkIvZNF9cqBmRx32tfxehFlqaLZoBqAS2YGEhKbX1QoCFwM8R7F2VM
pP/16pJeZszRDrbo8dk3/X5r4qpDQfpv2Q748+DbxtYMTBngkXJgdaYX1Vi2RtzA
7lGrN930Grw7IqHGGD1yp5S7rqk/tggP6Kux/mvsS0/Ntg7SQeVTqbfSFLEfLBVj
lr65B3IUb3m8PsBm4xdLVjZIVYnJqTCBmBDgm6tnw9hiEOCbkZhn7hIBrLJ0NJLR
xpUUW7XFx/+wvtntZphVBeKo89z7RohP5acRsFY5hFw+hCt7AlCNVH5Rd9n3yvj8
uRR9y8znMC/sw/1DR7fWV1mC0y338IaN4fuABnocLyMtk2mcVAmATB5xhiIFO9f4
LxYjqi10ybcgcE/6zGH/IcMEE0chUKH/2ySM+hu2RnkCuWx+1pnUeqoE+7Ij4H8u
LvVixbqabTRlAKAunoRzLjdUZ4XHRguoplwxLLZIGUicaMjQBVFMd4x0mPhuryJQ
11GOhQ3Nu7xtuEZDjlrTZYLZ8JinlSeP0pIO2LZgqsX6FO0LQduuajGxTeHdm/IQ
eQMrr7lsTKKBbjSgODGUS9uhP5dCAIM1nawW3ScOnBXiNYp97S5wWdcNiUrxmM4i
QLYPtKMG5kF86lky5ayuzfL1Wwbbcfzy2rJ4WognZf/fF4SLld4=
=ygyc
-----END PGP SIGNATURE-----

--+FlKIbswhidnlpem--