A new version of the original Bitcoin software launched by Satoshi Nakamoto in 2009 has been released.
Bitcoin Core 24.0 was worked on by 112 developers for roughly seven months to bring tangible improvements to Bitcoin Core’s wallet, peer-to-peer (P2P) communications, graphical user interface (GUI) and much more.
This article explores some of the main changes.
Initial Miniscript Support
Bitcoin Core 24.0 is introducing support for Miniscript by extending the wsh() output descriptor. While it’s an initial and rudimentary integration, the move paves the way for more complex scripting to be deployed to Bitcoin in a simpler — and safer — way.
Miniscript can be thought of as a framework (or template) for Bitcoin Script, Bitcoin’s native programming language. Bitcoin Script is responsible for enabling all programming functionality available for Bitcoin, including, for example, what is perhaps the most simple one of them: determining who is allowed to spend a given coin. For every Bitcoin transaction, the sender requests the receiver’s address and with that information constructs a script that locks the bitcoin being sent in a way that only the receiver will be able to spend it. While it is fairly easy to construct simple scripts such as the above with Bitcoin Script, the more complex the script gets the greater the chance of human error. This is where Miniscript comes into play.
Miniscript allows for writing a subset of Bitcoin Scripts in a structured way. It enables analysis, composition, and generic signing, among other things, allowing for advanced scripts to be more safely written by developers. In other words, Miniscript “contains” some functionality of pre-set Bitcoin Scripts to an expected behavior pattern, limiting eventual risks as unexpected behavior is minimized. In practice, it provides a “toolbox” for developers to tinker with and create advanced and complex scripts for Bitcoin rather than having to do it all manually through Bitcoin Script.
Starting with Bitcoin Core 24.0, users can now create a wallet containing a Miniscript script, create addresses for that wallet and fund them with bitcoin. Spending from those addresses is not yet supported by the Bitcoin Core wallet, however, meaning that Miniscript-enabled wallets on Bitcoin Core are watch-only for the time being.
A new RPC has been introduced, sendall, that lets users spend specific unspent transaction outputs (UTXOs) to their entirety. The RPC will send the amount held in the specified UTXOs to one or more recipients without generating change. (By default, sendall will spend every UTXO in the wallet.)
This behavior can be desirable in a few situations. First, naturally, the user might want to empty their wallet. Calling the new RPC with default configurations will do just that in an easy way. Second, the user might want to improve their privacy by forgoing change.
Change addresses are tricky because users often lose track of where they originated from and as such can mix them with other UTXOs as inputs in a future transaction. This would pose a privacy concern due to the common-input-ownership heuristic, a widely used premise in chain analysis that assumes all inputs in a transaction belong to the same user. In the change output example, the user would be making that link, effectively risking a deanonymization of multiple of their coins as a chain analyst would be able to cluster some of that user’s addresses as a wallet.
A changeless payment combats this issue by creating a transaction that spends the entirety of the selected UTXOs. Since there is no change, the user can’t make the mistake mentioned above. Moreover, a changeless payment introduces a reasonable doubt to a chain analyst wondering whether the new output is owned by the same entity that sent the payment (a mere movement of funds to a new address) or actually is now owned by a different user.
Change Output Randomization To Avoid Fingerprinting
As explained above, change outputs can be a privacy leak. While sendall mitigates the usage of a change address altogether, in reality there will be few times when the user owns a UTXO of the exact size of the payment that needs to be done. Ensuring that an observer can’t spot which of the outputs is the change address helps the user gain a bit of privacy because it won’t be trivial to link a newly created address (change output) with the now-spent input to that transaction.
Usually, when there isn’t a UTXO with the payment’s exact amount, most wallets and users intuitively opt for the one closest to that number. As a consequence, an observer watching the blockchain can see which output is the payment (larger one) and which one is the change (smaller one). This brings about many of the aforementioned risks.
To lower the likelihood that an observer can single out the change output and cluster user addresses, Bitcoin Core now randomizes change output values.
Starting with version 24.0, the Bitcoin Core wallet will pick a random number between the payment size and three times the payment size. This number will inform its UTXO selection for spending. This effectively means that sometimes the algorithm will pick a UTXO whose value is closer to the payment and other times it will select a UTXO whose value is closer to that upper bound of three times the payment amount. The former scenario will produce the typical change-output-lower-than-payment scenario while the latter will produce the inverse — a change output that is larger than the payment. Given that there is no way for a blockchain observer to tell when each scenario happens at a given time, the user should be able to enjoy greater privacy assurances.
Updates To Replace By Fee
RBF provides optionality for a Bitcoin user whenever they are sending a transaction to the network. Often, a user doesn’t want to overpay on miner fees, and as such can choose a “middle ground” between the fee paid and the speed through which the transaction gets included in a block. But if the fee value selected by the user is too low or the mempool is congested, it might take too long for the transaction to be included in a block (or it might get stuck in the mempool altogether). RBF allows the user to “bump” the fee of their transaction in such a case, more often than not enabling a faster settlement.
Under the hood, RBF doesn’t actually bump the fee though. What happens in the background is that the software client will broadcast a new transaction with the same inputs and most of the same outputs. (Some output values change; the fee value will naturally change to reflect the new number and usually that difference gets deducted from the amount that was being sent to the change address.)
Historically, nodes would only relay the first version of a transaction they saw. With the advent of RBF, a mechanism was introduced to let users flag that they were sending a transaction that could eventually be fee-bumped, i.e., replaced by a version with a higher fee. This served as a heads-up to nodes, letting them know that higher-fee versions of that transaction could be sent at a later time and that they should also be relayed. Probabilistically, the higher-fee version of the transaction will tend to be more attractive to miners and as such selected first. Once that happens and it gets included in a block, the lower-fee transaction will be dropped from the nodes’ mempools as it would be attempting a double-spend.
Bitcoin Core 24.0 introduces two updates to RBF functionality.
First, it now lets users configure their nodes so as to relay replaceable transactions without enforcing the RBF flag. This can be done through the new mempoolfullrbf option. It will be set to off by default, but those interested in enabling it can turn it on.
Second, RBF is now set as a standard in Bitcoin Core’s wallet. Transactions now opt-in to RBF by default and the -walletrbf startup option defaults to true. Users can opt-out of RBF by tweaking a given transaction in its building process or setting the -walletrbf startup option to false.
Descriptor Wallet Migration
Bitcoin Core 23.0 made descriptor wallets the standard. Descriptors facilitate the user’s life in backing up their wallet and later restoring that backup in a standard format.
Before descriptors existed, users had to know the derivation path of their wallet, which dictates how the wallet’s master key derives addresses to be used for receiving and sending bitcoin. Since wallets could have different derivation paths, it wasn’t enough for a backup to contain solely the seed phrases. Sometimes the user could be lucky and attempt to restore a backup with a wallet that leveraged the same derivation path, but given the low likelihood of that happening, entire websites dedicated to helping users figure out what derivation path to use for old and new wallets emerged.
The descriptor solves this problem by being descriptive about what derivation path the backed-up wallet uses, greatly improving user experience. The idea is that a descriptor wallet backup self-contains all the necessary information for it to be correctly restored by any software client (provided the client is descriptor-enabled).
Now, Bitcoin Core 24.0 introduces a new tool to migrate legacy wallets to a descriptor wallet format, enabling users to take advantage of this emerging standard to better safeguard their precious bitcoin. Though still experimental, a new RPC (migratewallet) has been introduced. This document provides more detail on its functionality.
The Bitcoin Core GUI has been known for not providing the same level of functionality that remote procedure calls (RPCs) and command line tools can achieve. Bitcoin 24.0 is taking some steps to change a bit of that.
Bitcoin Core’s newest version brings a new menu item on the GUI that lets users restore a wallet from backup, making it easier for non-technical folks to restore backups. Previously, this option existed only on the command line.
Another shortcoming the GUI had compared to the RPC interface was related to the Bitcoin Core client’s settings. The famous bitcoin.conf file is the holy grail of Bitcoin Core configuration, but again it was tweakable mainly through the command line. An option did exist to tweak settings in the GUI, but a warning made it clear that bitcoin.conf took precedence over the GUI in the event that both the file and the GUI attempted to set data for the same configuration. Therefore, while the GUI provided a simple option to change settings, the configuration file was still the most reliable way to go about customizing one’s Bitcoin Core client.
Bitcoin Core 24.0 changes that. The new update unifies the GUI settings page with the bitcoin.conf file. Now, when a user opens up the client’s settings on the GUI, the settings shown are pulled from the configuration file. Similarly, configuration changes made in the GUI are now reflected in bitcoin.conf. (It is worth pointing out that the relationship there is indirect, because changes in the GUI are actually set to settings.json, a file that takes precedence over bitcoin.conf.)
Changes To P2P Communications
New Logic For Downloading Headers
Bitcoin Core 24.0 brings an update to the way peers in the network catch up to the tip of the chain, either because they’re booting for the first time or have spent a long time without connecting to the Bitcoin network.
Before this release, a new peer joining Bitcoin would start looking for peers from which to download block headers. The peer doesn’t download entire blocks at first because it is incentivized to check whether it is following the correct chain before downloading the blocks for that chain. Otherwise it risks downloading blocks for the wrong chain, thereby wasting resources.
While downloading the headers aids in saving time and resources, a resource exhaustion attack could still happen where a malicious actor spams the peer with millions of fake block headers. Since the client needs to download and save the headers on disk, a big enough amount of data could be able to cripple the peer’s hardware.
To mitigate this threat, Bitcoin Core introduced the concept of checkpoints years ago. Checkpoints determine which blocks must be present in a chain in order for it to be valid. However, this solution also represents an issue, as checkpoints could be abused to effectively roll back the longest chain. Such a possibility is not desirable in Bitcoin, so a different solution had to be devised. Enter this new update.
With Bitcoin Core 24.0, peers now download block headers twice. In the first run, headers are downloaded and discarded (not saved on disk) until a sufficient amount of work is found — which suggests the chain the peer has been following is valid. In that case, the peer then restarts the process, but now, in addition to downloading, the peer also saves the block headers on disk. By only saving headers to disk once the peer is certain they are part of a chain with significant proof of work, the peer avoids using up large amounts of storage in an eventual attack such as a resource exhaustion. This also removes the need for checkpoints and is arguably a more elegant solution since it doesn’t depend on human input to determine chain validity.
Thanks to Aaron van Wirdum for feedback.
For more details and other changes, see the Bitcoin Core 24.0 release notes. To download Bitcoin Core 24.0, navigate here. Details about Bitcoin Core 24.0 are also explained in audio in the Bitcoin, Explained podcast episode 65.