This week’s newsletter describes a proposal for a new managed joinpool protocol and summarizes an idea for relaying transactions using the Nostr protocol. Also included is another entry in our limited weekly series about mempool policy, plus our regular sections summarizing notable questions and answers posted to the Bitcoin Stack Exchange, listing new software releases and release candidates, and describing notable changes to popular Bitcoin infrastructure software.

News

  • Proposal for a managed joinpool protocol: this week, Burak Keceli posted to the Bitcoin-Dev mailing list an idea for Ark, a new joinpool-style protocol where owners of bitcoins opt-in to using a counterparty as a co-signer on all transactions within a certain time period. The owners can either unilaterally withdraw their bitcoins onchain after the expiry of the timelock or instantly and trustlessly transfer them offchain to the counterparty before the timelock expires.

    Like any Bitcoin user, the counterparty can broadcast an onchain transaction at any time that spends only their own funds. If an output from that transaction is used as an input to the offchain transaction that transfers funds from the owner to the counterparty, it makes the offchain transfer invalid unless the onchain transaction confirms within a reasonable amount of time. In this case, the counterparty won’t sign their onchain transaction until they receive the signed offchain transaction. This provides a trustless single-hop, single-direction atomic transfer protocol from the owner to the counterparty. Keceli describes three uses for this atomic transfer protocol:

    • Mixing coins: several users within the joinpool can all, with the cooperation of the counterparty, make atomic swaps of their current offchain values for an equivalent amount of new offchain values. This can be performed quickly because a failure of the onchain component will simply unwind the swap, returning all funds to where they started. A blinding protocol similar to those used by some existing coinjoin implementations can prevent any user or the counterparty from determining which user ended up with which bitcoins.

    • Making internal transfers: one user can transfer their offchain funds to another user with the same counterparty. The atomicity assures that either the receiver will get their money or the spender receives a refund. For a receiver that doesn’t trust both the spender and the counterparty, they will need to wait for as many confirmations as they would for a regular onchain transaction.

      Keceli and a commentator link to previous research describing how a zero-conf payment can be made uneconomical to double spend by pairing it with a fidelity bond that can be claimed by any miner who observed both versions of the double-spent transaction. That might allow receivers to accept a payment within seconds even if they didn’t trust any other individual parties.

    • Paying LN invoices: a user can quickly commit to paying their offchain funds to the counterparty if that counterparty knows a secret, allowing the user to pay LN-style HTLC invoices through the counterparty.

      Similar to the problem with internal transfers, a user can’t receive funds trustlessly, so they shouldn’t reveal a secret before a payment has received a sufficient number of confirmations or it is secured by a fidelity bond that they find persuasive.

    Keceli says the base protocol can be implemented on Bitcoin today using frequent interaction between members of the joinpool. If a covenant proposal like OP_CHECKTEMPLATEVERIFY, SIGHASH_ANYPREVOUT, or OP_CAT + OP_CHECKSIGFROMSTACK is implemented, members of the joinpool will only need to interact with the counterparty when participating in a coinjoin, making a payment, or refreshing the timelock on their offchain funds.

    Every coinjoin, payment, or refresh requires the publication of a commitment in an onchain transaction, although an essentially unlimited number of operations can all be bundled in the same small transaction. To allow operations to complete quickly, Keceli suggests an onchain transaction be made approximately every five seconds so users don’t need to wait longer than that amount of time. Each transaction is separate—it’s not possible to combine the commitments from multiple transactions using replace-by-fee without breaking the commitments or requiring participation from all the users involved in previous rounds—so over 6.3 million transactions might need to be confirmed each year for one counterparty, although the individual transactions are fairly small.

    Comments about the protocol posted to the mailing list included:

    • A request for more documentation: at least two respondents requested additional documentation about how the system worked, finding it hard to analyze given the high-level description provided to the mailing list. Keceli has since begun publishing draft specifications.

    • Concern that receiving is slow compared to LN: several people noted that, in the initial design, it’s not possible to trustlessly receive a payment from the joinpool (either offchain or onchain) without waiting for a sufficient number of confirmations. That can take hours, whereas many LN payments currently complete in less than a second. Even with fidelity bonds, LN would be faster on average.

    • Concern that the onchain footprint is high: one reply noted that, at one transaction every five seconds, about 200 such counterparties would consume the entire space of every block. Another reply assumed that each of the counterparty’s onchain transactions will be roughly the size of an LN channel open or cooperative close transaction, so a counterparty with a million users that creates 6.3 million onchain transactions per year would use an equivalent amount of space to each of those users opening or closing an average of 6.3 channels each per year; thus, LN’s onchain costs could be lower than using the counterparty until it had reached massive scale.

    • Concern about a large hot wallet and the capital costs: a reply considered that the counterparty would need to keep an amount of bitcoin on hand (probably in a hot wallet) equal to the amount the users might spend in the near future. After a spend, the counterparty would not receive their bitcoins back for a period of up to 28 days under the current design proposal. If the counterparty charged a low interest rate of 1.5% per year on their capital, that would be an equivalent charge of 0.125% on the amount of every transaction performed with the involvement of the counterparty (including coinjoins, internal transfers, and LN payments). By comparison, public statistics available at the time of writing (collected by 1ML) indicate a median feerate per hop for LN transfers of 0.0026%, almost 50 times lower.

    Several comments on the list were also excited for the proposal and were looking forward to seeing Keceli and others explore the design space of managed joinpools.

  • Transaction relay over Nostr: Joost Jager posted to the Bitcoin-Dev mailing list to request feedback on the idea by Ben Carman of using the Nostr protocol for relaying transactions that might not propagate well on the P2P network of Bitcoin full nodes that provide relay services.

    In particular, Jager examines the possibility of using Nostr for the relay of transaction packages, such as relaying an ancestor transaction with a feerate below the minimum accepted value by bundling it with a descendant that pays a high enough fee to compensate for its ancestor’s deficiency. This makes CPFP fee bumping more reliable and efficient, and it’s a feature called package relay that Bitcoin Core developers have been working on implementing for the Bitcoin P2P network. A challenge in reviewing the design and implementation of package relay is ensuring that the new relay methods don’t create any new denial-of-service (DoS) vulnerabilities against individual nodes and miners (or the network in general).

    Jager notes that Nostr relays have the ability to easily use alternative types of DoS protection from the P2P relay network, such as requiring a small payment to relay a transaction. He suggests that can make it practical to allow package relay, or relay of other alternative transactions, even if a malicious transaction or package could lead to wasting a small amount of node resources.

    Included in Jager’s post was a link to a video of him demonstrating the feature. His post had only received a few replies as of this writing, although they were all positive.

Waiting for confirmation #3: Bidding for block space

A limited weekly series about transaction relay, mempool inclusion, and mining transaction selection—including why Bitcoin Core has a more restrictive policy than allowed by consensus and how wallets can use that policy most effectively.

Last week we mentioned that transactions pay fees for the used blockspace rather than the transferred amount, and established that miners optimize their transaction selection to maximize collected fees. It follows that only those transactions get confirmed that reside in the top of the mempool when a block is found. In this post, we will discuss practical strategies to get the most for our fees. Let’s assume we have a decent source of feerate estimates—we will talk more about feerate estimation in next week’s article.

While constructing transactions, some parts of the transaction are more flexible than others. Every transaction requires the header fields, the recipient outputs are determined by the payments being made, and most transactions require a change output. Both sender and receiver should prefer blockspace-efficient output types to reduce the future cost of spending their transaction outputs, but it’s during the input selection that there is the most room to change the final composition and weight of the transaction. As transactions compete by feerate [fee/weight], a lighter transaction requires a lower fee to reach the same feerate.

Some wallets, such as the Bitcoin Core wallet, try to combine inputs such that they avoid needing a change output altogether. Avoiding change saves the weight of an output now, but also saves the future cost of spending the change output later. Unfortunately, such input combinations will only seldom be available unless the wallet sports a large UTXO pool with a broad variety of amounts.

Modern output types are more blockspace-efficient than older output types. E.g. spending a P2TR input incurs less than 2/5ths of a P2PKH input’s weight. (Try it with our transaction size calculator!) For multisig wallets, the recently finalized MuSig2 schema and FROST protocol chalk out huge cost savings by permitting multisig functionality to be encoded in what looks like a single-sig input. Especially in times when blockspace demand goes through the roof, a wallet using modern output types by itself translates to big cost savings.

Overview of input and output weights

Smart wallets change their selection strategy on the basis of the feerate: at high feerates they use few inputs and modern input types to achieve the lowest possible weight for the input set. Always selecting the lightest input set would locally minimize the cost of the current transaction, but also grind a wallet’s UTXO pool into small fragments. This could set the user up for transactions with huge input sets at high feerates later. Therefore, it is prescient for wallets to also select more and heavier inputs at low feerates to opportunistically consolidate funds into fewer modern outputs in anticipation of later blockspace demand spikes.

High-volume wallets often batch multiple payments into a single transaction to reduce the transaction weight per payment. Instead of incurring the overhead of the header bytes and the change output for each payment, they only incur the overhead cost once shared across all payments. Even just batching a few payments quickly reduces cost per payment.

Savings from payment batching with
P2WPKH

Still, even while many wallets estimate feerates erring on overpayment, on a slow block or surge in transaction submissions, transactions sometimes sit unconfirmed longer than planned. In those cases, either the sender or receiver may want to reprioritize the transaction.

Users generally have two tools at their disposal to increase their transaction’s priority, child pays for parent (CPFP) and replace by fee (RBF). In CPFP, a user spends their transaction output to create a high-feerate child transaction. As described in last week’s post, miners are incentivized to pick the parent into the block in order to include the fee-rich child. CPFP is available to any user that gets paid by the transaction, so either receiver or sender (if they created a change output) can make use of it.

In RBF, the sender authors a higher-feerate replacement of the original transaction. The replacement transaction must reuse at least one input from the original transaction to ensure a conflict with the original and that only one of the two transactions can be included in the blockchain. Usually this replacement includes the payments from the original transaction, but the sender could also redirect the funds in the replacement transaction, or combine multiple transactions’ payments into one upon replacement. As described in last week’s post, nodes evict the original transaction in favor of the more incentive-compatible replacement transaction.

While both demand for and production of blockspace are outside our control, there are many techniques wallets can use to bid for blockspace effectively. Wallets can save fees by creating lighter transactions through eliminating the change output, spending native segwit outputs, and defragmenting their UTXO pool during low feerate environments. Wallets that support CPFP and RBF can also start with a conservative feerate and then update the transaction’s priority using CPFP or RBF if needed.

Selected Q&A from Bitcoin Stack Exchange

Bitcoin Stack Exchange is one of the first places Optech contributors look for answers to their questions—or when we have a few spare moments to help curious or confused users. In this monthly feature, we highlight some of the top-voted questions and answers posted since our last update.

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.

  • Bitcoin Core 25.0 is a release for the next major version of Bitcoin Core. The release adds a new scanblocks RPC, simplifies the use of bitcoin-cli, adds miniscript support to the finalizepsbt RPC, reduces default memory use with the blocksonly configuration option, and speeds up wallet rescans when compact block filters are enabled—among many other new features, performance improvements, and bug fixes. See the release notes for details.

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 #27469 speeds up Initial Block Download (IBD) when one or more wallets are being used. With this change, a block will only be scanned for transactions matching a particular wallet if it was mined after the wallet’s birthdate—the date recorded in the wallet as when it was created.

  • Bitcoin Core #27626 allows a peer who has requested our node provide compact block relay in high-bandwidth mode to make up to three requests for transactions from the latest block we advertised to them. Our node will respond to the request even if we didn’t initially provide them with a compact block. This allows a peer who receives a compact block from one of its other peers to request any missing transactions from us, which can help if that other peer has become unresponsive. This can help our peer validate the block faster, which may also help them use it sooner in time-critical functions, such as mining.

  • Bitcoin Core #25796 adds a new descriptorprocesspsbt that can be used to update a PSBT with information that will help it later be signed or finalized. A descriptor provided to the RPC will be used to retrieve information from the mempool and UTXO set (and, if available, complete confirmed transactions when the node was started with the txindex configuration option). The retrieved information will then be used to fill in the PSBT.

  • Eclair #2668 prevents Eclair from attempting to pay more in fees to claim an HTLC onchain than the value it will receive from successfully resolving that HTLC.

  • Eclair #2666 allows a remote peer receiving an HTLC to accept it even if the transaction fee that would need to be paid to accept it will reduce the peer’s balance below the minimum channel reserve. The channel reserve exists to ensure that a peer will lose at least a small amount of money if they attempt to close a channel in an outdated state, discouraging them from attempting theft. However, if the remote peer accepts an HTLC that will pay them if it’s successful, they will have more at stake than the reserve anyway. If it’s not successful, their balance will return to the previous amount, which will have been above the reserve.

    This is a mitigation for a stuck funds problem, which occurs when a payment would cause the party responsible for paying the fees to need to pay more value than their current available balance, even when they might be the party receiving the payment. For previous discussion of this problem, see Newsletter #85.

  • BTCPay Server 97e7e begins setting the BIP78 minfeerate (minimum feerate) parameter for payjoin payments. See also the bug report that lead to this commit.

  • BIPs #1446 makes a small change and a number of additions to the BIP340 specification of schnorr signatures for Bitcoin-related protocols. The change is allowing the message to be signed to be an arbitrary length; previous versions of the BIP required that the message be exactly 32 bytes. See a related change to the Libsecp256k1 library described in Newsletter #157. The change has no effect on the use of BIP340 in consensus applications as signatures used with both taproot and tapscript (respectively, BIPs 341 and 342) use 32-byte messages.

    The additions describe how to effectively use arbitrary length messages, recommends how to use a hashed tag prefix, and provides recommendations for increasing safety when using the same key in different domains (such as signing transactions or signing plain-text messages).