1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
|
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--
|