This week’s newsletter describes an update to the proposal for ephemeral anchors and provides a contributed field report about miniscript from a developer working at Wizardsardine. Also included are our regular sections announcing new software releases and release candidates and summarizing notable changes to popular Bitcoin infrastructure projects.

News

  • Eliminating malleability from ephemeral anchor spends: Gregory Sanders posted to the Delving Bitcoin forum about a tweak to the ephemeral anchors proposal. That proposal would allow transactions to include a zero-value output with an anyone-can-spend output script. Because anyone can spend the output, anyone can CPFP fee bump the transaction that created the output. This is convenient for multiparty contract protocols such as LN where transactions often get signed before it’s possible to accurately predict what feerate they should pay. Ephemeral anchors allows any party to the contract to add as much fee as they think is necessary. If any other party—or any other user for any reason—wants to add a higher fee, they can replace the CPFP fee bump with their own higher-feerate CPFP fee bump.

    The type of anyone-can-spend script proposed for use is an output script consisting of the equivalent of OP_TRUE, which can be spent by an input with an empty input script. As Sanders posted this week, using a legacy output script means that the child transaction spending it has a malleable txid, e.g. any miner can add data to the input script to change the child transaction’s txid. That can make it unwise to use the child transaction for anything besides fee bumping as, even if it gets confirmed, it might get confirmed with a different txid that invalidates any grandchild transactions.

    Sanders suggests instead using one of the output scripts that had been reserved for future segwit upgrades. This uses slightly more block space—four bytes for segwit versus one byte for bare OP_TRUE—but eliminates any concerns about transaction malleability. After some discussion on the thread, Sanders later proposed offering both: an OP_TRUE version for anyone who doesn’t care about malleability and wants to minimize transaction size, plus a segwit version that is slightly larger but does not allow the child transaction to be mutated. Additional discussion in the thread focused on choosing the extra bytes for the segwit approach to create a memorable bech32m address.

Field Report: A Miniscript Journey

Our (practical) interest for miniscript started back in early 2020 when we were designing Revault, a multiparty vault architecture only using then available scripting primitives.

We initially showcased Revault using a fixed set of participants. We quickly ran into issues as we tried to generalize it to more participants in a production setting.

  • Actually are we sure the script we used in the demo is secure? Is it possible to spend it in all the ways it’s advertized to be? Is there no other way of spending it than how it’s advertized?
  • Even if it is, how can we generalize it to various number of participants and keep it secure? How can we apply some optimizations and make sure the resulting script has the same semantics?
  • In addition, Revault is using pre-signed transactions (to enforce spending policies). How can we know in advance the budget to allocate for fee-bumping given the configuration of the script? How can we make sure any transaction spending those scripts will pass the most common standardness checks?
  • Finally, even assuming our scripts correspond to the intended semantics and are always spendable, how can we concretely spend them? As in how can we produce a satisfying witness for (“sign for”) each and every possible configuration? How can we make hardware signing devices compatible with our scripts?

These questions would have been a show stopper if it was not for miniscript. Two guys in a garage are not going to write a software that creates some script on the fly, hope for the best and on top of that call it a security enhancing Bitcoin wallet. We wanted to start a company around the development of Revault, but we wouldn’t get funding without providing some reasonable assurance to an investor we could bring a safe product to market. And we wouldn’t be able to solve all these engineering problems without funding.

Enters miniscript, “a language for writing (a subset of) Bitcoin Scripts in a structured way, enabling analysis, composition, generic signing and more. […] It has a structure that allows composition. It is very easy to statically analyze for various properties (spending conditions, correctness, security properties, malleability, …).” This is exactly what we needed. Armed with this powerful tool, we could give better guarantees [0] to our investors, raise funds, and start the development of Revault.

At the time, miniscript was still far from being a turnkey solution for any Bitcoin application developer to use. (If you are a new Bitcoin dev reading this after the year 2023, yes, there was a time where we used to write Bitcoin scripts BY HAND.) We had to integrate miniscript in Bitcoin Core (see PRs #24147, #24148 and #24149), which we used as the backend of the Revault wallet, and convince signing devices manufacturers to implement it in their firmware. The latter part would turn out to be the most difficult.

It was a chicken-and-egg problem: incentives were low for manufacturers to implement miniscript with no demand from users. And we couldn’t release Revault without signing device support. Fortunately this cycle was eventually broken by Stepan Snigirev in March 2021 by bringing support for miniscript descriptors to the Specter DIY. The Specter DIY was however for a long time disclaimed as being merely a “functional prototype”, and Salvatore Ingala brought miniscript to a production-ready signing device for the first time in 2022 with the new Bitcoin app for the Ledger Nano S(+). The app was released in January 2023, allowing us to publish the Liana wallet with support for the most popular signing device.

One last development is left to wrap up our miniscript journey. Liana is a Bitcoin wallet focused on recovery options. It lets one specify some timelocked recovery conditions (for instance a third-party recovery key that cannot normally spend the funds, or a decaying/expanding multisig). Miniscript was initially only available for P2WSH scripts. Almost 2 years after taproot activated, it’s unfortunate that you would have to publish your recovery spending paths onchain every time you spend. To this end, we have been working to port miniscript to tapscript (see here and here).

The future is bright. With most signing devices either having implemented or in the process of implementing miniscript support (for instance recently Bitbox and Coldcard), along with taproot and miniscript native frameworks being polished, contracting on Bitcoin with safe primitives is more accessible than ever.

It’s interesting to note how the funding of Open Source tools and frameworks lower the barrier to entry for innovative companies to compete and, more generally, projects to be implemented. This trend accelerating in the past years can make us hopeful about the future of the space.

[0] There was still risk, of course. But at least we were confident we could get past the onchain part. The offchain one would prove to be (as expected) more challenging.

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.

Notable code and documentation changes

Notable recent changes in Bitcoin Core, Core Lightning, Eclair, LDK, LND, libsecp256k1, Hardware Wallet Interface (HWI), Rust Bitcoin, BTCPay Server, BDK, Bitcoin Improvement Proposals (BIPs), Lightning BOLTs, and Bitcoin Inquisition.

  • Bitcoin Core #28207 updates the way the mempool is stored on disk (which normally happens during node shutdown, but can also be triggered by the savemempool RPC). Previously, it was stored in a simple serialization of the underlying data. Now, that serialized structure is XOR’d by a random value generated independently by each node, obfuscating the data. It’s XOR’d by the same value during loading to remove the obfuscation. The obfuscation prevents someone from being able to put certain data in a transaction to get a particular sequence of bytes to appear in the saved mempool data, which might cause programs like virus scanners to flag the saved mempool data as dangerous. The same method was previously applied to storing the UTXO set in PR #6650. Any software that needs to read mempool data from disk should be able to trivially apply the XOR operation itself, or use the configuration setting -persistmempoolv1 to request saving in the unobfuscated format. Note, the backward-compatibility configuration setting is planned to be removed in a future release.

  • LDK #2715 allows a node to optionally accept a smaller value HTLC than is supposed to be delivered. This is useful when the upstream peer is paying the node through a new JIT channel, which costs the upstream peer an onchain transaction fee that they want to deduct from the amount of the HTLC being paid to the node. See Newsletter #257 for LDK’s previous implementation of the upstream portion of this feature.