/ home / newsletters /
Bitcoin Optech Newsletter #225
This week’s newsletter summarizes continued discussion about a configuration option for enabling full-RBF in Bitcoin Core and describes a bug affecting BTCD, LND, and other software. Also included are our regular sections with the summary of a Bitcoin Core PR Review Club meeting, descriptions of new releases and release candidates, and overviews of notable changes to popular Bitcoin infrastructure software.
● Continued discussion about enabling full-RBF: as mentioned in newsletters for the past several weeks—users, service providers, and Bitcoin Core developers have been evaluating the inclusion of the
mempoolfullrbfconfiguration option into Bitcoin Core’s development branch and current release candidates for version 24.0. Those previous newsletters have summarized many previous arguments for and against this full RBF option (1, 2, 3). This week, Suhas Daftuar posted to the Bitcoin-Dev mailing list to “argue that we should continue to maintain a relay policy where replacements are rejected for transactions that don’t opt-in to RBF (as described in BIP 125), and moreover, that we should remove the
-mempoolfullrbfflag from Bitcoin Core’s latest release candidate and not plan to release software with that flag, unless (or until) circumstances change on the network.” He notes:
● Opt-in RBF already available: anyone who wants the benefits of RBF should be able to opt-in to it using the mechanism described in BIP125. Users would only be served by full RBF if there was some reason they couldn’t use opt-in RBF.
● Full RBF doesn’t fix anything that isn’t broken in other ways: a possible case where some users of a multiparty protocol could deny other users the ability to use opt-in RBF was previously identified, but Daftuar notes that protocol is vulnerable to other cheap or free attacks which full RBF would not solve.
● Full RBF takes away options: “absent any other examples [of problems fixed by fullrbf], it does not seem to me that fullrbf solves any problems for RBF users, who are already free to choose to subject their transactions to BIP 125’s RBF policy. From this perspective, “enabling fullrbf” is really just taking away user choice to opt a transaction into a non-replacement policy regime.”
● Offering non-replacement doesn’t introduce any issues for full nodes: indeed, it simplifies the handling of long chains of transactions.
● Determining incentive compatibility isn’t always straightforward: Daftuar uses the proposal for v3 transaction relay (see Newsletter #220) as an example:
Suppose in a few years someone proposes that we add a “-disable_v3_transaction_enforcement” flag to our software, to let users decide to turn off those policy restrictions and treat v3 transactions the same as v2, for all the same reasons that could be argued today with fullrbf […]
[That] would be subversive to making the lightning use case for v3 transactions work […] we should not enable users to disable this policy, because as long as that policy is just optional and working for those who want it, it shouldn’t harm anyone that we offer a tighter set of rules for a particular use case. Adding a way to bypass those rules is just trying to break someone else’s use case, not trying to add a new one. We should not wield “incentive compatibility” as a bludgeon for breaking things that appear to be working and not causing others harm.
I think this is exactly what is happening with fullrbf.
Daftuar ends his email with three questions for those who still want the
mempoolfullrbfoption to be included in Bitcoin Core:
“Does fullrbf offer any benefits other than breaking zeroconf business practices? If so, what are they?”
“Is it reasonable to enforce BIP 125’s rbf rules on all transactions, if those rules themselves are not always incentive compatible?”
“If someone were to propose a command line option that breaks v3 transaction relay in the future, is there a logical basis for opposing that which is consistent with moving towards fullrbf now?”
As of this writing, no one has answered Daftuar’s questions on the mailing list, although two answers to the set of questions were posted to a Bitcoin Core PR that Daftuar opened to propose removing the
mempoolfullrbfconfiguration option. Daftuar later closed the PR.
It wasn’t clear at the time of writing whether anyone would comment further on the topic.
● Block parsing bug affecting multiple software: as reported in Newsletter #222, it appeared that a serious bug affecting the BTCD full node and LND LN node was accidentally triggered, putting users of the software at risk. Updated software was quickly released. Shortly after that bug was triggered, Anthony Towns discovered a second related bug that could only be triggered by miners. Towns reported the bug to BTCD and LND lead maintainer Olaoluwa Osuntokun, who prepared a patch to include in the next general update of the software. Including the security fix alongside other changes could hide that a vulnerability was being fixed and reduce the chance of it being exploited. Both Towns and Osuntokun responsibly kept the vulnerability private until its fix could be deployed.
Unfortunately, the second related bug was independently rediscovered by someone who found a miner to trigger it. This new bug affected BTCD and LND again, but it also affected at least two other significant projects or services. All users of affected systems should upgrade immediately. We repeat our advice from three weeks ago for anyone using any Bitcoin software to sign up for security announcements from that software’s development team.
With the release of this newsletter, Optech has also added a special topic page where we list the names of the amazing people who responsibly disclosed a vulnerability that we’ve summarized in an Optech newsletter. There are likely several other disclosures not listed because they haven’t been made public yet. We of course also thank all the reviewers of proposals and pull requests whose diligent effort prevented innumerable security bugs from making it into released software.
Bitcoin Core PR Review Club
In this monthly section, we summarize a recent Bitcoin Core PR Review Club meeting, highlighting some of the important questions and answers. Click on a question below to see a summary of the answer from the meeting.
Relax MIN_STANDARD_TX_NONWITNESS_SIZE to 65 non-witness bytes is a PR by instagibbs that relaxes the mempool policy’s non-witness transaction size constraints. It allows transactions to be as small as 65 bytes, replacing the current policy that requires transactions to be at least 85 bytes (see Newsletter #222).
Since this Review Club meeting, this PR has been closed in favor of PR #26398, which relaxes policy even further by disallowing only 64-byte transactions. The relative merits of these two slightly-different policies were discussed during the meeting.
Why was the minimum transaction size 82 bytes? Can you describe the attack?
The 82-byte minimum, which was introduced by PR #11423 in 2018, is the size of the smallest standard payment transaction. This was presented as a cleanup of the standardness rules. But in reality, the change was to prevent a 64-byte transaction from being considered standard, because this size allowed a spoof payment attack against SPV clients (making them think they’ve received a payment when they hadn’t). The attack involves tricking an SPV client into thinking that a 64-byte transaction is an inner node of the transaction merkle tree, which is also 64 bytes in length. ➚
A participant asked, was it was necessary to fix this vulnerability covertly, given that it would be very expensive (on the order of USD$1M) to carry out this attack, combined with the fact that it seems unlikely people would use SPV clients for payments that large?
There was some agreement, but one participant pointed out that our intuition about this could be wrong. ➚
What does non-witness size mean, and why do we care about the non-witness distinction?
We care about the non-witness distinction because, as part of the segwit upgrade, witness data is excluded from the calculation of the merkle root. Since the attack requires the malicious transaction to be 64 bytes in the merkle root construction (so it looks like an inner node), we need to exclude witness data from it. ➚
Why does setting this policy help to prevent the attack?
Since inner merkle tree nodes can only be exactly 64 bytes, a transaction of a different size cannot be misinterpreted as an inner merkle node. ➚
Does it eliminate the attack vector entirely?
Changing the standardness rules only prevents 64-byte transactions from being accepted into mempools and relayed, but such transactions may still be consensus-valid and so can be mined into a block. For this reason, the attack is still possible, but only with the help of miners. ➚
Why might we want to change the minimum transaction size to 65 bytes, apart from the fact that it’s unnecessary to obfuscate the CVE?
There are legitimate use cases for transactions that are less than 82 bytes. One example mentioned is a Child Pays For Parent (CPFP) transaction that assigns an entire parent output to fees (such a transaction would have a single input and an empty
Between disallowing sizes less than 65 bytes and sizes equal to 64 bytes, which approach do you think is better and why? What are the implications of both approaches?
After some byte-counting discussion, it was agreed that a valid but non-standard transaction can be as small as 60 bytes: a stripped (non-witness) with a single native segwit input is 41 B + 10 B header + 8 B value + 1 B
OP_RETURN= 60 B. ➚
Releases and release candidates
New releases and release candidates for popular Bitcoin infrastructure projects. Please consider upgrading to new releases or helping to test release candidates.
● Rust Bitcoin 0.28.2 is a minor release containing a fixes for bugs that could “cause some specific transactions and/or blocks to fail to deserialize. No known such transactions exist on any public blockchain.”
● Bitcoin Core 24.0 RC3 is a release candidate for the next version of the network’s most widely used full node implementation. A guide to testing is available.
Warning: this release candidate includes the
mempoolfullrbfconfiguration option which several protocol and application developers believe could lead to problems for merchant services as described in this newsletter and previous newsletters #222 and #223. It could also cause problems for transaction relay as described in Newsletter #224. Optech encourages any services that might be affected to evaluate the RC and participate in the public discussion.
Notable code and documentation changes
Notable changes this week in Bitcoin Core, Core Lightning, Eclair, LDK, LND, libsecp256k1, Hardware Wallet Interface (HWI), Rust Bitcoin, BTCPay Server, BDK, Bitcoin Improvement Proposals (BIPs), and Lightning BOLTs.
● Bitcoin Core #26419 adds context to the validation interface logs detailing why a transaction is removed from the mempool.
● Eclair #2404 adds support for Short Channel IDentifier (SCID) aliases and zero-conf channels even for channel state commitments that don’t use anchor outputs.
● Eclair #2468 implements BOLTs #1032, allowing the ultimate receiver of a payment (HTLC) to accept a greater amount than they requested and with a longer time before it expires than they requested. Previously, Eclair-based receivers adhered to BOLT4’s requirement that the amount and expiry delta equal exactly the amount they requested, but that exactitude meant a forwarding node could probe the next hop to see if it was the final receiver by changing either value by the slightest bit.
● Eclair #2469 extends the amount of time it asks the last forwarding node to give the next hop to settle a payment. The last forwarding node shouldn’t know it’s the last forwarding node—it shouldn’t know that the next hop is the receiver of the payment. The extra settlement time implies that the next hop may be a routing node rather than the receiver. The PR description for this feature states that Core Lightning and LDK already implement this behavior. See also the description for Eclair #2468 above.
● Eclair #2362 adds support for the
dont_forwardflag for channel updates from BOLTs #999. Channel updates change the parameters of a channel and are often gossiped to inform other nodes on the network about how to use the channel, but when a channel update contains this flag, it should not be forwarded to other nodes.
● Eclair #2441 allows Eclair to begin receiving onion-wrapped error messages of any size. BOLT2 currently recommends 256 byte errors, but doesn’t forbid longer error messages and BOLTs #1021 is open to encourage use of 1024-byte error messages encoded using LN’s modern Type-Length-Value (TLV) semantics.
● LND #7100 updates LND to use the latest version of BTCD (as a library), fixing the block parsing bug described in the news section above.
● LDK #1761 adds a
PaymentIDparameter to methods for sending payments which callers can use to prevent sending multiple identical payments. Additionally, LDK may now continue trying to resend a payment indefinitely, rather than the previous behavior of ceasing retries after a few blocks of repeated failures; the
abandon_paymentmethod may be used to prevent further retrying.
● LDK #1743 provides a new
ChannelReadyevent when a channel becomes ready to use. Notably, the event may be issued after a channel has received a suitable number of confirmations, or it may be issued immediately in the case of a zero-conf channel.
● BTCPay Server #4157 adds opt-in support for a new version of the checkout interface. See the PR for screenshots and video previews.
● BOLTs #1032 allows the ultimate receiver of a payment (HTLC) to accept a greater amount than they requested and with a longer time before it expires than they requested. This makes it more difficult for a forwarding node to determine that the next hop is the receiver by slightly tweaking a payment’s parameters. See the description of Eclair #2468 above for more information.