This week’s newsletter links to a specification for a proposed OP_TXHASH opcode and includes our regular sections summarizing a Bitcoin Core PR Review Club meeting, linking to new releases and release candidates, and descriptions of notable changes to popular Bitcoin infrastructure projects.

News

  • Specification for OP_TXHASH proposed: Steven Roose posted to the Bitcoin-Dev mailing list a draft BIP for a new OP_TXHASH opcode. The idea behind this opcode has been discussed before (see Newsletter #185) but this is the first specification of the idea. In addition to describing exactly how the opcode would work, it also looks at mitigating some potential downsides, such as full nodes potentially needing to hash up to several megabytes of data every time the opcode is invoked. Roose’s draft includes a sample implementation of the opcode.

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.

util: Type-safe transaction identifiers is a PR by Niklas Gögge (dergoegge) that improves type safety by introducing separate types for txid (the transaction identifier or hash that doesn’t include the segwit witness data) and wtxid (same but includes the witness data), rather than both being represented by a uint256 (a 256-bit integer, which can contain a SHA256 hash). This PR should have no operational effect; it aims to prevent future programming errors in which one kind of transaction ID is used where the other was intended. Such errors will be detected at compile time.

To minimize disruption and ease review, these new types will initially be used in only one area of the code (the transaction “orphanage”); future PRs will use the new types in other areas of the codebase.

  • What does it mean for a transaction identifier to be type-safe? Why is that important or helpful? Are there any downsides?

    Since a transaction identifier has one of two meanings (txid or wtxid), type-safety is the property that an identifier can’t be used with the wrong meaning. That is, a txid can’t be used where a wtxid is expected, and vice versa, and that this is enforced by the compiler’s standard type checking. 

  • Rather than the new class types Txid and a Wtxid inheriting from uint256, should they include (wrap) a uint256? What are the tradeoffs?

    Those classes could do that, but it would cause much more code churn (many more source lines would need to be touched). 

  • Why is it better to enforce types at compile-time instead of at run-time?

    Developers discover errors quickly as they’re coding, rather than relying on writing extensive test suites to catch bugs in runtime (and these tests may still miss some errors). However, testing would still be useful since type safety won’t prevent consistent use of the wrong type of transaction ID in the first place. 

  • Conceptually, when writing new code that requires referring to transactions, when should you use txid and when should you use wtxid? Can you point to any examples in the code where using one instead of the other could be very bad?

    In general, use of wtxid is preferred since it commits to the entire transaction. An important exception is the prevout reference from each input to the output (UTXO) it’s spending, which must specify the transaction by txid. An example of where it’s important to use one and not the other is given here (for more info, see Newsletter #104). 

  • In which concrete way(s) could using transaction_identifier instead of uint256 help find existing bugs or prevent the introduction of new ones? On the other hand, could this change introduce new bugs?

    Without this PR, a function that takes a uint256 argument (such as a block ID hash) could be passed a txid. With this PR, this causes a compile-time error. 

  • The GenTxid class already exists. How does it already enforce type correctness, and how is it different from the approach in this PR?

    This class includes a hash and a flag indicating if the hash is a wtxid or a txid, so it’s still a single type rather than two distinct types. This allows type checking, but it must be explicitly programmed, and, more importantly, can only be done at run-time, not compile-time. It satisfies the frequent use case of wanting to take input that can be either kind of identifier. For this reason, this PR doesn’t remove GenTxid. A better alternative for the future might be std::variant<Txid, Wtxid>

  • How is transaction_identifier able to subclass uint256, given that, in C++, integers are types and not classes?

    Because uint256 is itself a class, rather than a built-in type. (The largest built-in C++ integer type is 64 bits.) 

  • Does a uint256 behave otherwise the same as, for example, a uint64_t?

    No, arithmetic operations aren’t permitted on uint256 because they don’t make sense for hashes (which is the main use of uint256). The name is misleading; it’s really just a blob of 256 bits. A separate arith_uint256 allows arithmetic (used, for example, in PoW calculations). 

  • Why does transaction_identifier subclass uint256 instead of being a completely new type?

    It allows us to use explicit and implicit conversions to leave code that is expecting a transaction ID in the form of a uint256 unchanged until it’s an appropriate time to refactor to use the new, stricter Txid or Wtxid types. 

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.

  • LDK 0.0.117 is a release of this library for building LN-enabled applications. It includes security bug fixes related to the anchor outputs features included in the immediately prior release. The release also improves pathfinding, improves watchtower support, enables batch funding of new channels, among several other features and bug fixes.

  • BDK 0.29.0 is a release of this library for building wallet applications. It updates dependencies and fixes a (likely rare) bug affecting cases where a wallet received more than one output from miner coinbase transactions.

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), Lightning BOLTs, and Bitcoin Inquisition.

  • Bitcoin Core #27596 finishes the first phase of the assumeutxo project, containing all the remaining changes necessary to both use an assumedvalid snapshot chainstate and do a full validation sync in the background. It makes UTXO snapshots loadable via RPC (loadtxoutset) and adds assumeutxo parameters to chainparams.

    Although the feature set will not be available on mainnet until activated, this merge marks the culmination of a multi-year effort. The project, proposed in 2018 and formalized in 2019, will significantly improve the user experience of new full nodes first coming onto the network. Follow-ups of the merge include Bitcoin Core #28590, #28562, and #28589.

  • Bitcoin Core #28331, #28588, #28577, and GUI #754 add support for version 2 encrypted P2P transport as specified in BIP324. The feature is currently disabled by default but can be enabled using the -v2transport option.

    Encrypted transport helps improve the privacy of Bitcoin users by preventing passive observers (such as ISPs) from directly determining which transactions nodes relay to their peers. It’s also possible to use encrypted transport to thwart active man-in-the-middle observers by comparing session identifiers. In the future, the addition of other features may make it convenient for a lightweight client to securely connect to a trusted node over a P2P encrypted connection.

  • Bitcoin Core #27609 makes the submitpackage RPC available on non-regtest networks. Users can use this RPC to submit packages of a single transaction with its unconfirmed parents, where none of the parents spend the output of another parent. The child transaction can be used to CPFP parents that are below the node’s dynamic mempool minimum feerate. However, while package relay is not yet supported, these transactions may not necessarily propagate to other nodes on the network.

  • Bitcoin Core GUI #764 removes the ability to create a legacy wallet in the GUI. The ability to create legacy wallets is being removed; all newly created wallets in future versions of Bitcoin Core will be descriptor-based.

  • Core Lightning #6676 adds a new addpsbtoutput RPC that will add an output to a PSBT for receiving funds onchain to the node’s wallet.