summaryrefslogtreecommitdiff
path: root/dd/9fcf0dd2a5c6f2144303422f14e21ea00a2a8a
blob: 2dedcd5bef3d83deebbff3f01ecde6c7465af958 (plain)
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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
Return-Path: <gloriajzhao@gmail.com>
Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133])
 by lists.linuxfoundation.org (Postfix) with ESMTP id 7945AC000B
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Mon,  7 Feb 2022 11:16:45 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
 by smtp2.osuosl.org (Postfix) with ESMTP id 4812540298
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Mon,  7 Feb 2022 11:16:45 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
X-Spam-Flag: NO
X-Spam-Score: -2.098
X-Spam-Level: 
X-Spam-Status: No, score=-2.098 tagged_above=-999 required=5
 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1,
 DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001,
 HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,
 SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: smtp2.osuosl.org (amavisd-new);
 dkim=pass (2048-bit key) header.d=gmail.com
Received: from smtp2.osuosl.org ([127.0.0.1])
 by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id AhwZ_TQdLuHl
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Mon,  7 Feb 2022 11:16:39 +0000 (UTC)
X-Greylist: whitelisted by SQLgrey-1.8.0
Received: from mail-yb1-xb34.google.com (mail-yb1-xb34.google.com
 [IPv6:2607:f8b0:4864:20::b34])
 by smtp2.osuosl.org (Postfix) with ESMTPS id 80D2740272
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Mon,  7 Feb 2022 11:16:39 +0000 (UTC)
Received: by mail-yb1-xb34.google.com with SMTP id p5so38673883ybd.13
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Mon, 07 Feb 2022 03:16:39 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to
 :cc; bh=XmfX9W2HbqhCTSh2YXvGGPAT9AhwK7s/Zc0iQROyeXM=;
 b=LgaqWKHwYJG09rKOByoFu4UTheZRya1iFgDAkhMItPahbAL/MSJ4MJlT5IQFHHZiKo
 I+3CLSg5LGFqqq931Yya2WkXEsa6YZJhvas3X+bWo0T4xRl+MgZ5zTV6kWhTtYcMqjVO
 RjUncF+RqnpdG9P9JBX5Di1J+P7LV9knUHvNCiRc0KMwSYvIh/YVSU8AICqxHsbhPyJ6
 S4TtpH3tbH1lrLTAUL6+NJ2uvc+20UFzdIHs/VHRL3UoJ9Q1UTlqN9QZRhU9/A+MiSM/
 1dTcqo4yk3QVwE9XKz1h7SKbxHZs9lDDp3QDpPX/JvjOwnyrON+ET5/rI2zflN0zzolq
 MYyQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20210112;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to:cc;
 bh=XmfX9W2HbqhCTSh2YXvGGPAT9AhwK7s/Zc0iQROyeXM=;
 b=pq4R11sSSpUyBAwFBj1bx5+o37WXFq1G7NfLNY23X7Pix/MIrgR1Z+cv/Xo6gdwtnw
 iHinZGyMQ1eskeqpnOVKIqgz7Mli5hZMIv/5EcLECO/vlB1Shh7lw+xisgABIQjVbM7s
 qzp205t/iD7yo3sfplMlwk3R9MZJFEFrIk9SONeqTDPIbieKJpESYlcBOKZIvmFI74cJ
 8/Vz9aIrQa7ewkSODFSFWxiD+CUsZ3mOmU9esB/3W28LWZHOfsXFXWn/DiKDkAqOWO52
 /p6jO+y4inEG+1LF2ojz4sS38TjJmimJkCFBUtkUGC0tA7AHrXz2DppQIUoL/9eJpY2l
 5yAg==
X-Gm-Message-State: AOAM533RfkAIwrpo7VkCnqcpIi1u4+RVnh/u252HcOeZhWbug4yuL9v3
 dSbwLGGs9EbUc2trfRFOlkmCDWxMmmzekVtVYow=
X-Google-Smtp-Source: ABdhPJxi1z9OWCHRjEEUBdZOuzOqMN9BA4EK6WnUnbl8fB4wO56a+CwUw0ZjsX9tNbLkdqDJEm4c0StzsjGJphYLahE=
X-Received: by 2002:a81:c64b:: with SMTP id q11mr10444417ywj.289.1644232597851; 
 Mon, 07 Feb 2022 03:16:37 -0800 (PST)
MIME-Version: 1.0
References: <CAFXO6=LGbaur6XQrE+6a6mAAHXduOCXoWPTgPosxAG59ZkK6Gg@mail.gmail.com>
 <CALZpt+EjqKbhnN_5jy3kvYpMvjN8=iwRzMLSM7yS8_j-WzLrBQ@mail.gmail.com>
 <CACdvm3P1co1HDFKNxpHRe_JX_UPNw_P5qgL5cHCM=Qs+kR=B_A@mail.gmail.com>
 <GlEfqW7mh2W3uHkxDxwb5RSj-O_zbTUi4wa67oRz3erHRM1ykxT0BrcJrqulCOqrRLVJ4Bp8KVSOj0yJGB7rwcFGlZDyMrTsndPFO89hAQc=@protonmail.com>
 <CACdvm3P_-1DPxcWkd1J-PckPF1oRTtVB5zz5e3+VQ0Mko1T=hQ@mail.gmail.com>
In-Reply-To: <CACdvm3P_-1DPxcWkd1J-PckPF1oRTtVB5zz5e3+VQ0Mko1T=hQ@mail.gmail.com>
From: Gloria Zhao <gloriajzhao@gmail.com>
Date: Mon, 7 Feb 2022 11:16:26 +0000
Message-ID: <CAFXO6=+WFUueqDh21NTZzA5EcSQjX2owFn0+dr0ua_BRLfV4QQ@mail.gmail.com>
To: Bastien TEINTURIER <bastien@acinq.fr>, 
 Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>
Content-Type: multipart/alternative; boundary="000000000000ec51c205d76bbb39"
X-Mailman-Approved-At: Mon, 07 Feb 2022 11:59:03 +0000
Cc: Anthony Towns <aj@erisian.com.au>
Subject: Re: [bitcoin-dev] Improving RBF Policy
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: Mon, 07 Feb 2022 11:16:45 -0000

--000000000000ec51c205d76bbb39
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hi everyone,

Thanks for giving your attention to the post! I haven't had time to write
responses to everything, but sending my thoughts about what has been most
noteworthy to me:

@jeremy:
> A final point is that a verifiable delay function could be used over,
e.g., each of the N COutpoints individually to rate-limit transaction
replacement. The VDF period can be made shorter / eliminated depending on
the feerate increase.

Thanks for the suggestion! In general, I don't think rate limiting by
outpoint/prevout is a safe option, as it is particularly dangerous for L2
applications with shared prevouts. For example, the prevout that LN channel
counterparties conflict on is the output from their shared funding tx. Any
kind of limit on spending this prevout can be monopolized by a spammy
attacker. For example, if you only allow 1 per minute, the attacker will
just race to take up that slot every minute to prevent the honest party's
transaction from being accepted.
This is similar to the pinning attack based on monopolizing the
transaction's descendant limit, except we can't carve out an exemption
because we wouldn't know whose replacement we're looking at.

@tbast:
> The way I understand it, limiting the impact on descendant transactions
is only important for DoS protection, not for incentive compatibility.

> I believe it's completely ok to require increasing both the fees and
feerate if we don't take descendants into account, because you control your
ancestor set - whereas the descendant set may be completely out of your
control.

Ignoring descendants of direct conflicts would certainly make our lives
much easier! Unfortunately, I don't think we can do this since they can be
fee bumps, i.e., in AJ's example. Considering descendants is important for
both incentive compatibility and DoS.
If the replacement transaction has a higher feerate than its direct
conflict, but the direct conflict also has high feerate descendants, we
might end up with lower fees and/or feerates by accepting the replacement.

@aj:
> I wonder sometimes if it could be sufficient to just have a relay rate
limit and prioritise by ancestor feerate though. Maybe something like:
>
> - instead of adding txs to each peers setInventoryTxToSend immediately,
>   set a mempool flag "relayed=3Dfalse"
>
> - on a time delay, add the top N (by fee rate) "relayed=3Dfalse" txs to
>   each peer's setInventoryTxToSend and mark them as "relayed=3Dtrue";
>   calculate how much kB those txs were, and do this again after
>   SIZE/RATELIMIT seconds
>
> - don't include "relayed=3Dfalse" txs when building blocks?

Wow cool! I think outbound tx relay size-based rate-limiting and
prioritizing tx relay by feerate are great ideas for preventing spammers
from wasting bandwidth network-wide. I agree, this would slow the low
feerate spam down, preventing a huge network-wide bandwidth spike. And it
would allow high feerate transactions to propagate as they should,
regardless of how busy traffic is. Combined with inbound tx request
rate-limiting, might this be sufficient to prevent DoS regardless of the
fee-based replacement policies?

One point that I'm not 100% clear on: is it ok to prioritize the
transactions by ancestor feerate in this scheme? As I described in the
original post, this can be quite different from the actual feerate we would
consider a transaction in a block for. The transaction could have a high
feerate sibling bumping its ancestor.
For example, A (1sat/vB) has 2 children: B (49sat/vB) and C (5sat/vB). If
we just received C, it would be incorrect to give it a priority equal to
its ancestor feerate (3sat/vB) because if we constructed a block template
now, B would bump A, and C's new ancestor feerate is 5sat/vB.
Then, if we imagine that top N is >5sat/vB, we're not relaying C. If we
also exclude C when building blocks, we're missing out on good fees.

> - keep high-feerate evicted txs around for a while in case they get
>   mined by someone else to improve compact block relay, a la the
>   orphan pool?

Replaced transactions are already added to vExtraTxnForCompact :D

@ariard
> Deployment of Taproot opens interesting possibilities in the
vaults/payment channels design space, where the tapscripts can commit to
different set of timelocks/quorum of keys. Even if the pre-signed states
stay symmetric, whoever is the publisher, the feerate cost to spend can
fluctuate.

Indeed, perhaps with taproot we may legitimately have
same-txid-different-witness transactions as a normal thing rather than rare
edge case. But as with everything enabled by taproot, I wouldn't count our
tapscript eggs until a concrete use case hatches and/or an application
actually implements it.

> How this new replacement rule would behave if you have a parent in the
"replace-by-feerate" half but the child is in the "replace-by-fee" one ?

Thanks for considering my suggestion! This particular scenario is not
possible, since a child cannot be considered for the next block without its
parent. But if the original transactions are found both in and outside the
next block, I think it would be fine to just require both are met.

> Overall, I think there is the deployment issue to warn of. Moving to a
new set of RBF rules implies for a lot of Bitcoin applications to rewrite
their RBF logics.

I agree that transitioning as painlessly as possible would be a huge
priority in any kind of upgrade to mempool policy. I'm very interested in
hearing wallet devs' feedback on this.
I'm also not actually clear on what backwards compatibility in this
scenario would look like. I imagine it to mean we run both sets of RBF
rules and accept the replacement if it passes either one. Or do we only
accept the replacement if it passes both?
For wallets, AJ's "All you need is for there to be *a* path that follows
the new relay rules and gets from your node/wallet to perhaps 10% of
hashpower" makes sense to me (which would be the former). For merchants who
care more about making sure the original transaction isn't replaceable,
would they prefer that either policy is sufficient to prevent a replacement
(more in line with the latter)? Or is that covered by signaling / am I
overthinking this?

Thanks,
Gloria

On Mon, Feb 7, 2022 at 10:24 AM Bastien TEINTURIER via bitcoin-dev <
bitcoin-dev@lists.linuxfoundation.org> wrote:

> Good morning,
>
> > The tricky question is what happens when X arrives on its own and it
> > might be that no one ever sends a replacement for B,C,D)
>
> It feels ok to me, but this is definitely arguable.
>
> It covers the fact that B,C,D could have been fake transactions whose
> sole purpose was to do a pinning attack: in that case the attacker would
> have found a way to ensure these transactions don't confirm anyway (or
> pay minimal/negligible fees).
>
> If these transactions were legitimate, I believe that their owners would
> remake them at some point (because these transactions reflect a business
> relationship that needed to happen, so it should very likely still
> happen). It's probably hard to verify because the new corresponding
> transactions may have nothing in common with the first, but I think the
> simplifications it offers for wallets is worth it (which is just my
> opinion and needs more scrutiny/feedback).
>
> > But if your backlog's feerate does drop off, *and* that matters, then
> > I don't think you can ignore the impact of the descendent transactions
> > that you might not get a replacement for.
>
> That is because you're only taking into account the current backlog, and
> not taking into account the fact that new items will be added to it soon
> to replace the evicted descendants. But I agree that this is a bet: we
> can't predict the future and guarantee these replacements will come.
>
> It is really a trade-off, ignoring descendents provides a much simpler
> contract that doesn't vary from one mempool to another, but when your
> backlog isn't full enough, you may lose some future profits if
> transactions don't come in later.
>
> > I think "Y% higher" rather than just "higher" is only useful for
> > rate-limiting, not incentive compatibility. (Though maybe it helps
> > stabilise a greedy algorithm in some cases?)
>
> That's true. I claimed these policies only address incentives, but using
> a percentage increase addresses rate-limiting a bit as well (I couldn't
> resist trying to do at least something for it!). I find it a very easy
> mechanism to implement, while choosing an absolute value is hard (it's
> always easier to think in relatives than absolutes).
>
> > This is why I think it is important to understand the rationales for
> introducing the rules in the first place
>
> I completely agree. As you mentioned, we are still in brainstorming
> phase, once (if?) we start to converge on what could be better policies,
> we do need to clearly explain each policy's expected goal. That will let
> future Bastien writing code in 2030 clearly highlight why the 2022 rules
> don't make sense anymore!
>
> Cheers,
> Bastien
>
> Le sam. 5 f=C3=A9vr. 2022 =C3=A0 14:22, Michael Folkson <
> michaelfolkson@protonmail.com> a =C3=A9crit :
>
>> Thanks for this Bastien (and Gloria for initially posting about this).
>>
>> I sympathetically skimmed the eclair PR (
>> https://github.com/ACINQ/eclair/pull/2113) dealing with replaceable
>> transactions fee bumping.
>>
>> There will continue to be a (hopefully) friendly tug of war on this
>> probably for the rest of Bitcoin's existence. I am sure people like Luke=
,
>> Prayank etc will (rightfully) continue to raise that Lightning and other
>> second layer protocols shouldn't demand that policy rules be changed if
>> there is a reason (e.g. DoS vector) for those rules on the base network.
>> But if there are rules that have no upside, introduce unnecessary
>> complexity for no reason and make Lightning implementers like Bastien's
>> life miserable attempting to deal with them I really hope we can make
>> progress on removing or simplifying them.
>>
>> This is why I think it is important to understand the rationales for
>> introducing the rules in the first place (and why it is safe to remove t=
hem
>> if indeed it is) and being as rigorous as possible on the rationales for
>> introducing additional rules. It sounds like from Gloria's initial post =
we
>> are still at a brainstorming phase (which is fine) but knowing what we k=
now
>> today I really hope we can learn from the mistakes of the original BIP 1=
25,
>> namely the Core implementation not matching the BIP and the sparse
>> rationales for the rules. As Bastien says this is not criticizing the
>> original BIP 125 authors, 7 years is a long time especially in Bitcoin
>> world and they probably weren't thinking about Bastien sitting down to
>> write an eclair PR in late 2021 (and reviewers of that PR) when they wro=
te
>> the BIP in 2015.
>>
>> --
>> Michael Folkson
>> Email: michaelfolkson at protonmail.com
>> Keybase: michaelfolkson
>> PGP: 43ED C999 9F85 1D40 EAF4 9835 92D6 0159 214C FEE3
>>
>>
>>
>> ------- Original Message -------
>> On Monday, January 31st, 2022 at 3:57 PM, Bastien TEINTURIER via
>> bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote:
>>
>> Hi Gloria,
>>
>> Many thanks for raising awareness on these issues and constantly pushing
>> towards finding a better model. This work will highly improve the
>> security of any multi-party contract trying to build on top of bitcoin
>> (because most multi-party contracts will need to have timeout conditions
>> and participants will need to make some transactions confirm before a
>> timeout happens - otherwise they may lose funds).
>>
>> For starters, let me quickly explain why the current rules are hard to
>> work with in the context of lightning (but I believe most L2 protocols
>> will have the same issues). Feel free to skip this part if you are
>> already convinced.
>>
>> ## Motivation
>>
>> The biggest pain point is BIP 125 rule 2.
>> If I need to increase the fees of a time-sensitive transaction because
>> the feerate has been rising since I broadcast it, I may need to also pay
>> high fees just to produce a confirmed utxo that I can use. I'm actually
>> paying a high fee twice instead of once (and needlessly using on-chain
>> space, our scarcest asset, because we could have avoided that additional
>> transaction!).
>>
>> It also has some annoying "non-determinism".
>> Imagine that my transaction has been evicted from my mempool because its
>> feerate was too low. I could think "Great, that means I don't have to
>> apply BIP 125 restrictions, I can just fund this transaction as if it
>> were a new one!". But actually I do, because my transaction could still
>> be in miner's mempools and I have no way of knowing it...this means that
>> whenever I have broadcast a transaction, I must assume that I will
>> always need to abide by whatever replacement rules the network applies.
>>
>> Fortunately, as far as I understand it, this rule only exists because of
>> a previous implementation detail of bitcoin core, so there's simply no
>> good reason to keep it.
>>
>> The second biggest pain point is rule 3. It prevents me from efficiently
>> using my capital while it's unconfirmed. Whenever I'm using a big utxo
>> to fund a transaction, I will get a big change output, and it would
>> really be a waste to be unable to use that change output to fund other
>> transactions. In order to be capital-efficient, I will end up creating
>> descendant trees for my time-sensitive transactions. But as Gloria
>> explained, replacing all my children will cost me an absurdly large
>> amount of fees. So what I'm actually planning to do instead is to RBF
>> one of the descendants high enough to get the whole tree confirmed.
>> But if those descendants' timeouts were far in the future, that's a
>> waste, I paid a lot more fees for them than I should have. I'd like to
>> just replace my transaction and republish the invalidated children
>> independently.
>>
>> Rule 4 doesn't hurt as much as the two previous ones, I don't have too
>> much to say about it.
>>
>> To be fair to the BIP 125 authors, all of these scenarios were very hard
>> to forecast at the time this BIP was created. We needed years to build
>> on those rules to get a better understanding of their limitations and if
>> the rationale behind them made sense in the long term.
>>
>> ## Proposals
>>
>> I believe that now is a good time to re-think those, and I really like
>> Gloria's categorization of the design constraints.
>>
>> I'd like to propose a different way of looking at descendants that makes
>> it easier to design the new rules. The way I understand it, limiting the
>> impact on descendant transactions is only important for DoS protection,
>> not for incentive compatibility. I would argue that after evictions,
>> descendant transactions will be submitted again (because they represent
>> transactions that people actually want to make), so evicting them does
>> not have a negative impact on mining incentives (in a world where blocks
>> are full most of the time).
>>
>> I'm curious to hear other people's thoughts on that. If it makes sense,
>> I would propose the following very simple rules:
>>
>> 1. The transaction's ancestor absolute fees must be X% higher than the
>> previous transaction's ancestor fees
>> 2. The transaction's ancestor feerate must be Y% higher than the
>> previous transaction's ancestor feerate
>>
>> I believe it's completely ok to require increasing both the fees and
>> feerate if we don't take descendants into account, because you control
>> your ancestor set - whereas the descendant set may be completely out of
>> your control.
>>
>> This is very easy to use by wallets, because the ancestor set is easy to
>> obtain. And an important point is that the ancestor set is the same in
>> every mempool, whereas the descendant set is not (your mempool may have
>> rejected the last descendants, while other people's mempools may still
>> contain them).
>>
>> Because of that reason, I'd like to avoid having a rule that relies on
>> some size of the replaced descendant set: it may be valid in your
>> mempool but invalid in someone else's, which makes it exploitable for
>> pinning attacks.
>>
>> I believe these rules are incentive compatible (again, if you accept
>> the fact that the descendants will be re-submitted and mined as well,
>> so their fees aren't lost).
>>
>> Can we choose X and Y so that these two rules are also DoS-resistant?
>> Unfortunately I'm not sure, so maybe we'll need to add a third rule to
>> address that. But before we do, can someone detail what it costs for a
>> node to evict a descendant tree? Given that bitcoin core doesn't allow
>> chains of more than 25 transactions, the maximum number of transactions
>> being replaced will be bounded by 25 * N (where N is the number of
>> outputs of the transaction being replaced). If it's just O(n) pruning of
>> a graph, maybe that's ok? Or maybe we make X or Y depend on the number
>> of outputs of the transaction being replaced (this would need very
>> careful thoughts)?
>>
>> If you made it this far, thanks for reading!
>> A couple of comments on the previous messages:
>>
>> > Currently, if we see a transaction
>> > that has the same txid as one in the mempool, we reject it as a
>> > duplicate, even if the feerate is much higher. It's unclear to me if
>> > we have a very strong reason to change this, but noting it as a
>> > limitation of our current replacement policy.
>>
>> I don't see a strong reason from an L2 protocol's point of view yet, but
>> there are many unkown unknowns. But from a miner incentive's point of
>> view, we should keep the transaction with the higher feerate, shouldn't
>> we? In that case it's also a more efficient use of on-chain space, which
>> is a win, right?
>>
>> > We might have a more-or-less long transition period during which we
>> support both...
>>
>> Yes, this is a long term thing.
>> Even if bitcoin core releases a new version with updated RBF rules, as a
>> wallet you'll need to keep using the old rules for a long time if you
>> want to be safe.
>>
>> But it's all the more reason to try to ship this as soon as possible,
>> this way maybe our grand-children will be able to benefit from it ;)
>> (just kidding on the timespan obviously).
>>
>> Cheers,
>> Bastien
>>
>> Le lun. 31 janv. 2022 =C3=A0 00:11, Antoine Riard via bitcoin-dev <
>> bitcoin-dev@lists.linuxfoundation.org> a =C3=A9crit :
>>
>>> Hi Gloria,
>>>
>>> Thanks for this RBF sum up. Few thoughts and more context comments if i=
t
>>> can help other readers.
>>>
>>> > For starters, the absolute fee pinning attack is especially
>>> > problematic if we apply the same rules (i.e. Rule #3 and #4) in
>>> > Package RBF. Imagine that Alice (honest) and Bob (adversary) share a
>>> > LN channel. The mempool is rather full, so their pre-negotiated
>>> > commitment transactions' feerates would not be considered high
>>> > priority by miners. Bob broadcasts his commitment transaction and
>>> > attaches a very large child (100KvB with 100,000sat in fees) to his
>>> > anchor output. Alice broadcasts her commitment transaction with a
>>> > fee-bumping child (200vB with 50,000sat fees which is a generous
>>> > 250sat/vB), but this does not meet the absolute fee requirement. She
>>> > would need to add another 50,000sat to replace Bob's commitment
>>> > transaction.
>>>
>>> Solving LN pinning attacks, what we're aiming for is enabling a fair
>>> feerate bid between the counterparties, thus either forcing the adversa=
ry
>>> to overbid or to disengage from the confirmation competition. If the
>>> replace-by-feerate rule is adopted, there shouldn't be an incentive for=
 Bob
>>> to
>>> pick up the first option. Though if he does, that's a winning outcome
>>> for Alice, as one of the commitment transactions confirms and her
>>> time-sensitive second-stage HTLC can be subsequently confirmed.
>>>
>>> > It's unclear to me if
>>> > we have a very strong reason to change this, but noting it as a
>>> > limitation of our current replacement policy. See [#24007][12].
>>>
>>> Deployment of Taproot opens interesting possibilities in the
>>> vaults/payment channels design space, where the tapscripts can commit t=
o
>>> different set of timelocks/quorum of keys. Even if the pre-signed state=
s
>>> stay symmetric, whoever is the publisher, the feerate cost to spend can
>>> fluctuate.
>>>
>>> > While this isn't completely broken, and the user interface is
>>> > secondary to the safety of the mempool policy
>>>
>>> I think with L2s transaction broadcast backend, the stability and
>>> clarity of the RBF user interface is primary. What we could be worried
>>> about is a too-much complex interface easing the way for an attacker to
>>> trigger your L2 node to issue policy-invalid chain of transactions.
>>> Especially, when we consider that an attacker might have leverage on ch=
ain
>>> of transactions composition ("force broadcast of commitment A then
>>> commitment B, knowing they will share a CPFP") or even transactions siz=
e
>>> ("overload commitment A with HTLCs").
>>>
>>> > * If the original transaction is in the top {0.75MvB, 1MvB} of the
>>> > mempool, apply the current rules (absolute fees must increase and
>>> > pay for the replacement transaction's new bandwidth). Otherwise, use =
a
>>> > feerate-only rule.
>>>
>>> How this new replacement rule would behave if you have a parent in the
>>> "replace-by-feerate" half but the child is in the "replace-by-fee" one =
?
>>>
>>> If we allow the replacement of the parent based on the feerate, we migh=
t
>>> decrease the top block absolute fees.
>>>
>>> If we block the replacement of the parent based on the feerate because
>>> the replacement absolute fees aren't above the replaced package, we sti=
ll
>>> preclude a pinning vector. The child might be low-feerate junk and even
>>> attached to a low ancestor-score branch.
>>>
>>> If I'm correct on this limitation, maybe we could turn off the
>>> "replace-by-fee" behavior as soon as the mempool is fulfilled with a fe=
w
>>> blocks ?
>>>
>>> > * Rate-limit how many replacements we allow per prevout.
>>>
>>> Depending on how it is implemented, though I would be concerned it
>>> introduces a new pinning vector in the context of shared-utxo. If it's =
a
>>> hardcoded constant, it could be exhausted by an adversary starting at t=
he
>>> lowest acceptable feerate then slowly increasing while still not reachi=
ng
>>> the top of the mempool. Same if it's time-based or block-based, no
>>> guarantee the replacement slot is honestly used by your counterparty.
>>>
>>> Further, an above-the-average replacement frequency might just be the
>>> reflection of your confirmation strategy reacting to block schedule or
>>> mempools historical data. As long as the feerate penalty is paid, I lea=
n to
>>> allow replacement.
>>>
>>> (One solution could be to associate per-user "tag" to the LN
>>> transactions, where each "tag" would have its own replacement slots, bu=
t
>>> privacy?)
>>>
>>> > * Rate-limit transaction validation in general, per peer.
>>>
>>> I think we could improve on the Core's new transaction requester logic.
>>> Maybe we could bind the peer announced flow based on the feerate score
>>> (modulo validation time) of the previously validated transactions from =
that
>>> peer ? That said, while related to RBF, it sounds to me that enhancing
>>> Core's rate-limiting transaction strategy is a whole discussion in itse=
lf
>>> [0]. Especially ensuring it's tolerant to the specific requirements of =
LN &
>>> consorts.
>>>
>>> > What should they be? We can do some arithmetic to see what happens if
>>> > you start with the biggest/lowest feerate transaction and do a bunch
>>> > of replacements. Maybe we end up with values that are high enough to
>>> > prevent abuse and make sense for applications/users that do RBF.
>>>
>>> That's a good question.
>>>
>>> One observation is that the attacker can always renew the set of DoSy
>>> utxos to pursue the attack. So maybe we could pick up constants scaled =
on
>>> the block size ? That way an attacker would have to burn fees, thus
>>> deterring them from launching an attack. Even if the attackers are mine=
rs,
>>> they have to renounce their income to acquire new DoSy utxos. If a low-=
fee
>>> period, we could scale up the constants ?
>>>
>>>
>>> Overall, I think there is the deployment issue to warn of. Moving to a
>>> new set of RBF rules implies for a lot of Bitcoin applications to rewri=
te
>>> their RBF logics. We might have a more-or-less long transition period
>>> during which we support both...
>>>
>>> Cheers,
>>> Antoine
>>>
>>> [0] https://github.com/bitcoin/bitcoin/pull/21224
>>>
>>> Le jeu. 27 janv. 2022 =C3=A0 09:10, Gloria Zhao via bitcoin-dev <
>>> bitcoin-dev@lists.linuxfoundation.org> a =C3=A9crit :
>>>
>>>> Hi everyone,
>>>>
>>>> This post discusses limitations of current Bitcoin Core RBF policy and
>>>> attempts to start a conversation about how we can improve it,
>>>> summarizing some ideas that have been discussed. Please reply if you
>>>> have any new input on issues to be solved and ideas for improvement!
>>>>
>>>> Just in case I've screwed up the text wrapping again, another copy can
>>>> be
>>>> found here:
>>>> https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff
>>>>
>>>> ## Background
>>>>
>>>> Please feel free to skip this section if you are already familiar
>>>> with RBF.
>>>>
>>>> Nodes may receive *conflicting* unconfirmed transactions, aka
>>>> "double spends" of the same inputs. Instead of always keeping the
>>>> first transaction, since v0.12, Bitcoin Core mempool policy has
>>>> included a set of Replace-by-Fee (RBF) criteria that allows the second
>>>> transaction to replace the first one and any descendants it may have.
>>>>
>>>> Bitcoin Core RBF policy was previously documented as BIP 125.
>>>> The current RBF policy is documented [here][1]. In summary:
>>>>
>>>> 1. The directly conflicting transactions all signal replaceability
>>>> explicitly.
>>>>
>>>> 2. The replacement transaction only includes an unconfirmed input if
>>>> that input was included in one of the directly conflicting
>>>> transactions.
>>>>
>>>> 3. The replacement transaction pays an absolute fee of at least the
>>>> sum paid by the original transactions.
>>>>
>>>> 4. The additional fees pays for the replacement transaction's
>>>> bandwidth at or above the rate set by the node's *incremental relay
>>>> feerate*.
>>>>
>>>> 5. The sum of all directly conflicting transactions' descendant counts
>>>> (number of transactions inclusive of itself and its descendants)
>>>> does not exceed 100.
>>>>
>>>> We can split these rules into 3 categories/goals:
>>>>
>>>> - **Allow Opting Out**: Some applications/businesses are unable to
>>>> handle transactions that are replaceable (e.g. merchants that use
>>>> zero-confirmation transactions). We (try to) help these businesses by
>>>> honoring BIP125 signaling; we won't replace transactions that have not
>>>> opted in.
>>>>
>>>> - **Incentive Compatibility**: Ensure that our RBF policy would not
>>>> accept replacement transactions which would decrease fee profits
>>>> of a miner. In general, if our mempool policy deviates from what is
>>>> economically rational, it's likely that the transactions in our
>>>> mempool will not match the ones in miners' mempools, making our
>>>> fee estimation, compact block relay, and other mempool-dependent
>>>> functions unreliable. Incentive-incompatible policy may also
>>>> encourage transaction submission through routes other than the p2p
>>>> network, harming censorship-resistance and privacy of Bitcoin payments=
.
>>>>
>>>> - **DoS Protection**: Limit two types of DoS attacks on the node's
>>>> mempool: (1) the number of times a transaction can be replaced and
>>>> (2) the volume of transactions that can be evicted during a
>>>> replacement.
>>>>
>>>> Even more abstract: our goal is to make a replacement policy that
>>>> results in a useful interface for users and safe policy for
>>>> node operators.
>>>>
>>>> ## Motivation
>>>>
>>>> There are a number of known problems with the current RBF policy.
>>>> Many of these shortcomings exist due to mempool limitations at the
>>>> time RBF was implemented or result from new types of Bitcoin usage;
>>>> they are not criticisms of the original design.
>>>>
>>>> ### Pinning Attacks
>>>>
>>>> The most pressing concern is that attackers may take advantage of
>>>> limitations in RBF policy to prevent other users' transactions from
>>>> being mined or getting accepted as a replacement.
>>>>
>>>> #### SIGHASH_ANYONECANPAY Pinning
>>>>
>>>> BIP125#2 can be bypassed by creating intermediary transactions to be
>>>> replaced together. Anyone can simply split a 1-input 1-output
>>>> transaction off from the replacement transaction, then broadcast the
>>>> transaction as is. This can always be done, and quite cheaply. More
>>>> details in [this comment][2].
>>>>
>>>> In general, if a transaction is signed with SIGHASH\_ANYONECANPAY,
>>>> anybody can just attach a low feerate parent to this transaction and
>>>> lower its ancestor feerate. Even if you require SIGHASH\_ALL which
>>>> prevents an attacker from changing any outputs, the input can be a
>>>> very low amount (e.g. just above the dust limit) from a low-fee
>>>> ancestor and still bring down the ancestor feerate of the transaction.
>>>>
>>>> TLDR: if your transaction is signed with SIGHASH\_ANYONECANPAY and
>>>> signals replaceability, regardless of the feerate you broadcast at, an
>>>> attacker can lower its mining priority by adding an ancestor.
>>>>
>>>> #### Absolute Fee
>>>>
>>>> The restriction of requiring replacement transactions to increase the
>>>> absolute fee of the mempool has been described as "bonkers." If the
>>>> original transaction has a very large descendant that pays a large
>>>> amount of fees, even if it has a low feerate, the replacement
>>>> transaction must now pay those fees in order to meet Rule #3.
>>>>
>>>> #### Package RBF
>>>>
>>>> There are a number of reasons why, in order to enable Package RBF, we
>>>> cannot use the same criteria.
>>>>
>>>> For starters, the absolute fee pinning attack is especially
>>>> problematic if we apply the same rules (i.e. Rule #3 and #4) in
>>>> Package RBF. Imagine that Alice (honest) and Bob (adversary) share a
>>>> LN channel. The mempool is rather full, so their pre-negotiated
>>>> commitment transactions' feerates would not be considered high
>>>> priority by miners. Bob broadcasts his commitment transaction and
>>>> attaches a very large child (100KvB with 100,000sat in fees) to his
>>>> anchor output. Alice broadcasts her commitment transaction with a
>>>> fee-bumping child (200vB with 50,000sat fees which is a generous
>>>> 250sat/vB), but this does not meet the absolute fee requirement. She
>>>> would need to add another 50,000sat to replace Bob's commitment
>>>> transaction.
>>>>
>>>> Disallowing new unconfirmed inputs (Rule #2) in Package RBF would be
>>>> broken for packages containing transactions already in the mempool,
>>>> explained [here][7].
>>>>
>>>> Note: I originally [proposed][6] Package RBF using the same Rule #3
>>>> and #4 before I realized how significant this pinning attack is. I'm
>>>> retracting that proposal, and a new set of Package RBF rules would
>>>> follow from whatever the new individual RBF rules end up being.
>>>>
>>>> #### Same Txid Different Witness
>>>>
>>>> Two transactions with the same non-witness data but different
>>>> witnesses have the same txid but different wtxid, and the same fee but
>>>> not necessarily the same feerate. Currently, if we see a transaction
>>>> that has the same txid as one in the mempool, we reject it as a
>>>> duplicate, even if the feerate is much higher. It's unclear to me if
>>>> we have a very strong reason to change this, but noting it as a
>>>> limitation of our current replacement policy. See [#24007][12].
>>>>
>>>> ### User Interface
>>>>
>>>> #### Using Unconfirmed UTXOs to Fund Replacements
>>>>
>>>> The restriction of only allowing confirmed UTXOs for funding a
>>>> fee-bump (Rule #2) can hurt users trying to fee-bump their
>>>> transactions and complicate wallet implementations. If the original
>>>> transaction's output value isn't sufficient to fund a fee-bump and/or
>>>> all of the user's other UTXOs are unconfirmed, they might not be able
>>>> to fund a replacement transaction. Wallet developers also need to
>>>> treat self-owned unconfirmed UTXOs as unusable for fee-bumping, which
>>>> adds complexity to wallet logic. For example, see BDK issues [#144][4]
>>>> and [#414][5].
>>>>
>>>> #### Interface Not Suitable for Coin Selection
>>>>
>>>> Currently, a user cannot simply create a replacement transaction
>>>> targeting a specific feerate or meeting a minimum fee amount and
>>>> expect to meet the RBF criteria. The fee amount depends on the size of
>>>> the replacement transaction, and feerate is almost irrelevant.
>>>>
>>>> Bitcoin Core's `bumpfee` doesn't use the RBF rules when funding the
>>>> replacement. It [estimates][13] a feerate which is "wallet incremental
>>>> relay fee" (a conservative overestimation of the node's incremental
>>>> relay fee) higher than the original transaction, selects coins for
>>>> that feerate, and hopes that it meets the RBF rules. It never fails
>>>> Rule #3 and #4 because it uses all original inputs and refuses to
>>>> bump a transaction with mempool descendants.
>>>>
>>>> This is suboptimal, but is designed to work with the coin selection
>>>> engine: select a feerate first, and then add fees to cover it.
>>>> Following the exact RBF rules would require working the other way
>>>> around: based on how much fees we've added to the transaction and its
>>>> current size, calculate the feerate to see if we meet Rule #4.
>>>>
>>>> While this isn't completely broken, and the user interface is
>>>> secondary to the safety of the mempool policy, we can do much better.
>>>> A much more user-friendly interface would depend *only* on the
>>>> fee and size of the original transactions.
>>>>
>>>> ### Updates to Mempool and Mining
>>>>
>>>> Since RBF was first implemented, a number of improvements have been
>>>> made to mempool and mining logic. For example, we now use ancestor
>>>> feerates in mining (allowing CPFP), and keep track of ancestor
>>>> packages in the mempool.
>>>>
>>>> ## Ideas for Improvements
>>>>
>>>> ### Goals
>>>>
>>>> To summarize, these seem to be desired changes, in order of priority:
>>>>
>>>> 1. Remove Rule #3. The replacement should not be *required* to pay
>>>> higher absolute fees.
>>>>
>>>> 2. Make it impossible for a replacement transaction to have a lower
>>>> mining score than the original transaction(s). This would eliminate
>>>> the `SIGHASH\_ANYONECANPAY` pinning attack.
>>>>
>>>> 3. Remove Rule #2. Adding new unconfirmed inputs should be allowed.
>>>>
>>>> 4. Create a more helpful interface that helps wallet fund replacement
>>>> transactions that aim for a feerate and fee.
>>>>
>>>> ### A Different Model for Fees
>>>>
>>>> For incentive compatibility, I believe there are different
>>>> formulations we should consider. Most importantly, if we want to get
>>>> rid of the absolute fee rule, we can no longer think of it as "the
>>>> transaction needs to pay for its own bandwidth," since we won't always
>>>> be getting additional fees. That means we need a new method of
>>>> rate-limiting replacements that doesn't require additional fees every
>>>> time.
>>>>
>>>> While it makes sense to think about monetary costs when launching a
>>>> specific type of attack, given that the fees are paid to the miner and
>>>> not to the mempool operators, maybe it doesn't make much sense to
>>>> think about "paying for bandwidth". Maybe we should implement
>>>> transaction validation rate-limiting differently, e.g. building it
>>>> into the P2P layer instead of the mempool policy layer.
>>>>
>>>> Recently, Suhas gave a [formulation][8] for incentive compatibility
>>>> that made sense to me: "are the fees expected to be paid in the next
>>>> (N?) blocks higher or lower if we process this transaction?"
>>>>
>>>> I started by thinking about this where N=3D1 or `1 + p`.
>>>> Here, a rational miner is looking at what fees they would
>>>> collect in the next block, and then some proportion `p` of the rest of
>>>> the blocks based on their hashrate. We're assuming `p` isn't *so high*
>>>> that they would be okay with lower absolute fees in the next 1 block.
>>>> We're also assuming `p` isn't *so low* that the miner doesn't care
>>>> about what's left of the mempool after this block.
>>>>
>>>> A tweak to this formulation is "if we process this transaction, would
>>>> the fees in the next 1 block higher or lower, and is the feerate
>>>> density of the rest of the mempool higher or lower?" This is pretty
>>>> similar, where N=3D1, but we consider the rest of the mempool by feera=
te
>>>> rather than fees.
>>>>
>>>> ### Mining Score of a Mempool Transaction
>>>>
>>>> We are often interested in finding out what
>>>> the "mining score" of a transaction in the mempool is. That is, when
>>>> the transaction is considered in block template building, what is the
>>>> feerate it is considered at?
>>>>
>>>> Obviously, it's not the transaction's individual feerate. Bitcoin Core
>>>> [mining code sorts][14] transactions by their ancestor feerate and
>>>> includes them packages at a time, keeping track of how this affects th=
e
>>>> package feerates of remaining transactions in the mempool.
>>>>
>>>> *ancestor feerate*: Ancestor feerate is easily accessible information,
>>>> but it's not accurate either, because it doesn't take into account the
>>>> fact that subsets of a transaction's ancestor set can be included
>>>> without it. For example, ancestors may have high feerates on their own
>>>> or we may have [high feerate siblings][8].
>>>>
>>>> TLDR: *Looking at the current ancestor feerate of a transaction is
>>>> insufficient to tell us what feerate it will be considered at when
>>>> building a block template in the future.*
>>>>
>>>> *min(individual feerate, ancestor feerate)*: Another
>>>> heuristic that is simple to calculate based on current mempool tooling
>>>> is to use the [minimum of a transaction's individual score and its
>>>> ancestor score][10] as a conservative measure. But this can
>>>> overestimate as well (see the example below).
>>>>
>>>> *min ancestor feerate(tx + possible ancestor subsets)* We can also
>>>> take the minimum of every possible ancestor subset, but this can be
>>>> computationally expensive since there can be lots and lots of ancestor
>>>> subsets.
>>>>
>>>> *max ancestor feerate(tx + possible descendant subsets)*: Another idea
>>>> is to use the [maximum ancestor score of the transaction + each of its
>>>> descendants][9]. This doesn't work either; it has the same blindspot
>>>> of ancestor subsets being mined on their own.
>>>>
>>>> #### Mining Score Example
>>>>
>>>> Here's an example illustrating why mining score is tricky to
>>>> efficiently calculate for mempool transactions:
>>>>
>>>> Let's say you have same-size transactions A (21sat/vB), B (1sat/vB),
>>>> C(9sat/vB), D(5sat/vB).
>>>> The layout is: grandparent A, parent B, and two children C and D.
>>>>
>>>> ```
>>>> A
>>>> ^
>>>> B
>>>> ^ ^
>>>> C D
>>>> ```
>>>>
>>>> A miner using ancestor packages to build block templates will first
>>>> include A with a mining score of 21. Next, the miner will include B an=
d
>>>> C with a mining score of 6. This leaves D, with a mining score of 5.
>>>>
>>>> Note: in this case, mining by ancestor feerate results in the most
>>>> rational decisions, but [a candidate set-based approach][10] which
>>>> makes ancestor feerate much less relevant could
>>>> be more advantageous in other situations.
>>>>
>>>> Here is a chart showing the "true" mining score alongside the values
>>>> calculating using imperfect heuristics described above. All of them
>>>> can overestimate or underestimate.
>>>>
>>>> ```
>>>> A B C D
>>>> mining score | 21 | 6 | 6 | 5 |
>>>> ancestor feerate | 21 | 11 | 10.3 | 9 |
>>>> min(individual, ancestor) | 21 | 1 | 9 | 5 |
>>>> min(tx + ancestor subsets) | 21 | 1 | 5 | 3 |
>>>> max(tx + descendants subsets) | 21 | 9 | 9 | 5 |
>>>>
>>>> ```
>>>>
>>>> Possibly the best solution for finding the "mining score" of a
>>>> transaction is to build a block template, see what feerate each
>>>> package is included at. Perhaps at some cutoff, remaining mempool
>>>> transactions can be estimated using some heuristic that leans
>>>> {overestimating, underestimating} depending on the situation.
>>>>
>>>> Mining score seems to be relevant in multiple places: Murch and I
>>>> recently [found][3] that it would be very important in
>>>> "ancestor-aware" funding of transactions (the wallet doesn't
>>>> incorporate ancestor fees when using unconfirmed transactions in coin
>>>> selection, which is a bug we want to fix).
>>>>
>>>> In general, it would be nice to know the exact mining priority of
>>>> one's unconfirmed transaction is. I can think of a few block/mempool
>>>> explorers who might want to display this information for users.
>>>>
>>>> ### RBF Improvement Proposals
>>>>
>>>> After speaking to quite a few people, here are some suggestions
>>>> for improvements that I have heard:
>>>>
>>>> * The ancestor score of the replacement must be {5, 10, N}% higher
>>>> than that of every original transaction.
>>>>
>>>> * The ancestor score of the replacement must be 1sat/vB higher than
>>>> that of every original transaction.
>>>>
>>>> * If the original transaction is in the top {0.75MvB, 1MvB} of the
>>>> mempool, apply the current rules (absolute fees must increase and
>>>> pay for the replacement transaction's new bandwidth). Otherwise, use a
>>>> feerate-only rule.
>>>>
>>>> * If fees don't increase, the size of the replacement transaction must
>>>> decrease by at least N%.
>>>>
>>>> * Rate-limit how many replacements we allow per prevout.
>>>>
>>>> * Rate-limit transaction validation in general, per peer.
>>>>
>>>> Perhaps some others on the mailing list can chime in to throw other
>>>> ideas into the ring and/or combine some of these rules into a sensible
>>>> policy.
>>>>
>>>> #### Replace by Feerate Only
>>>>
>>>> I don't think there's going to be a single-line feerate-based
>>>> rule that can incorporate everything we need.
>>>> On one hand, a feerate-only approach helps eliminate the issues
>>>> associated with Rule #3. On the other hand, I believe the main concern
>>>> with a feerate-only approach is how to rate limit replacements. We
>>>> don't want to enable an attack such as:
>>>>
>>>> 1. Attacker broadcasts large, low-feerate transaction, and attaches a
>>>> chain of descendants.
>>>>
>>>> 2. The attacker replaces the transaction with a smaller but higher
>>>> feerate transaction, attaching a new chain of descendants.
>>>>
>>>> 3. Repeat 1000 times.
>>>>
>>>> #### Fees in Next Block and Feerate for the Rest of the Mempool
>>>>
>>>> Perhaps we can look at replacements like this:
>>>>
>>>> 1. Calculate the directly conflicting transactions and, with their
>>>> descendants, the original transactions. Check signaling. Limit the
>>>> total volume (e.g. can't be more than 100 total or 1MvB or something).
>>>>
>>>> 2. Find which original transactions would be in the next ~1 block. The
>>>> replacement must pay at least this amount + X% in absolute fees. This
>>>> guarantees that the fees of the next block doesn't decrease.
>>>>
>>>> 3. Find which transactions would be left in the mempool after that ~1
>>>> block. The replacement's feerate must be Y% higher than the maximum
>>>> mining score of these transactions. This guarantees that you now have
>>>> only *better* candidates in your after-this-block mempool than you did
>>>> before, even if the size and fees the transactions decrease.
>>>>
>>>> 4. Now you have two numbers: a minimum absolute fee amount and a
>>>> minimum feerate. Check to see if the replacement(s) meet these
>>>> minimums. Also, a wallet would be able to ask the node "What fee and
>>>> feerate would I need to put on a transaction replacing this?" and use
>>>> this information to fund a replacement transaction, without needing to
>>>> guess or overshoot.
>>>>
>>>> Obviously, there are some magic numbers missing here. X and Y are
>>>> TBD constants to ensure we have some kind of rate limiting for the
>>>> number of replacements allowed using some set of fees.
>>>>
>>>> What should they be? We can do some arithmetic to see what happens if
>>>> you start with the biggest/lowest feerate transaction and do a bunch
>>>> of replacements. Maybe we end up with values that are high enough to
>>>> prevent abuse and make sense for applications/users that do RBF.
>>>>
>>>> ### Mempool Changes Need for Implementation
>>>>
>>>> As described in the mining score section above,
>>>> we may want additional tooling to more accurately assess
>>>> the economic gain of replacing transactions in our mempool.
>>>>
>>>> A few options have been discussed:
>>>>
>>>> * Calculate block templates on the fly when we need to consider a
>>>> replacement. However, since replacements are [quite common][11]
>>>> and the information might be useful for other things as well,
>>>> it may be worth it to cache a block template.
>>>>
>>>> * Keep a persistent block template so that we know what transactions
>>>> we would put in the next block. We need to remember the feerate
>>>> at which each transaction was included in the template, because an
>>>> ancestor package may be included in the same block template in
>>>> multiple subsets. Transactions included earlier alter the ancestor
>>>> feerate of the remaining transactions in the package. We also need
>>>> to keep track of the new feerates of transactions left over.
>>>>
>>>> * Divide the mempool into two layers, "high feerate" and "low
>>>> feerate." The high feerate layer contains ~1 block of packages with
>>>> the highest ancestor feerates, and the low feerate layer contains
>>>> everything else. At the edge of a block, we have a Knapsacky problem
>>>> where the next highest ancestor feerate package might not fit, so we
>>>> would probably want the high feerate layer ~2MvB or something to avoid
>>>> underestimating the fees.
>>>>
>>>> ## Acknowledgements
>>>>
>>>> Thank you to everyone whose RBF-related suggestions, grievances,
>>>> criticisms and ideas were incorporated in this document:
>>>> Andrew Chow, Matt Corallo, Suhas Daftuar, Christian Decker,
>>>> Mark Erhardt, Lloyd Fournier, Lisa Neigut, John Newbery,
>>>> Antoine Poinsot, Antoine Riard, Larry Ruane,
>>>> S3RK and Bastien Teinturier.
>>>>
>>>> Thanks for reading!
>>>>
>>>> Best,
>>>> Gloria
>>>>
>>>> [1]:
>>>> https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-repl=
acements.md
>>>> [2]:
>>>> https://github.com/bitcoin/bitcoin/pull/23121#issuecomment-929475999
>>>> [3]:
>>>> https://github.com/Xekyo/bitcoin/commit/d754b0242ec69d42c570418aebf9c1=
335af0b8ea
>>>> [4]: https://github.com/bitcoindevkit/bdk/issues/144
>>>> [5]: https://github.com/bitcoindevkit/bdk/issues/414
>>>> [6]:
>>>> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September=
/019464.html
>>>> [7]:
>>>> https://gist.github.com/glozow/dc4e9d5c5b14ade7cdfac40f43adb18a#new-un=
confirmed-inputs-rule-2
>>>> [8]:
>>>> https://github.com/bitcoin/bitcoin/pull/23121#discussion_r777131366
>>>> [9]:
>>>> https://github.com/bitcoin/bitcoin/pull/22290#issuecomment-865887922
>>>> [10]:
>>>> https://gist.github.com/Xekyo/5cb413fe9f26dbce57abfd344ebbfaf2#file-ca=
ndidate-set-based-block-building-md
>>>> [11]:
>>>> https://github.com/bitcoin/bitcoin/pull/22539#issuecomment-885763670
>>>> [12]: https://github.com/bitcoin/bitcoin/pull/24007
>>>> [13]:
>>>> https://github.com/bitcoin/bitcoin/blob/1a369f006fd0bec373b95001ed84b4=
80e852f191/src/wallet/feebumper.cpp#L114
>>>> [14]:
>>>> https://github.com/bitcoin/bitcoin/blob/cf5bb048e80d4cde8828787b266b7f=
5f2e3b6d7b/src/node/miner.cpp#L310-L320
>>>> _______________________________________________
>>>> 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
>>>
>>
>> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists.linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

--000000000000ec51c205d76bbb39
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hi everyone,<br><br>Thanks for giving your attention =
to the post! I haven&#39;t had time to write responses to everything, but s=
ending my thoughts about what has been most noteworthy to me:<br><br>@jerem=
y:<br>&gt; A final point is that a verifiable delay function could be used =
over, e.g., each of the N COutpoints individually to rate-limit transaction=
 replacement. The VDF period can be made shorter / eliminated depending on =
the feerate increase.<br><br>Thanks for the suggestion! In general, I don&#=
39;t think rate limiting by outpoint/prevout is a safe option, as it is par=
ticularly dangerous for L2 applications with shared prevouts. For example, =
the prevout that LN channel counterparties conflict on is the output from t=
heir shared funding tx. Any kind of limit on spending this prevout can be m=
onopolized by a spammy attacker. For example, if you only allow 1 per minut=
e, the attacker will just race to take up that slot every minute to prevent=
 the honest party&#39;s transaction from being accepted.<br>This is similar=
 to the pinning attack based on monopolizing the transaction&#39;s descenda=
nt limit, except we can&#39;t carve out an exemption because we wouldn&#39;=
t know whose replacement we&#39;re looking at.<br><br>@tbast:<br>&gt; The w=
ay I understand it, limiting the impact on descendant transactions is only =
important for DoS protection, not for incentive compatibility.<br><br>&gt; =
I believe it&#39;s completely ok to require increasing both the fees and fe=
erate if we don&#39;t take descendants into account, because you control yo=
ur ancestor set - whereas the descendant set may be completely out of your =
control.<br><br>Ignoring descendants of direct conflicts would certainly ma=
ke our lives much easier! Unfortunately, I don&#39;t think we can do this s=
ince they can be fee bumps, i.e., in AJ&#39;s example. Considering descenda=
nts is important for both incentive compatibility and DoS.</div><div>If the=
 replacement transaction has a higher feerate than its direct conflict, but=
 the direct conflict also has high feerate descendants, we might end up wit=
h lower fees and/or feerates by accepting the replacement.<br></div><div><b=
r></div><div>@aj:<br></div><div>&gt; I wonder sometimes if it could be suff=
icient to just have a relay rate limit and prioritise by ancestor feerate t=
hough. Maybe something like:<br>&gt;<br>&gt; - instead of adding txs to eac=
h peers setInventoryTxToSend immediately,<br>&gt; =C2=A0 set a mempool flag=
 &quot;relayed=3Dfalse&quot;<br>&gt;<br>&gt; - on a time delay, add the top=
 N (by fee rate) &quot;relayed=3Dfalse&quot; txs to<br>&gt; =C2=A0 each pee=
r&#39;s setInventoryTxToSend and mark them as &quot;relayed=3Dtrue&quot;;<b=
r>&gt; =C2=A0 calculate how much kB those txs were, and do this again after=
<br>&gt; =C2=A0 SIZE/RATELIMIT seconds<br>&gt;<br>&gt; - don&#39;t include =
&quot;relayed=3Dfalse&quot; txs when building blocks?<br><br>Wow cool! I th=
ink outbound tx relay size-based rate-limiting and prioritizing tx relay by=
 feerate are great ideas for preventing spammers from wasting bandwidth net=
work-wide. I agree, this would slow the low feerate spam down, preventing a=
 huge network-wide bandwidth spike. And it would allow high feerate transac=
tions to propagate as they should, regardless of how busy traffic is. Combi=
ned with inbound tx request rate-limiting, might this be sufficient to prev=
ent DoS regardless of the fee-based replacement policies?<br><br>One point =
that I&#39;m not 100% clear on: is it ok to prioritize the transactions by =
ancestor feerate in this scheme? As I described in the original post, this =
can be quite different from the actual feerate we would consider a transact=
ion in a block for. The transaction could have a high feerate sibling bumpi=
ng its ancestor.<br>For example, A (1sat/vB) has 2 children: B (49sat/vB) a=
nd C (5sat/vB). If we just received C, it would be incorrect to give it a p=
riority equal to its ancestor feerate (3sat/vB) because if we constructed a=
 block template now, B would bump A, and C&#39;s new ancestor feerate is 5s=
at/vB.<br>Then, if we imagine that top N is &gt;5sat/vB, we&#39;re not rela=
ying C. If we also exclude C when building blocks, we&#39;re missing out on=
 good fees.<br><br>&gt; - keep high-feerate evicted txs around for a while =
in case they get<br>&gt; =C2=A0 mined by someone else to improve compact bl=
ock relay, a la the<br>&gt; =C2=A0 orphan pool?<br><br>Replaced transaction=
s are already added to vExtraTxnForCompact :D</div><div><br>@ariard<br>&gt;=
 Deployment of Taproot opens interesting possibilities in the vaults/paymen=
t channels design space, where the tapscripts can commit to different set o=
f timelocks/quorum of keys. Even if the pre-signed states stay symmetric, w=
hoever is the publisher, the feerate cost to spend can fluctuate.<br><br>In=
deed, perhaps with taproot we may legitimately have same-txid-different-wit=
ness transactions as a normal thing rather than rare edge case. But as with=
 everything enabled by taproot, I wouldn&#39;t count our tapscript eggs unt=
il a concrete use case hatches and/or an application actually implements it=
.<br><br>&gt; How this new replacement rule would behave if you have a pare=
nt in the &quot;replace-by-feerate&quot; half but the child is in the &quot=
;replace-by-fee&quot; one ?<br><br>Thanks for considering my suggestion! Th=
is particular scenario is not possible, since a child cannot be considered =
for the next block without its parent. But if the original transactions are=
 found both in and outside the next block, I think it would be fine to just=
 require both are met.</div><div><br></div><div>&gt; Overall, I think there=
 is the deployment issue to warn of. Moving to a new set of RBF rules impli=
es for a lot of Bitcoin applications to rewrite their RBF logics.</div><div=
><br></div><div>I agree that transitioning as painlessly as possible would =
be a huge priority in any kind of upgrade to mempool policy. I&#39;m very i=
nterested in hearing wallet devs&#39; feedback on this.<br>I&#39;m also not=
 actually clear on what backwards compatibility in this scenario would look=
 like. I imagine it to mean we run both sets of RBF rules and accept the re=
placement if it passes either one. Or do we only accept the replacement if =
it passes both?<br>For wallets, AJ&#39;s &quot;All you need is for there to=
 be *a* path that follows the new relay rules and gets from your node/walle=
t to perhaps 10% of hashpower&quot; makes sense to me (which would be the f=
ormer). For merchants who care more about making sure the original transact=
ion isn&#39;t replaceable, would they prefer that either policy is sufficie=
nt to prevent a replacement (more in line with the latter)? Or is that cove=
red by signaling / am I overthinking this?<br><br></div><div>Thanks,</div><=
div>Gloria<br></div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr" c=
lass=3D"gmail_attr">On Mon, Feb 7, 2022 at 10:24 AM Bastien TEINTURIER via =
bitcoin-dev &lt;<a href=3D"mailto:bitcoin-dev@lists.linuxfoundation.org">bi=
tcoin-dev@lists.linuxfoundation.org</a>&gt; wrote:<br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid =
rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>Good morning,</div=
><div><br></div>&gt; The tricky question is what happens when X arrives on =
its own and it<br>&gt; might be that no one ever sends a replacement for B,=
C,D)<br><br>It feels ok to me, but this is definitely arguable.<br><br>It c=
overs the fact that B,C,D could have been fake transactions whose<br>sole p=
urpose was to do a pinning attack: in that case the attacker would<br>have =
found a way to ensure these transactions don&#39;t confirm anyway (or<br>pa=
y minimal/negligible fees).<br><br>If these transactions were legitimate, I=
 believe that their owners would<br>remake them at some point (because thes=
e transactions reflect a business<br>relationship that needed to happen, so=
 it should very likely still<br>happen). It&#39;s probably hard to verify b=
ecause the new corresponding<br>transactions may have nothing in common wit=
h the first, but I think the<br>simplifications it offers for wallets is wo=
rth it (which is just my<br>opinion and needs more scrutiny/feedback).<br><=
br>&gt; But if your backlog&#39;s feerate does drop off, *and* that matters=
, then<br>&gt; I don&#39;t think you can ignore the impact of the descenden=
t transactions<br>&gt; that you might not get a replacement for.<br><br>Tha=
t is because you&#39;re only taking into account the current backlog, and<b=
r>not taking into account the fact that new items will be added to it soon<=
br>to replace the evicted descendants. But I agree that this is a bet: we<b=
r>can&#39;t predict the future and guarantee these replacements will come.<=
br><br>It is really a trade-off, ignoring descendents provides a much simpl=
er<br>contract that doesn&#39;t vary from one mempool to another, but when =
your<br>backlog isn&#39;t full enough, you may lose some future profits if<=
br>transactions don&#39;t come in later.<br><br>&gt; I think &quot;Y% highe=
r&quot; rather than just &quot;higher&quot; is only useful for<br>&gt; rate=
-limiting, not incentive compatibility. (Though maybe it helps<br>&gt; stab=
ilise a greedy algorithm in some cases?)<br><br>That&#39;s true. I claimed =
these policies only address incentives, but using<br>a percentage increase =
addresses rate-limiting a bit as well (I couldn&#39;t<br>resist trying to d=
o at least something for it!). I find it a very easy<br>mechanism to implem=
ent, while choosing an absolute value is hard (it&#39;s<br>always easier to=
 think in relatives than absolutes).<br><br>&gt; This is why I think it is =
important to understand the rationales for introducing the rules in the fir=
st place<br><br>I completely agree. As you mentioned, we are still in brain=
storming<br>phase, once (if?) we start to converge on what could be better =
policies,<br>we do need to clearly explain each policy&#39;s expected goal.=
 That will let<br>future Bastien writing code in 2030 clearly highlight why=
 the 2022 rules<br>don&#39;t make sense anymore!<br><br>Cheers,<br>Bastien<=
/div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">L=
e=C2=A0sam. 5 f=C3=A9vr. 2022 =C3=A0=C2=A014:22, Michael Folkson &lt;<a hre=
f=3D"mailto:michaelfolkson@protonmail.com" target=3D"_blank">michaelfolkson=
@protonmail.com</a>&gt; a =C3=A9crit=C2=A0:<br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204=
,204,204);padding-left:1ex"><div style=3D"font-family:arial;font-size:14px"=
><div style=3D"font-family:arial;font-size:14px">Thanks for this Bastien (a=
nd Gloria for initially posting about this).<br></div><div style=3D"font-fa=
mily:arial;font-size:14px"><br></div><div style=3D"font-family:arial;font-s=
ize:14px">I sympathetically skimmed the eclair PR (<a href=3D"https://githu=
b.com/ACINQ/eclair/pull/2113" target=3D"_blank">https://github.com/ACINQ/ec=
lair/pull/2113</a>) dealing with replaceable transactions fee bumping.<br><=
/div><div style=3D"font-family:arial;font-size:14px"><br></div><div style=
=3D"font-family:arial;font-size:14px">There will continue to be a (hopefull=
y) friendly tug of war on this probably for the rest of Bitcoin&#39;s exist=
ence. I am sure people like Luke, Prayank etc will (rightfully) continue to=
 raise that Lightning and other second layer protocols shouldn&#39;t demand=
 that policy rules be changed if there is a reason (e.g. DoS vector) for th=
ose rules on the base network. But if there are rules that have no upside, =
introduce unnecessary complexity for no reason and make Lightning implement=
ers like Bastien&#39;s life miserable attempting to deal with them I really=
 hope we can make progress on removing or simplifying them.=C2=A0<br></div>=
<div style=3D"font-family:arial;font-size:14px"><br></div><div style=3D"fon=
t-family:arial;font-size:14px">This is why I think it is important to under=
stand the rationales for introducing the rules in the first place (and why =
it is safe to remove them if indeed it is) and being as rigorous as possibl=
e on the rationales for introducing additional rules. It sounds like from G=
loria&#39;s initial post we are still at a brainstorming phase (which is fi=
ne) but knowing what we know today I really hope we can learn from the mist=
akes of the original BIP 125, namely the Core implementation not matching t=
he BIP and the sparse rationales for the rules. As Bastien says this is not=
 criticizing the original BIP 125 authors, 7 years is a long time especiall=
y in Bitcoin world and they probably weren&#39;t thinking about Bastien sit=
ting down to write an eclair PR in late 2021 (and reviewers of that PR) whe=
n they wrote the BIP in 2015.<br></div><div style=3D"font-family:arial;font=
-size:14px"><br></div><div style=3D"font-family:arial;font-size:14px"><div>=
<div style=3D"font-family:arial;font-size:14px"><span style=3D"color:rgb(38=
,42,51);font-style:normal;font-weight:400;letter-spacing:normal;text-indent=
:0px;text-transform:none;white-space:pre-wrap;word-spacing:0px;background-c=
olor:rgb(255,255,255);float:none;display:inline"><span style=3D"font-family=
:SFMono-Regular,Consolas,&quot;Liberation Mono&quot;,Menlo,monospace,monosp=
ace"><span style=3D"font-size:14px">--<br>Michael Folkson<br>Email: michael=
folkson at </span></span></span><a rel=3D"noopener noreferrer" style=3D"lin=
e-height:normal;text-decoration:underline;font-family:SFMono-Regular,Consol=
as,&quot;Liberation Mono&quot;,Menlo,monospace,monospace;font-size:14px;fon=
t-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-t=
ransform:none;white-space:pre-wrap;word-spacing:0px" href=3D"http://protonm=
ail.com/" target=3D"_blank">protonmail.com</a><span style=3D"color:rgb(38,4=
2,51);font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0=
px;text-transform:none;white-space:pre-wrap;word-spacing:0px;background-col=
or:rgb(255,255,255);float:none;display:inline"><span style=3D"font-family:S=
FMono-Regular,Consolas,&quot;Liberation Mono&quot;,Menlo,monospace,monospac=
e"><span style=3D"font-size:14px"> </span></span></span></div><div style=3D=
"font-family:arial;font-size:14px"><span style=3D"color:rgb(38,42,51);font-=
style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-tra=
nsform:none;white-space:pre-wrap;word-spacing:0px;background-color:rgb(255,=
255,255);float:none;display:inline"><span style=3D"font-family:SFMono-Regul=
ar,Consolas,&quot;Liberation Mono&quot;,Menlo,monospace,monospace"><span st=
yle=3D"font-size:14px">Keybase: michaelfolkson<br>PGP: 43ED C999 9F85 1D40 =
EAF4 9835 92D6 0159 214C FEE3</span></span></span></div></div><div><br></di=
v></div><div><br></div></div><div style=3D"font-family:arial;font-size:14px=
"><br></div><div>
        ------- Original Message -------<br>
        On Monday, January 31st, 2022 at 3:57 PM, Bastien TEINTURIER via bi=
tcoin-dev &lt;<a href=3D"mailto:bitcoin-dev@lists.linuxfoundation.org" targ=
et=3D"_blank">bitcoin-dev@lists.linuxfoundation.org</a>&gt; wrote:<br>
        <blockquote type=3D"cite">
            <div dir=3D"ltr">Hi Gloria,<br><br>Many thanks for raising awar=
eness on these issues and constantly pushing<br>towards finding a better mo=
del. This work will highly improve the<br>security of any multi-party contr=
act trying to build on top of bitcoin<br>(because most multi-party contract=
s will need to have timeout conditions<br>and participants will need to mak=
e some transactions confirm before a<br>timeout happens - otherwise they ma=
y lose funds).<br><br>For starters, let me quickly explain why the current =
rules are hard to<br>work with in the context of lightning (but I believe m=
ost L2 protocols<br>will have the same issues). Feel free to skip this part=
 if you are<br>already convinced.<br><br>## Motivation<br><br>The biggest p=
ain point is BIP 125 rule 2.<br>If I need to increase the fees of a time-se=
nsitive transaction because<br>the feerate has been rising since I broadcas=
t it, I may need to also pay<br>high fees just to produce a confirmed utxo =
that I can use. I&#39;m actually<br>paying a high fee twice instead of once=
 (and needlessly using on-chain<br>space, our scarcest asset, because we co=
uld have avoided that additional<br>transaction!).<br><br>It also has some =
annoying &quot;non-determinism&quot;.<br>Imagine that my transaction has be=
en evicted from my mempool because its<br>feerate was too low. I could thin=
k &quot;Great, that means I don&#39;t have to<br>apply BIP 125 restrictions=
, I can just fund this transaction as if it<br>were a new one!&quot;. But a=
ctually I do, because my transaction could still<br>be in miner&#39;s mempo=
ols and I have no way of knowing it...this means that<br>whenever I have br=
oadcast a transaction, I must assume that I will<br>always need to abide by=
 whatever replacement rules the network applies.<br><br>Fortunately, as far=
 as I understand it, this rule only exists because of<br>a previous impleme=
ntation detail of bitcoin core, so there&#39;s simply no<br>good reason to =
keep it.<br><br>The second biggest pain point is rule 3. It prevents me fro=
m efficiently<br>using my capital while it&#39;s unconfirmed. Whenever I&#3=
9;m using a big utxo<br>to fund a transaction, I will get a big change outp=
ut, and it would<br>really be a waste to be unable to use that change outpu=
t to fund other<br>transactions. In order to be capital-efficient, I will e=
nd up creating<br>descendant trees for my time-sensitive transactions. But =
as Gloria<br>explained, replacing all my children will cost me an absurdly =
large<br>amount of fees. So what I&#39;m actually planning to do instead is=
 to RBF<br>one of the descendants high enough to get the whole tree confirm=
ed.<br>But if those descendants&#39; timeouts were far in the future, that&=
#39;s a<br>waste, I paid a lot more fees for them than I should have. I&#39=
;d like to<br>just replace my transaction and republish the invalidated chi=
ldren<br>independently.<br><br>Rule 4 doesn&#39;t hurt as much as the two p=
revious ones, I don&#39;t have too<br>much to say about it.<br><br>To be fa=
ir to the BIP 125 authors, all of these scenarios were very hard<br>to fore=
cast at the time this BIP was created. We needed years to build<br>on those=
 rules to get a better understanding of their limitations and if<br>the rat=
ionale behind them made sense in the long term.<br><br>## Proposals<br><br>=
I believe that now is a good time to re-think those, and I really like<br>G=
loria&#39;s categorization of the design constraints.<br><br>I&#39;d like t=
o propose a different way of looking at descendants that makes<br>it easier=
 to design the new rules. The way I understand it, limiting the<br>impact o=
n descendant transactions is only important for DoS protection,<br>not for =
incentive compatibility. I would argue that after evictions,<br>descendant =
transactions will be submitted again (because they represent<br>transaction=
s that people actually want to make), so evicting them does<br>not have a n=
egative impact on mining incentives (in a world where blocks<br>are full mo=
st of the time).<br><br>I&#39;m curious to hear other people&#39;s thoughts=
 on that. If it makes sense,<br>I would propose the following very simple r=
ules:<br><br>1. The transaction&#39;s ancestor absolute fees must be X% hig=
her than the<br>previous transaction&#39;s ancestor fees<br>2. The transact=
ion&#39;s ancestor feerate must be Y% higher than the<br>previous transacti=
on&#39;s ancestor feerate<br><br>I believe it&#39;s completely ok to requir=
e increasing both the fees and<br>feerate if we don&#39;t take descendants =
into account, because you control<br>your ancestor set - whereas the descen=
dant set may be completely out of<br>your control.<br><br>This is very easy=
 to use by wallets, because the ancestor set is easy to<br>obtain. And an i=
mportant point is that the ancestor set is the same in<br>every mempool, wh=
ereas the descendant set is not (your mempool may have<br>rejected the last=
 descendants, while other people&#39;s mempools may still<br>contain them).=
<br><br>Because of that reason, I&#39;d like to avoid having a rule that re=
lies on<br>some size of the replaced descendant set: it may be valid in you=
r<br>mempool but invalid in someone else&#39;s, which makes it exploitable =
for<br>pinning attacks.<br><br>I believe these rules are incentive compatib=
le (again, if you accept<br>the fact that the descendants will be re-submit=
ted and mined as well,<br>so their fees aren&#39;t lost).<br><br>Can we cho=
ose X and Y so that these two rules are also DoS-resistant?<br>Unfortunatel=
y I&#39;m not sure, so maybe we&#39;ll need to add a third rule to<br>addre=
ss that. But before we do, can someone detail what it costs for a<br>node t=
o evict a descendant tree? Given that bitcoin core doesn&#39;t allow<br>cha=
ins of more than 25 transactions, the maximum number of transactions<br>bei=
ng replaced will be bounded by 25 * N (where N is the number of<br>outputs =
of the transaction being replaced). If it&#39;s just O(n) pruning of<br>a g=
raph, maybe that&#39;s ok? Or maybe we make X or Y depend on the number<br>=
of outputs of the transaction being replaced (this would need very<br>caref=
ul thoughts)?<br><br>If you made it this far, thanks for reading!<br>A coup=
le of comments on the previous messages:<br><br>&gt; Currently, if we see a=
 transaction<br>&gt; that has the same txid as one in the mempool, we rejec=
t it as a<br>&gt; duplicate, even if the feerate is much higher. It&#39;s u=
nclear to me if<br>&gt; we have a very strong reason to change this, but no=
ting it as a<br>&gt; limitation of our current replacement policy.<br><br>I=
 don&#39;t see a strong reason from an L2 protocol&#39;s point of view yet,=
 but<br>there are many unkown unknowns. But from a miner incentive&#39;s po=
int of<br>view, we should keep the transaction with the higher feerate, sho=
uldn&#39;t<br>we? In that case it&#39;s also a more efficient use of on-cha=
in space, which<br>is a win, right?<br><br>&gt; We might have a more-or-les=
s long transition period during which we support both...<br><br>Yes, this i=
s a long term thing.<br>Even if bitcoin core releases a new version with up=
dated RBF rules, as a<br>wallet you&#39;ll need to keep using the old rules=
 for a long time if you<div>want to be safe.<div><br>But it&#39;s all the m=
ore reason to try to ship this as soon as possible,<br>this way maybe our g=
rand-children will be able to benefit from it ;)<br>(just kidding on the ti=
mespan obviously).<br><br>Cheers,<br>Bastien</div></div></div><br><div clas=
s=3D"gmail_quote"><div class=3D"gmail_attr" dir=3D"ltr">Le lun. 31 janv. 20=
22 =C3=A0 00:11, Antoine Riard via bitcoin-dev &lt;<a href=3D"mailto:bitcoi=
n-dev@lists.linuxfoundation.org" rel=3D"noreferrer nofollow noopener" targe=
t=3D"_blank">bitcoin-dev@lists.linuxfoundation.org</a>&gt; a =C3=A9crit :<b=
r></div><blockquote style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid=
 rgb(204,204,204);padding-left:1ex" class=3D"gmail_quote"><div dir=3D"ltr">=
<div>Hi Gloria,<br><br>Thanks for this RBF sum up. Few thoughts and more co=
ntext comments if it can help other readers.<br><br>&gt; For starters, the =
absolute fee pinning attack is especially<br>&gt; problematic if we apply t=
he same rules (i.e. Rule #3 and #4) in<br>&gt; Package RBF. Imagine that Al=
ice (honest) and Bob (adversary) share a<br>&gt; LN channel. The mempool is=
 rather full, so their pre-negotiated<br>&gt; commitment transactions&#39; =
feerates would not be considered high<br>&gt; priority by miners.  Bob broa=
dcasts his commitment transaction and<br>&gt; attaches a very large child (=
100KvB with 100,000sat in fees) to his<br>&gt; anchor output. Alice broadca=
sts her commitment transaction with a<br>&gt; fee-bumping child (200vB with=
 50,000sat fees which is a generous<br>&gt; 250sat/vB), but this does not m=
eet the absolute fee requirement. She<br>&gt; would need to add another 50,=
000sat to replace Bob&#39;s commitment<br>&gt; transaction.<br><br>Solving =
LN pinning attacks, what we&#39;re aiming for is enabling a fair feerate bi=
d between the  counterparties, thus either forcing the adversary to overbid=
 or to disengage from the confirmation competition. If the replace-by-feera=
te rule is adopted, there shouldn&#39;t be an incentive for Bob to<br>pick =
up the first option. Though if he does, that&#39;s a winning outcome for Al=
ice, as one of the commitment transactions confirms and her time-sensitive =
second-stage HTLC can be subsequently confirmed.<br><br>&gt; It&#39;s uncle=
ar to me if<br>&gt; we have a very strong reason to change this, but noting=
 it as a<br>&gt; limitation of our current replacement policy. See [#24007]=
[12].<br><br>Deployment of Taproot opens interesting possibilities in the v=
aults/payment channels design space, where the tapscripts can commit to dif=
ferent set of timelocks/quorum of keys. Even if the pre-signed states stay =
symmetric, whoever is the publisher, the feerate cost to spend can fluctuat=
e.<br><br>&gt; While this isn&#39;t completely broken, and the user interfa=
ce is<br>&gt; secondary to the safety of the mempool policy<br><br>I think =
with L2s transaction broadcast backend, the stability and clarity of the RB=
F user interface is primary. What we could be worried about is a too-much c=
omplex interface easing the way for an attacker to trigger your L2 node to =
issue policy-invalid chain of transactions. Especially, when we consider th=
at an attacker might have leverage on chain of transactions composition (&q=
uot;force broadcast of commitment A then commitment B, knowing they will sh=
are a CPFP&quot;) or even transactions size (&quot;overload commitment A wi=
th HTLCs&quot;).<br><br>&gt; * If the original transaction is in the top {0=
.75MvB, 1MvB} of the<br>&gt;   mempool, apply the current rules (absolute f=
ees must increase and<br>&gt; pay for the replacement transaction&#39;s new=
 bandwidth). Otherwise, use a<br>&gt; feerate-only rule.<br><br>How this ne=
w replacement rule would behave if you have a parent in the &quot;replace-b=
y-feerate&quot; half but the child is in the &quot;replace-by-fee&quot; one=
 ?<br><br>If we allow the replacement of the parent based on the feerate, w=
e might decrease the top block absolute fees.<br><br>If we block the replac=
ement of the parent based on the feerate because the replacement absolute f=
ees aren&#39;t above the replaced package, we still preclude a pinning vect=
or. The child might be low-feerate junk and even attached to a low ancestor=
-score branch.<br><br>If I&#39;m correct on this limitation, maybe we could=
 turn off the &quot;replace-by-fee&quot; behavior as soon as the mempool is=
 fulfilled with a few blocks ?<br><br>&gt; * Rate-limit how many replacemen=
ts we allow per prevout.<br><br>Depending on how it is implemented, though =
I would be concerned it introduces a new pinning vector in the context of s=
hared-utxo. If it&#39;s a hardcoded constant, it could be exhausted by an a=
dversary starting at the lowest acceptable feerate then slowly increasing w=
hile still not reaching<br>the top of the mempool. Same if it&#39;s time-ba=
sed or block-based, no guarantee the replacement slot is honestly used by y=
our counterparty.<br><br>Further, an above-the-average replacement frequenc=
y might just be the reflection of your confirmation strategy reacting to bl=
ock schedule or mempools historical data. As long as the feerate penalty is=
 paid, I lean to allow replacement.<br><br></div>(One solution could be to =
associate per-user &quot;tag&quot; to the LN transactions, where each &quot=
;tag&quot; would have its own replacement slots, but privacy?)<br><div><br>=
&gt; * Rate-limit transaction validation in general, per peer.<br><br>I thi=
nk we could improve on the Core&#39;s new transaction requester logic. Mayb=
e we could bind the peer announced flow based on the feerate score (modulo =
validation time) of the previously validated transactions from that peer ? =
That said, while related to RBF, it sounds to me that enhancing Core&#39;s =
rate-limiting transaction strategy is a whole discussion in itself [0]. Esp=
ecially ensuring it&#39;s tolerant to the specific requirements of LN &amp;=
 consorts.<br><br>&gt; What should they be? We can do some arithmetic to se=
e what happens if<br>&gt; you start with the biggest/lowest feerate transac=
tion and do a bunch<br>&gt; of replacements. Maybe we end up with values th=
at are high enough to<br>&gt; prevent abuse and make sense for applications=
/users that do RBF.<br><br>That&#39;s a good question. <br><br>One observat=
ion is that the attacker can always renew the set of DoSy utxos to pursue t=
he attack. So maybe we could pick up constants scaled on the block size ? T=
hat way an attacker would have to burn fees, thus deterring them from launc=
hing an attack. Even if the attackers are miners, they have to renounce the=
ir income to acquire new DoSy utxos. If a low-fee period, we could scale up=
 the constants ?<br><br><br>Overall, I think there is the deployment issue =
to warn of. Moving to a new set of RBF rules implies for a lot of Bitcoin a=
pplications to rewrite their RBF logics. We might have a more-or-less long =
transition period during which we support both...<br><br>Cheers,<br>Antoine=
<br><br>[0] <a href=3D"https://github.com/bitcoin/bitcoin/pull/21224" rel=
=3D"noreferrer nofollow noopener" target=3D"_blank">https://github.com/bitc=
oin/bitcoin/pull/21224</a><br></div></div><br><div class=3D"gmail_quote"><d=
iv class=3D"gmail_attr" dir=3D"ltr">Le jeu. 27 janv. 2022 =C3=A0 09:10, Glo=
ria Zhao via bitcoin-dev &lt;<a href=3D"mailto:bitcoin-dev@lists.linuxfound=
ation.org" rel=3D"noreferrer nofollow noopener" target=3D"_blank">bitcoin-d=
ev@lists.linuxfoundation.org</a>&gt; a =C3=A9crit :<br></div><blockquote st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex" class=3D"gmail_quote"><div dir=3D"ltr">Hi everyone,<br><br>Th=
is post discusses limitations of current Bitcoin Core RBF policy and<br>att=
empts to start a conversation about how we can improve it,<br>summarizing s=
ome ideas that have been discussed. Please reply if you<br>have any new inp=
ut on issues to be solved and ideas for improvement!<br><br>Just in case I&=
#39;ve screwed up the text wrapping again, another copy can be<br>found her=
e: <a href=3D"https://gist.github.com/glozow/25d9662c52453bd08b4b4b1d3783b9=
ff" rel=3D"noreferrer nofollow noopener" target=3D"_blank">https://gist.git=
hub.com/glozow/25d9662c52453bd08b4b4b1d3783b9ff</a><br><br>## Background<br=
><br>Please feel free to skip this section if you are already familiar<br>w=
ith RBF.<br><br>Nodes may receive *conflicting* unconfirmed transactions, a=
ka<br>&quot;double spends&quot; of the same inputs. Instead of always keepi=
ng the<br>first transaction, since v0.12, Bitcoin Core mempool policy has<b=
r>included a set of Replace-by-Fee (RBF) criteria that allows the second<br=
>transaction to replace the first one and any descendants it may have.<br><=
br>Bitcoin Core RBF policy was previously documented as BIP 125.<br>The cur=
rent RBF policy is documented [here][1]. In summary:<br><br>1. The directly=
 conflicting transactions all signal replaceability<br>   explicitly.<br><b=
r>2. The replacement transaction only includes an unconfirmed input if<br> =
  that input was included in one of the directly conflicting<br>transaction=
s.<br><br>3. The replacement transaction pays an absolute fee of at least t=
he<br>   sum paid by the original transactions.<br><br>4. The additional fe=
es pays for the replacement transaction&#39;s<br>   bandwidth at or above t=
he rate set by the node&#39;s *incremental relay<br>feerate*.<br><br>5. The=
 sum of all directly conflicting transactions&#39; descendant counts<br>   =
(number of transactions inclusive of itself and its descendants)<br>does no=
t exceed 100.<br><br>We can split these rules into 3 categories/goals:<br><=
br>- **Allow Opting Out**: Some applications/businesses are unable to<br>  =
handle transactions that are replaceable (e.g. merchants that use<br>zero-c=
onfirmation transactions). We (try to) help these businesses by<br>honoring=
 BIP125 signaling; we won&#39;t replace transactions that have not<br>opted=
 in.<br><br>- **Incentive Compatibility**: Ensure that our RBF policy would=
 not<br>  accept replacement transactions which would decrease fee profits<=
br>  of a miner. In general, if our mempool policy deviates from what is<br=
>economically rational, it&#39;s likely that the transactions in our<br>mem=
pool will not match the ones in miners&#39; mempools, making our<br>fee est=
imation, compact block relay, and other mempool-dependent<br>functions unre=
liable. Incentive-incompatible policy may also<br>encourage transaction sub=
mission through routes other than the p2p<br>network, harming censorship-re=
sistance and privacy of Bitcoin payments.<br><br>- **DoS Protection**: Limi=
t two types of DoS attacks on the node&#39;s<br>  mempool: (1) the number o=
f times a transaction can be replaced and<br>(2) the volume of transactions=
 that can be evicted during a<br>replacement.<br><br>Even more abstract: ou=
r goal is to make a replacement policy that<br>results in a useful interfac=
e for users and safe policy for<br>node operators.<br><br>## Motivation<br>=
<br>There are a number of known problems with the current RBF policy.<br>Ma=
ny of these shortcomings exist due to mempool limitations at the<br>time RB=
F was implemented or result from new types of Bitcoin usage;<br>they are no=
t criticisms of the original design.<br><br>### Pinning Attacks<br><br>The =
most pressing concern is that attackers may take advantage of<br>limitation=
s in RBF policy to prevent other users&#39; transactions from<br>being mine=
d or getting accepted as a replacement.<br><br>#### SIGHASH_ANYONECANPAY Pi=
nning<br><br>BIP125#2 can be bypassed by creating intermediary transactions=
 to be<br>replaced together. Anyone can simply split a 1-input 1-output<br>=
transaction off from the replacement transaction, then broadcast the<br>tra=
nsaction as is. This can always be done, and quite cheaply. More<br>details=
 in [this comment][2].<br><br>In general, if a transaction is signed with S=
IGHASH\_ANYONECANPAY,<br>anybody can just attach a low feerate parent to th=
is transaction and<br>lower its ancestor feerate.  Even if you require SIGH=
ASH\_ALL which<br>prevents an attacker from changing any outputs, the input=
 can be a<br>very low amount (e.g. just above the dust limit) from a low-fe=
e<br>ancestor and still bring down the ancestor feerate of the transaction.=
<br><br>TLDR: if your transaction is signed with SIGHASH\_ANYONECANPAY and<=
br>signals replaceability, regardless of the feerate you broadcast at, an<b=
r>attacker can lower its mining priority by adding an ancestor.<br><br>####=
 Absolute Fee<br><br>The restriction of requiring replacement transactions =
to increase the<br>absolute fee of the mempool has been described as &quot;=
bonkers.&quot; If the<br>original transaction has a very large descendant t=
hat pays a large<br>amount of fees, even if it has a low feerate, the repla=
cement<br>transaction must now pay those fees in order to meet Rule #3.<br>=
<br>#### Package RBF<br><br>There are a number of reasons why, in order to =
enable Package RBF, we<br>cannot use the same criteria.<br><br>For starters=
, the absolute fee pinning attack is especially<br>problematic if we apply =
the same rules (i.e. Rule #3 and #4) in<br>Package RBF. Imagine that Alice =
(honest) and Bob (adversary) share a<br>LN channel. The mempool is rather f=
ull, so their pre-negotiated<br>commitment transactions&#39; feerates would=
 not be considered high<br>priority by miners.  Bob broadcasts his commitme=
nt transaction and<br>attaches a very large child (100KvB with 100,000sat i=
n fees) to his<br>anchor output. Alice broadcasts her commitment transactio=
n with a<br>fee-bumping child (200vB with 50,000sat fees which is a generou=
s<br>250sat/vB), but this does not meet the absolute fee requirement. She<b=
r>would need to add another 50,000sat to replace Bob&#39;s commitment<br>tr=
ansaction.<br><br>Disallowing new unconfirmed inputs (Rule #2) in Package R=
BF would be<br>broken for packages containing transactions already in the m=
empool,<br>explained [here][7].<br><br>Note: I originally [proposed][6] Pac=
kage RBF using the same Rule #3<br>and #4 before I realized how significant=
 this pinning attack is. I&#39;m<br>retracting that proposal, and a new set=
 of Package RBF rules would<br>follow from whatever the new individual RBF =
rules end up being.<br><br>#### Same Txid Different Witness<br><br>Two tran=
sactions with the same non-witness data but different<br>witnesses have the=
 same txid but different wtxid, and the same fee but<br>not necessarily the=
 same feerate. Currently, if we see a transaction<br>that has the same txid=
 as one in the mempool, we reject it as a<br>duplicate, even if the feerate=
 is much higher. It&#39;s unclear to me if<br>we have a very strong reason =
to change this, but noting it as a<br>limitation of our current replacement=
 policy. See [#24007][12].<br><br>### User Interface<br><br>#### Using Unco=
nfirmed UTXOs to Fund Replacements<br><br>The restriction of only allowing =
confirmed UTXOs for funding a<br>fee-bump (Rule #2) can hurt users trying t=
o fee-bump their<br>transactions and complicate wallet implementations. If =
the original<br>transaction&#39;s output value isn&#39;t sufficient to fund=
 a fee-bump and/or<br>all of the user&#39;s other UTXOs are unconfirmed, th=
ey might not be able<br>to fund a replacement transaction. Wallet developer=
s also need to<br>treat self-owned unconfirmed UTXOs as unusable for fee-bu=
mping, which<br>adds complexity to wallet logic. For example, see BDK issue=
s [#144][4]<br>and [#414][5].<br><br>#### Interface Not Suitable for Coin S=
election<br><br>Currently, a user cannot simply create a replacement transa=
ction<br>targeting a specific feerate or meeting a minimum fee amount and<b=
r>expect to meet the RBF criteria. The fee amount depends on the size of<br=
>the replacement transaction, and feerate is almost irrelevant.<br><br>Bitc=
oin Core&#39;s `bumpfee` doesn&#39;t use the RBF rules when funding the<br>=
replacement. It [estimates][13] a feerate which is &quot;wallet incremental=
<br>relay fee&quot; (a conservative overestimation of the node&#39;s increm=
ental<br>relay fee) higher than the original transaction, selects coins for=
<br>that feerate, and hopes that it meets the RBF rules. It never fails<br>=
Rule #3 and #4 because it uses all original inputs and refuses to<br>bump a=
 transaction with mempool descendants.<br><br>This is suboptimal, but is de=
signed to work with the coin selection<br>engine: select a feerate first, a=
nd then add fees to cover it.<br>Following the exact RBF rules would requir=
e working the other way<br>around: based on how much fees we&#39;ve added t=
o the transaction and its<br>current size, calculate the feerate to see if =
we meet Rule #4.<br><br>While this isn&#39;t completely broken, and the use=
r interface is<br>secondary to the safety of the mempool policy, we can do =
much better.<br>A much more user-friendly interface would depend *only* on =
the<br>fee and size of the original transactions.<br><br>### Updates to Mem=
pool and Mining<br><br>Since RBF was first implemented, a number of improve=
ments have been<br>made to mempool and mining logic. For example, we now us=
e ancestor<br>feerates in mining (allowing CPFP), and keep track of ancesto=
r<br>packages in the mempool.<br><br>## Ideas for Improvements<br><br>### G=
oals<br><br>To summarize, these seem to be desired changes, in order of pri=
ority:<br><br>1. Remove Rule #3. The replacement should not be *required* t=
o pay<br>higher absolute fees.<br><br>2. Make it impossible for a replaceme=
nt transaction to have a lower<br>mining score than the original transactio=
n(s). This would eliminate<br>the `SIGHASH\_ANYONECANPAY` pinning attack.<b=
r><br>3. Remove Rule #2. Adding new unconfirmed inputs should be allowed.<b=
r><br>4. Create a more helpful interface that helps wallet fund replacement=
<br>transactions that aim for a feerate and fee.<br><br>### A Different Mod=
el for Fees<br><br>For incentive compatibility, I believe there are differe=
nt<br>formulations we should consider.  Most importantly, if we want to get=
<br>rid of the absolute fee rule, we can no longer think of it as &quot;the=
<br>transaction needs to pay for its own bandwidth,&quot; since we won&#39;=
t always<br>be getting additional fees. That means we need a new method of<=
br>rate-limiting replacements that doesn&#39;t require additional fees ever=
y<br>time.<br><br>While it makes sense to think about monetary costs when l=
aunching a<br>specific type of attack, given that the fees are paid to the =
miner and<br>not to the mempool operators, maybe it doesn&#39;t make much s=
ense to<br>think about &quot;paying for bandwidth&quot;. Maybe we should im=
plement<br>transaction validation rate-limiting differently, e.g. building =
it<br>into the P2P layer instead of the mempool policy layer.<br><br>Recent=
ly, Suhas gave a [formulation][8] for incentive compatibility<br>that made =
sense to me: &quot;are the fees expected to be paid in the next<br>(N?) blo=
cks higher or lower if we process this transaction?&quot;<br><br>I started =
by thinking about this where N=3D1 or `1 + p`.<br>Here, a rational miner is=
 looking at what fees they would<br>collect in the next block, and then som=
e proportion `p` of the rest of<br>the blocks based on their hashrate. We&#=
39;re assuming `p` isn&#39;t *so high*<br>that they would be okay with lowe=
r absolute fees in the next 1 block.<br>We&#39;re also assuming `p` isn&#39=
;t *so low* that the miner doesn&#39;t care<br>about what&#39;s left of the=
 mempool after this block.<br><br>A tweak to this formulation is &quot;if w=
e process this transaction, would<br>the fees in the next 1 block higher or=
 lower, and is the feerate<br>density of the rest of the mempool higher or =
lower?&quot; This is pretty<br>similar, where N=3D1, but we consider the re=
st of the mempool by feerate<br>rather than fees.<br><br>### Mining Score o=
f a Mempool Transaction<br><br>We are often interested in finding out what<=
br>the &quot;mining score&quot; of a transaction in the mempool is. That is=
, when<br>the transaction is considered in block template building, what is=
 the<br>feerate it is considered at?<br><br>Obviously, it&#39;s not the tra=
nsaction&#39;s individual feerate. Bitcoin Core<br>[mining code sorts][14] =
transactions by their ancestor feerate and<br>includes them packages at a t=
ime, keeping track of how this affects the<br>package feerates of remaining=
 transactions in the mempool.<br><br>*ancestor feerate*: Ancestor feerate i=
s easily accessible information,<br>but it&#39;s not accurate either, becau=
se it doesn&#39;t take into account the<br>fact that subsets of a transacti=
on&#39;s ancestor set can be included<br>without it. For example, ancestors=
 may have high feerates on their own<br>or we may have [high feerate siblin=
gs][8].<br><br>TLDR: *Looking at the current ancestor feerate of a transact=
ion is<br>insufficient to tell us what feerate it will be considered at whe=
n<br>building a block template in the future.*<br><br>*min(individual feera=
te, ancestor feerate)*: Another<br>heuristic that is simple to calculate ba=
sed on current mempool tooling<br>is to use the [minimum of a transaction&#=
39;s individual score and its<br>ancestor score][10] as a conservative meas=
ure.  But this can<br>overestimate as well (see the example below). <br><br=
>*min ancestor feerate(tx + possible ancestor subsets)* We can also<br>take=
 the minimum of every possible ancestor subset, but this can be<br>computat=
ionally expensive since there can be lots and lots of ancestor<br>subsets.<=
br><br>*max ancestor feerate(tx + possible descendant subsets)*: Another id=
ea<br>is to use the [maximum ancestor score of the transaction + each of it=
s<br>descendants][9]. This doesn&#39;t work either; it has the same blindsp=
ot<br>of ancestor subsets being mined on their own.<br><br>#### Mining Scor=
e Example<br><br>Here&#39;s an example illustrating why mining score is tri=
cky to<br>efficiently calculate for mempool transactions:<br><br>Let&#39;s =
say you have same-size transactions A (21sat/vB), B (1sat/vB),<br>C(9sat/vB=
), D(5sat/vB).<br>The layout is: grandparent A, parent B, and two children =
C and D.<br><br>```<br>    A<br>    ^<br>    B<br>   ^ ^<br>   C D<br>```<b=
r><br>A miner using ancestor packages to build block templates will first<b=
r>include A with a mining score of 21. Next, the miner will include B and<b=
r>C with a mining score of 6. This leaves D, with a mining score of 5.<br><=
br>Note: in this case, mining by ancestor feerate results in the most<br>ra=
tional decisions, but [a candidate set-based approach][10] which<br>makes a=
ncestor feerate much less relevant could<br>be more advantageous in other s=
ituations.<br><br>Here is a chart showing the &quot;true&quot; mining score=
 alongside the values<br>calculating using imperfect heuristics described a=
bove. All of them<br>can overestimate or underestimate.<br><br>```<br>				 =
   A	     B       C	     D<br>mining score			|   21   |   6   |   6   |   5=
   |<br>ancestor feerate	  	|   21   |  11   | 10.3  |   9   |<br>min(indiv=
idual, ancestor)	|   21   |   1   |   9   |   5   |<br>min(tx + ancestor su=
bsets)      |   21   |   1   |   5   |   3   |<br>max(tx + descendants subs=
ets)	|   21   |   9   |   9   |   5   |<br><br>```<br><br>Possibly the best=
 solution for finding the &quot;mining score&quot; of a<br>transaction is t=
o build a block template, see what feerate each<br>package is included at. =
Perhaps at some cutoff, remaining mempool<br>transactions can be estimated =
using some heuristic that leans<br>{overestimating, underestimating} depend=
ing on the situation.<br><br>Mining score seems to be relevant in multiple =
places: Murch and I<br>recently [found][3] that it would be very important =
in<br>&quot;ancestor-aware&quot; funding of transactions (the wallet doesn&=
#39;t<br>incorporate ancestor fees when using unconfirmed transactions in c=
oin<br>selection, which is a bug we want to fix).<br><br>In general, it wou=
ld be nice to know the exact mining priority of<br>one&#39;s unconfirmed tr=
ansaction is.  I can think of a few block/mempool<br>explorers who might wa=
nt to display this information for users.<br><br>### RBF Improvement Propos=
als<br><br>After speaking to quite a few people, here are some suggestions<=
br>for improvements that I have heard:<br><br>* The ancestor score of the r=
eplacement must be {5, 10, N}% higher<br>  than that of every original tran=
saction.<br><br>* The ancestor score of the replacement must be 1sat/vB hig=
her than<br>  that of every original transaction.<br><br>* If the original =
transaction is in the top {0.75MvB, 1MvB} of the<br>  mempool, apply the cu=
rrent rules (absolute fees must increase and<br>pay for the replacement tra=
nsaction&#39;s new bandwidth). Otherwise, use a<br>feerate-only rule.<br><b=
r>* If fees don&#39;t increase, the size of the replacement transaction mus=
t<br>  decrease by at least N%.<br><br>* Rate-limit how many replacements w=
e allow per prevout.<br><br>* Rate-limit transaction validation in general,=
 per peer.<br><br>Perhaps some others on the mailing list can chime in to t=
hrow other<br>ideas into the ring and/or combine some of these rules into a=
 sensible<br>policy.<br><br>#### Replace by Feerate Only<br><br>I don&#39;t=
 think there&#39;s going to be a single-line feerate-based<br>rule that can=
 incorporate everything we need.<br>On one hand, a feerate-only approach he=
lps eliminate the issues<br>associated with Rule #3. On the other hand, I b=
elieve the main concern<br>with a feerate-only approach is how to rate limi=
t replacements. We<br>don&#39;t want to enable an attack such as:<br><br>1.=
 Attacker broadcasts large, low-feerate transaction, and attaches a<br>chai=
n of descendants.<br><br>2. The attacker replaces the transaction with a sm=
aller but higher<br>feerate transaction, attaching a new chain of descendan=
ts.<br><br>3. Repeat 1000 times.<br><br>#### Fees in Next Block and Feerate=
 for the Rest of the Mempool<br><br>Perhaps we can look at replacements lik=
e this:<br><br>1. Calculate the directly conflicting transactions and, with=
 their<br>descendants, the original transactions. Check signaling. Limit th=
e<br>total volume (e.g. can&#39;t be more than 100 total or 1MvB or somethi=
ng).<br><br>2. Find which original transactions would be in the next ~1 blo=
ck. The<br>replacement must pay at least this amount + X% in absolute fees.=
 This<br>guarantees that the fees of the next block doesn&#39;t decrease.<b=
r><br>3. Find which transactions would be left in the mempool after that ~1=
<br>block. The replacement&#39;s feerate must be Y% higher than the maximum=
<br>mining score of these transactions. This guarantees that you now have<b=
r>only *better* candidates in your after-this-block mempool than you did<br=
>before, even if the size and fees the transactions decrease.<br><br>4. Now=
 you have two numbers: a minimum absolute fee amount and a<br>minimum feera=
te. Check to see if the replacement(s) meet these<br>minimums. Also, a wall=
et would be able to ask the node &quot;What fee and<br>feerate would I need=
 to put on a transaction replacing this?&quot; and use<br>this information =
to fund a replacement transaction, without needing to<br>guess or overshoot=
.<br><br>Obviously, there are some magic numbers missing here. X and Y are<=
br>TBD constants to ensure we have some kind of rate limiting for the<br>nu=
mber of replacements allowed using some set of fees.<br><br>What should the=
y be? We can do some arithmetic to see what happens if<br>you start with th=
e biggest/lowest feerate transaction and do a bunch<br>of replacements. May=
be we end up with values that are high enough to<br>prevent abuse and make =
sense for applications/users that do RBF.<br><br>### Mempool Changes Need f=
or Implementation<br><br>As described in the mining score section above,<br=
>we may want additional tooling to more accurately assess<br>the economic g=
ain of replacing transactions in our mempool.<br><br>A few options have bee=
n discussed:<br><br>* Calculate block templates on the fly when we need to =
consider a<br>  replacement. However, since replacements are [quite common]=
[11]<br>  and the information might be useful for other things as well, <br=
>  it may be worth it to cache a block template.<br><br>* Keep a persistent=
 block template so that we know what transactions<br>  we would put in the =
next block. We need to remember the feerate<br>at which each transaction wa=
s included in the template, because an<br>ancestor package may be included =
in the same block template in<br>multiple subsets. Transactions included ea=
rlier alter the ancestor<br>feerate of the remaining transactions in the pa=
ckage. We also need<br>to keep track of the new feerates of transactions le=
ft over. <br><br>* Divide the mempool into two layers, &quot;high feerate&q=
uot; and &quot;low<br>  feerate.&quot; The high feerate layer contains ~1 b=
lock of packages with<br>the highest ancestor feerates, and the low feerate=
 layer contains<br>everything else. At the edge of a block, we have a Knaps=
acky problem<br>where the next highest ancestor feerate package might not f=
it, so we<br>would probably want the high feerate layer ~2MvB or something =
to avoid<br>underestimating the fees.<br><br>## Acknowledgements<br><br>Tha=
nk you to everyone whose RBF-related suggestions, grievances,<br>criticisms=
 and ideas were incorporated in this document:<br>Andrew Chow, Matt Corallo=
, Suhas Daftuar, Christian Decker,<br>Mark Erhardt, Lloyd Fournier, Lisa Ne=
igut, John Newbery,<br>Antoine Poinsot, Antoine Riard, Larry Ruane,<br><div=
>S3RK and Bastien Teinturier.</div><div><br></div><div>Thanks for reading!<=
/div><div><br></div><div>Best,<br></div><div>Gloria<br></div><br>[1]: <a hr=
ef=3D"https://github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-rep=
lacements.md" rel=3D"noreferrer nofollow noopener" target=3D"_blank">https:=
//github.com/bitcoin/bitcoin/blob/master/doc/policy/mempool-replacements.md=
</a><br>[2]: <a href=3D"https://github.com/bitcoin/bitcoin/pull/23121#issue=
comment-929475999" rel=3D"noreferrer nofollow noopener" target=3D"_blank">h=
ttps://github.com/bitcoin/bitcoin/pull/23121#issuecomment-929475999</a><br>=
[3]: <a href=3D"https://github.com/Xekyo/bitcoin/commit/d754b0242ec69d42c57=
0418aebf9c1335af0b8ea" rel=3D"noreferrer nofollow noopener" target=3D"_blan=
k">https://github.com/Xekyo/bitcoin/commit/d754b0242ec69d42c570418aebf9c133=
5af0b8ea</a><br>[4]: <a href=3D"https://github.com/bitcoindevkit/bdk/issues=
/144" rel=3D"noreferrer nofollow noopener" target=3D"_blank">https://github=
.com/bitcoindevkit/bdk/issues/144</a><br>[5]: <a href=3D"https://github.com=
/bitcoindevkit/bdk/issues/414" rel=3D"noreferrer nofollow noopener" target=
=3D"_blank">https://github.com/bitcoindevkit/bdk/issues/414</a><br>[6]: <a =
href=3D"https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-Septem=
ber/019464.html" rel=3D"noreferrer nofollow noopener" target=3D"_blank">htt=
ps://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-September/019464.=
html</a><br>[7]: <a href=3D"https://gist.github.com/glozow/dc4e9d5c5b14ade7=
cdfac40f43adb18a#new-unconfirmed-inputs-rule-2" rel=3D"noreferrer nofollow =
noopener" target=3D"_blank">https://gist.github.com/glozow/dc4e9d5c5b14ade7=
cdfac40f43adb18a#new-unconfirmed-inputs-rule-2</a><br>[8]: <a href=3D"https=
://github.com/bitcoin/bitcoin/pull/23121#discussion_r777131366" rel=3D"nore=
ferrer nofollow noopener" target=3D"_blank">https://github.com/bitcoin/bitc=
oin/pull/23121#discussion_r777131366</a><br>[9]: <a href=3D"https://github.=
com/bitcoin/bitcoin/pull/22290#issuecomment-865887922" rel=3D"noreferrer no=
follow noopener" target=3D"_blank">https://github.com/bitcoin/bitcoin/pull/=
22290#issuecomment-865887922</a><br>[10]: <a href=3D"https://gist.github.co=
m/Xekyo/5cb413fe9f26dbce57abfd344ebbfaf2#file-candidate-set-based-block-bui=
lding-md" rel=3D"noreferrer nofollow noopener" target=3D"_blank">https://gi=
st.github.com/Xekyo/5cb413fe9f26dbce57abfd344ebbfaf2#file-candidate-set-bas=
ed-block-building-md</a><br>[11]: <a href=3D"https://github.com/bitcoin/bit=
coin/pull/22539#issuecomment-885763670" rel=3D"noreferrer nofollow noopener=
" target=3D"_blank">https://github.com/bitcoin/bitcoin/pull/22539#issuecomm=
ent-885763670</a><br>[12]: <a href=3D"https://github.com/bitcoin/bitcoin/pu=
ll/24007" rel=3D"noreferrer nofollow noopener" target=3D"_blank">https://gi=
thub.com/bitcoin/bitcoin/pull/24007</a><br>[13]: <a href=3D"https://github.=
com/bitcoin/bitcoin/blob/1a369f006fd0bec373b95001ed84b480e852f191/src/walle=
t/feebumper.cpp#L114" rel=3D"noreferrer nofollow noopener" target=3D"_blank=
">https://github.com/bitcoin/bitcoin/blob/1a369f006fd0bec373b95001ed84b480e=
852f191/src/wallet/feebumper.cpp#L114</a><br><div>[14]: <a href=3D"https://=
github.com/bitcoin/bitcoin/blob/cf5bb048e80d4cde8828787b266b7f5f2e3b6d7b/sr=
c/node/miner.cpp#L310-L320" rel=3D"noreferrer nofollow noopener" target=3D"=
_blank">https://github.com/bitcoin/bitcoin/blob/cf5bb048e80d4cde8828787b266=
b7f5f2e3b6d7b/src/node/miner.cpp#L310-L320</a></div></div>
_______________________________________________<br>
bitcoin-dev mailing list<br>
<a href=3D"mailto:bitcoin-dev@lists.linuxfoundation.org" rel=3D"noreferrer =
nofollow noopener" target=3D"_blank">bitcoin-dev@lists.linuxfoundation.org<=
/a><br>
<a rel=3D"noreferrer nofollow noopener" href=3D"https://lists.linuxfoundati=
on.org/mailman/listinfo/bitcoin-dev" target=3D"_blank">https://lists.linuxf=
oundation.org/mailman/listinfo/bitcoin-dev</a><br>
</blockquote></div>
_______________________________________________<br>
bitcoin-dev mailing list<br>
<a href=3D"mailto:bitcoin-dev@lists.linuxfoundation.org" rel=3D"noreferrer =
nofollow noopener" target=3D"_blank">bitcoin-dev@lists.linuxfoundation.org<=
/a><br>
<a rel=3D"noreferrer nofollow noopener" href=3D"https://lists.linuxfoundati=
on.org/mailman/listinfo/bitcoin-dev" target=3D"_blank">https://lists.linuxf=
oundation.org/mailman/listinfo/bitcoin-dev</a><br>
</blockquote></div>

        </blockquote><br>
    </div></blockquote></div>
_______________________________________________<br>
bitcoin-dev mailing list<br>
<a href=3D"mailto:bitcoin-dev@lists.linuxfoundation.org" target=3D"_blank">=
bitcoin-dev@lists.linuxfoundation.org</a><br>
<a href=3D"https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev" =
rel=3D"noreferrer" target=3D"_blank">https://lists.linuxfoundation.org/mail=
man/listinfo/bitcoin-dev</a><br>
</blockquote></div>

--000000000000ec51c205d76bbb39--